所有Android设备的相机应用程序

时间:2012-04-16 10:35:47

标签: camera xamarin.android android

我目前正在为Android开发一个相机应用程序,在该应用程序上发生了一些问题。我需要它才能在所有Android设备上运行,并且因为所有这些设备都以不同的方式工作,特别是相机硬件,我很难找到适用于每个设备的解决方案。

我的应用主要目标是按下按钮启动相机,拍照并将其上传到服务器。所以我真的不需要在设备上保存图像的功能,但如果需要进一步使用图像,我可以允许它。

例如,我在Samsung Galaxy SII和Motorola Pad上测试我的应用程序。我得到了启动相机的工作代码,这是C#代码的方式,因为我使用的是Monodroid:

Intent cameraIntent = new Intent(Android.Provider.MediaStore.ActionImageCapture);  
StartActivityForResult(cameraIntent, PHOTO_CAPTURE);

我获取结果,类似于我遵循的本指南: http://kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/ 为什么我遵循本指南是因为我的galaxy设备上的活动返回null(另一个面向设备的问题)。

此代码在Galaxy设备上运行良好。它需要一张照片并将照片保存在库中,我可以从中上传到服务器。通过进一步研究,这显然是星系标准行为,所以这在我的摩托罗拉垫上不起作用。相机工作正常,但没有图像保存到图库。

所以有了这个背景,我的问题是,我是否在正确的道路上?我是否需要将图像保存到图库以便在我的应用程序中进一步使用?是否有适用于每个Android设备的解决方案,因为这是我需要的解决方案。

感谢您的反馈!

2 个答案:

答案 0 :(得分:1)

阅读链接文章后,该文章采用的方法面向Galaxy系列,因为它们似乎会自动写入图库。

本文详细讨论了其他一些场景:

Android ACTION_IMAGE_CAPTURE Intent

因此,我不一定认为您提供的链接文章是正确的路径。并非所有设备都自动写入该文章中描述的画廊afaik。我链接的文章指出了与安全性相关的问题,并建议将图像写入/ sdcard / tmp文件夹以存储原始图像。沿着类似的路径走下去很可能会导致代码在许多设备上可靠地运行。

以下是一些其他链接供参考:

关于此主题的Google讨论:http://code.google.com/p/android/issues/detail?id=1480 项目可能解决问题:https://github.com/johnyma22/classdroid

虽然该讨论/项目在Java / Android SDK中,但相同的概念应该适用于Monodroid。如果您需要帮助,我很乐意帮助您将代码调整为适用于Android的Mono解决方案。

答案 1 :(得分:1)

to long2know: 是的,相同的概念适用于Monodroid。我已经阅读了你与其他类似的链接文章。但是我不喜欢该特定帖子中的方法,因为它检查了一些硬编码到集合中的设备的错误。这意味着它可能无法检测未来设备中的错误。由于我不会对此应用程序进行维护,我不能允许这样做。我在其他地方找到了解决方案,并根据我的情况对其进行了调整,如果有人需要,我会在下面发布。它适用于我的两个设备,猜测它适用于大多数其他设备。谢谢你的帖子!

允许您拍摄照片并使用的解决方案,也可以选择使用图库中的图像。解决方案使用选项菜单用于这些目的,仅用于测试。 (Monodroid代码)。

相机代码的灵感来自: access to full resolution pictures from camera with MonoDroid

namespace StackOverFlow.UsingCameraWithMonodroid
{
    [Activity(Label = "ImageActivity")]
    public class ImageActivity
        private readonly static int TakePicture = 1;
        private readonly static int SelectPicture = 2;
        private string imageUriString;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            this.SetContentView(Resource.Layout.ImageActivity);
        }

        public override bool OnCreateOptionsMenu(IMenu menu)
        {
            MenuInflater flate = this.MenuInflater;
            flate.Inflate(Resource.Menu.ImageMenues, menu);

            return base.OnCreateOptionsMenu(menu);
        }

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            switch (item.ItemId)
            {
                case Resource.Id.UseExisting:
                    this.SelectImageFromStorage();
                    return true;
                case Resource.Id.AddNew:
                    this.StartCamera();
                    return true;
                default:
                    return base.OnOptionsItemSelected(item);
            }
        }

        private Boolean isMounted
        {
            get
            {
                return Android.OS.Environment.ExternalStorageState.Equals(Android.OS.Environment.MediaMounted);
            }
        }

        private void StartCamera()
        {
            var imageUri = ContentResolver.Insert(isMounted ? MediaStore.Images.Media.ExternalContentUri
                                    : MediaStore.Images.Media.InternalContentUri, new ContentValues());

            this.imageUriString = imageUri.ToString();

            var cameraIntent = new Intent(MediaStore.ActionImageCapture);
            cameraIntent.PutExtra(MediaStore.ExtraOutput, imageUri);
            this.StartActivityForResult(cameraIntent, TakePicture);
        }

        private void SelectImageFromStorage()
        {
            Intent intent = new Intent();
            intent.SetType("image/*");
            intent.SetAction(Intent.ActionGetContent);
            this.StartActivityForResult(Intent.CreateChooser(intent,
                    "Select Picture"), SelectPicture);

        }

        // Example code of using the result, in my case i want to upload in another activity
        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            // If a picture was taken
            if (resultCode == Result.Ok && requestCode == TakePicture)
            {
                // For some devices data can become null when using the camera activity.
                // For this reason we save pass the already saved imageUriString to the upload activity
                // in order to adapt to every device. Instead we would want to use the data intent
                // like in the SelectPicture option.

                var uploadIntent = new Intent(this.BaseContext, typeof(UploadActivity));
                uploadIntent.PutExtra("ImageUri", this.imageUriString);
                this.StartActivity(uploadIntent);
            }
            // User has selected a image from storage
            else if (requestCode == SelectPicture)
            {
                var uploadIntent = new Intent(this.BaseContext, typeof(UploadActivity));
                uploadIntent.PutExtra("ImageUri", data.DataString);
                this.StartActivity(uploadIntent);
            }
        }
    }
}