xamarin.Android 选择本地图片、拍摄图片、剪裁图片

    [Activity(Theme = "@style/MyStyleBottom")]
    public class SelectPicPopupWindow : Activity, IOnClickListener
    {
        private const int Display_RequestCode = 0xa1;
        private const int Camera_RequestCode = 0xa2;
        private const int PhotoGallery_RequestCode = 0xa3;

        private Java.IO.File finalFile;
        private Java.IO.File originalFile;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            //竖屏显示
            RequestedOrientation = Android.Content.PM.ScreenOrientation.Portrait;

            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.SelectPicPopupWindow);

            originalFile = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(
                Android.OS.Environment.DirectoryPictures
                ), "zcb_pic_" + SystemClock.CurrentThreadTimeMillis() + ".png");
            finalFile = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(
                Android.OS.Environment.DirectoryPictures
                ), "zcb_pic_" + SystemClock.CurrentThreadTimeMillis() + ".png");

            var btn_take_photo = this.FindViewById<Button>(Resource.Id.btn_take_photo);
            var btn_pick_photo = this.FindViewById<Button>(Resource.Id.btn_pick_photo);
            var btn_cancel = this.FindViewById<Button>(Resource.Id.btn_cancel);

            btn_take_photo.SetOnClickListener(this);
            btn_pick_photo.SetOnClickListener(this);
            btn_cancel.SetOnClickListener(this);

            var windowManager = WindowManager;
            var windowManagerLayoutParams = Window.Attributes;
            var displayMetrics = new Android.Util.DisplayMetrics();
            windowManager.DefaultDisplay.GetMetrics(displayMetrics);
            windowManagerLayoutParams.Width = (int)(displayMetrics.WidthPixels * 1); // 宽度设置
            Window.Attributes = windowManagerLayoutParams;
        }
        
        public void OnClick(View v)
        {
            switch (v.Id)
            {
                case Resource.Id.btn_take_photo:
                    try
                    {
                        // 摄像头拍摄
                        CutImageByCamera();
                    }
                    catch (Exception ex)
                    {
                        Toast.MakeText(this, "App Camera Error:" + ex.InnerException, ToastLength.Short).Show();
                    }
                    break;
                case Resource.Id.btn_pick_photo:
                    try
                    {
                        // 相册选择
                        CutImageByImgStore();
                    }
                    catch (Exception ex)
                    {
                        Toast.MakeText(this, "App Select Photo Gallery Error:" + ex.InnerException, ToastLength.Short).Show();
                    }
                    break;
                case Resource.Id.btn_cancel:
                default: Finish(); break;
            }
        }

        public override bool OnTouchEvent(MotionEvent e)
        {
            Finish();
            return base.OnTouchEvent(e);
        }

        protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result ResultStatus, Intent data)
        {
            if (ResultStatus == Result.Ok)
            {
                if (requestCode == Display_RequestCode)// 显示结果
                {
                    Intent intent = new Intent();
                    intent.SetData(Android.Net.Uri.FromFile(finalFile));
                    SetResult(Result.Ok, intent);
                    Finish();
                }
                if (requestCode == Camera_RequestCode) //摄像头 剪裁  
                {
                    CropRawPhoto(Android.Net.Uri.FromFile(originalFile));
                }
                if (requestCode == PhotoGallery_RequestCode)// 选择图片 剪裁
                {
                    /*
                    * 若系统版本低于4.4,返回原uri
                    * 若高于4.4,解析uri后返回
                    * */
                    if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
                    {
                        var url= Android.Net.Uri.Parse("file://" + GetPath(BaseContext, data.Data));
                        data.SetData(url);
                    }

                    CropRawPhoto(data.Data);
                }
            }
        }

        /// <summary>
        /// 调用摄像头拍摄
        /// </summary>
        private void CutImageByCamera()
        {
            Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
            getImageByCamera.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(originalFile));
            getImageByCamera.PutExtra(MediaStore.ExtraVideoQuality, 1);
            StartActivityForResult(getImageByCamera, Camera_RequestCode);
        }

        /// <summary>
        /// 调用相册选择
        /// </summary>
        private void CutImageByImgStore()
        {
            Intent _intentCut =new Intent(Intent.ActionGetContent, null);
            _intentCut.SetType("image/*");// 设置文件类型
            _intentCut.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(originalFile));
            _intentCut.PutExtra(MediaStore.ExtraVideoQuality, 1);
            
            StartActivityForResult(_intentCut, PhotoGallery_RequestCode);
        }

        /// <summary>
        /// 剪裁图片
        /// </summary>
        /// <param name="uri"></param>
        public void CropRawPhoto(Android.Net.Uri uri)
        {
            if (!HasSdcard)
            {
                Toast.MakeText(this, "无法存储截取后的图片", ToastLength.Short).Show();
                return;
            }

            Intent _intentCut = new Intent("com.android.camera.action.CROP");
            _intentCut.SetDataAndType(uri, "image/*");
            _intentCut.PutExtra("crop", "true");
            // aspectX , aspectY :宽高的比例
            _intentCut.PutExtra("aspectX", 1);
            _intentCut.PutExtra("aspectY", 1);
            // outputX , outputY : 裁剪图片宽高
            _intentCut.PutExtra("outputX", "500");
            _intentCut.PutExtra("outputY", "500");
            _intentCut.PutExtra(MediaStore.ExtraVideoQuality, 1);
            _intentCut.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(finalFile));
            StartActivityForResult(_intentCut, Display_RequestCode);
        }

        /// <summary>
        /// 检查设备是否存在SDCard的工具方法
        /// </summary>
        /// <returns></returns>
        public static bool HasSdcard
        {
            get
            {
                String state = Android.OS.Environment.ExternalStorageState;
                if (state.Equals(Android.OS.Environment.MediaMounted))
                    return true;
                else
                    return false;
            }
        }




        #region 高于 v4.4 版本 解析真实路径


        public static String GetPath(Context context,Android.Net.Uri uri)
        {

            bool isKitKat = Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat;

            // DocumentProvider  
            if (isKitKat && DocumentsContract.IsDocumentUri(context, uri))
            {
                // ExternalStorageProvider  
                if (isExternalStorageDocument(uri))
                {
                    String docId = DocumentsContract.GetDocumentId(uri);
                    String[] split = docId.Split(':');
                    String type = split[0];

                    if ("primary".Equals(type.ToLower()))
                    {
                        return Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
                    }

                    // TODO handle non-primary volumes  
                }
                // DownloadsProvider  
                else if (isDownloadsDocument(uri))
                {

                    String id = DocumentsContract.GetDocumentId(uri);
                    Android.Net.Uri contentUri = ContentUris.WithAppendedId(
                            Android.Net.Uri.Parse("content://downloads/public_downloads"),long.Parse(id));

                    return getDataColumn(context, contentUri, null, null);
                }
                // MediaProvider  
                else if (isMediaDocument(uri))
                {
                    String docId = DocumentsContract.GetDocumentId(uri);
                    String[] split = docId.Split(':');
                    String type = split[0];

                    Android.Net.Uri contentUri = null;
                    if ("image".Equals(type))
                    {
                        contentUri = MediaStore.Images.Media.ExternalContentUri;
                    }
                    else if ("video".Equals(type))
                    {
                        contentUri = MediaStore.Video.Media.ExternalContentUri;
                    }
                    else if ("audio".Equals(type))
                    {
                        contentUri = MediaStore.Audio.Media.ExternalContentUri;
                    }

                    String selection = "_id=?";
                    String[] selectionArgs = new String[] {
                    split[1]
            };

                    return getDataColumn(context, contentUri, selection, selectionArgs);
                }
            }
            // MediaStore (and general)  
            else if ("content".Equals(uri.Scheme.ToLower()))
            {

                // Return the remote address  
                if (isGooglePhotosUri(uri))
                    return uri.LastPathSegment;

                return getDataColumn(context, uri, null, null);
            }
            // File  
            else if ("file".Equals(uri.Scheme.ToLower()))
            {
                return uri.Path;
            }

            return null;
        }

        /** 
         * Get the value of the data column for this Uri. This is useful for 
         * MediaStore Uris, and other file-based ContentProviders. 
         * 
         * @param context The context. 
         * @param uri The Uri to query. 
         * @param selection (Optional) Filter used in the query. 
         * @param selectionArgs (Optional) Selection arguments used in the query. 
         * @return The value of the _data column, which is typically a file path. 
         */
        public static String getDataColumn(Context context,Android.Net.Uri uri, String selection,
                String[] selectionArgs)
        {

            ICursor cursor = null;
            String column = "_data";
            String[] projection = {
                column
            };

            try
            {
                cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs,
                        null);
                if (cursor != null && cursor.MoveToFirst())
                {
                    int index = cursor.GetColumnIndexOrThrow(column);
                    return cursor.GetString(index);
                }
            }
            finally
            {
                if (cursor != null)
                    cursor.Close();
            }
            return null;
        }


        /** 
         * @param uri The Uri to check. 
         * @return Whether the Uri authority is ExternalStorageProvider. 
         */
        public static bool isExternalStorageDocument(Android.Net.Uri uri)
        {
            return "com.android.externalstorage.documents".Equals(uri.Authority);
        }

        /** 
         * @param uri The Uri to check. 
         * @return Whether the Uri authority is DownloadsProvider. 
         */
        public static bool isDownloadsDocument(Android.Net.Uri uri)
        {
            return "com.android.providers.downloads.documents".Equals(uri.Authority);
        }

        /** 
         * @param uri The Uri to check. 
         * @return Whether the Uri authority is MediaProvider. 
         */
        public static bool isMediaDocument(Android.Net.Uri uri)
        {
            return "com.android.providers.media.documents".Equals(uri.Authority);
        }

        /** 
         * @param uri The Uri to check. 
         * @return Whether the Uri authority is Google Photos. 
         */
        public static bool isGooglePhotosUri(Android.Net.Uri uri)
        {
            return "com.google.android.apps.photos.content".Equals(uri.Authority);
        }

        #endregion

    }

 

posted @ 2016-06-03 17:19  mycing  阅读(5312)  评论(2编辑  收藏  举报