【问题标题】:take a picture for android version 7.0 using xamarin android使用 xamarin android 为 android 版本 7.0 拍照
【发布时间】:2017-04-26 17:46:50
【问题描述】:

我想为我的 xamarin 应用程序使用相机。

我使用以下代码从我的相机拍照。

Intent intent = new Intent(MediaStore.ActionImageCapture);
            App._file = new File(App._dir, String.Format("myPhoto.jpg", Guid.NewGuid()));
            intent.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(App._file));
            StartActivityForResult(intent, 0);

此代码适用于 android 版本 6.0。但是当我在清单 xml 上使用 android 版本 7.0 时不起作用。

请帮帮我...

【问题讨论】:

    标签: xamarin.android


    【解决方案1】:

    简答

    imageUri = FileProvider.GetUriForFile(this, "YourPackageName", photoFile);
    takePictureIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
    

    长答案

    示例代码

    using System;
    using Android.App;
    using Android.Content;
    using Android.Content.PM;
    using Android.OS;
    using Android.Provider;
    using Android.Runtime;
    using Android.Support.V4.Content;
    using Android.Util;
    using DSP.Core.Client.UILogic;
    using Java.IO;
    using ReadyApps.Xamarin.Framework.Droid;
    using ReadyApps.Xamarin.Framework.Droid.Base;
    using ReadyApps.Xamarin.Framework.Droid.Controls;
    using ReadyApps.Xamarin.Framework.Droid.Helper;
    using static ReadyApps.Xamarin.Framework.Droid.Keys.DroidFramePublicKeys;
    
    namespace DSP.Droid.Activities.Orders
    {
        [Activity(Theme = "@style/ActivityDialog")]
        public class ChooseImageActivity : BaseActivity<ChooseImageActivityLogic>
        {
            private static readonly string TAG = typeof(ChooseImageActivity).Name;
            private const int REQUEST_CAMERA = 1001;
            private const int SELECT_FILE = 1002;
    
            private string currentFilePath;
            private MarshMallowPermission marshMallowPermission;
            private ExtTextView openCamera, selectImage;
    
            protected override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
                SetContentView(Resource.Layout.ChooseImageActivity);
                ((MyApplication)Application.Context).OnActivityCreated(this, null);
                marshMallowPermission = new MarshMallowPermission(this);
                InitView();
            }
    
            void InitView()
            {
                openCamera  = FindViewById<ExtTextView>(Resource.Id.openCamera);
                selectImage = FindViewById<ExtTextView>(Resource.Id.selectImage);
    
                openCamera.Click += OpenCamera_Click;
                selectImage.Click +=SelectImage_Click;
            }
    
            void SelectImage_Click(object sender, EventArgs e)
            {
                if (VersionUtils.isAfter23())
                {
                    if (!marshMallowPermission.checkPermissionForReadExternalStorage())
                    {
                        marshMallowPermission.requestPermissionForReadExternalStorage();
                    }
                }
                DispatchChoosePictureIntent();
            }
    
            void OpenCamera_Click(object sender, EventArgs e)
            {
                if (VersionUtils.isAfter23())
                {
                    if (!marshMallowPermission.checkPermissionForCamera())
                    {
                        marshMallowPermission.requestPermissionForCameraAndStorage();
                    }
                }
                DispatchTakePictureIntent();
            }
    
            private void DispatchTakePictureIntent()
            {
                var takePictureIntent = new Intent(MediaStore.ActionImageCapture);
                File photoFile = null;
                Android.Net.Uri imageUri;
                try
                {
                    photoFile = FileUtils.createImageFile();
                    currentFilePath = "file:" + photoFile.AbsolutePath;
                    if (VersionUtils.isAfter24())
                    {
                        imageUri = FileProvider.GetUriForFile(this, "YourPackageName", photoFile);
                        takePictureIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
                    }
                    else { 
                        imageUri = Android.Net.Uri.FromFile(photoFile);
                    }
    
                if (photoFile != null && takePictureIntent.ResolveActivity(PackageManager) != null)
                {
                    takePictureIntent.PutExtra(MediaStore.ExtraOutput, imageUri);
                    StartActivityForResult(takePictureIntent, REQUEST_CAMERA);
                }
                }
                catch (Exception e)
                {
                    Log.Debug(TAG, e.Message);
                    return;
                }
    
            }
            private void DispatchChoosePictureIntent()
            {
                var intent = new Intent(Intent.ActionPick, MediaStore.Images.Media.ExternalContentUri);
                intent.SetType("image/*");
                StartActivityForResult(Intent.CreateChooser(intent, GetString(Resource.String.select_picture)), SELECT_FILE);
            }
            protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
            {
                base.OnActivityResult(requestCode, resultCode, data);
    
                if (resultCode == Result.Ok)
                {
                    Intent mIntent = new Intent();
                    Android.Net.Uri imageUri = null;
                    switch (requestCode) { 
                        case REQUEST_CAMERA:
                             imageUri = Android.Net.Uri.Parse(currentFilePath);
                            break;
                        case SELECT_FILE:
                            imageUri = data.Data;
                            break;
                    }
                    mIntent.SetData(imageUri);
                    SetResult(Result.Ok, mIntent);
                    Finish();
                }
            }
    
            public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
            {
    
                if (grantResults?.Length> 0 && grantResults[0] == Permission.Granted)
                {
                    switch (requestCode)
                    {
                        case CAMERA_Storage_PERMISSION_REQUEST_CODE:
                            {
                                DispatchTakePictureIntent();
                            }
                            break;
    
                        case READ_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE:
                            {
                                DispatchChoosePictureIntent();
                            }
                            break;
                    }
                }
    
                base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            }
    
            public override void CleanResources()
            {
    
            }
        }
    }
    

    清单

    <provider android:name="android.support.v4.content.FileProvider" android:authorities="YourPackageName" android:exported="false" android:grantUriPermissions="true">
                <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
            </provider>
    

    资源 --> xml --> provider_paths.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="external_files" path="."/>
    </paths>
    

    FileUtils --> createImageFile()

    public class FileUtils
        {
            public static File createImageFile() 
            {
                //create an image file name
                string timeStamp = DateTime.Now.Ticks.ToString(); 
                string imageFileName = "JPEG_" + timeStamp + "_";
                File storageDir = Android.OS.Environment.GetExternalStoragePublicDirectory(
                    Android.OS.Environment.DirectoryPictures);
    
                if (!storageDir.Exists()) {
                    storageDir.Mkdirs();
                }
            File image = File.CreateTempFile(
                    imageFileName,
                        ".jpg",
                        storageDir
                );
            // Save a file: path for use with ACTION_VIEW intents
    
            return image;
    
        }
    }
    

    VersionUtils --> isAfter24()

    public static class VersionUtils
        {
    
            public static bool isAfter24()
            {
                return Build.VERSION.SdkInt >= BuildVersionCodes.N;
            }
    
    }
    

    你可以忽略 MarshMallowPermission

    【讨论】:

    • 嗨米娜,谢谢你的回复。 MarshMallowPermission、FileUtils 和 VersionUtils 在我的代码中显示错误。
    猜你喜欢
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多