转载——解决小米miui系统调用系统裁剪图片功能camera.action.CROP后崩溃或重新打开app的问题

本文介绍了一个在小米系统中使用com.android.camera.action.CROP进行图片剪裁时遇到的权限问题,详细分析了错误日志,并推测可能的原因是由于缺少特定权限导致的。
最近向做一个头像剪裁的功能,调用系统的gallery选择图片,用com.android.camera.action.CROP对URI剪裁便可以实现。
用联想的一部手机测试如下代码没问题
Java code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public  void  ChooseImage(View v) {
         Intent intent =  new  Intent(Intent.ACTION_GET_CONTENT); // ACTION_OPEN_DOCUMENT
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.setType( "image/*" );
         if  (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
             startActivityForResult(intent, SELECT_PIC_KITKAT);
         else  {
             startActivityForResult(intent, SELECT_PIC);
         }
     }
 
@Override
     public  void  onActivityResult( int  requestCode,  int  resultCode, Intent data) {
         if  (RESULT_OK == resultCode) {
             switch  (requestCode) {
             case  SELECT_PIC_KITKAT:
                 Uri selectedImage = data.getData();
                 startPhotoZoom(selectedImage);
                 break ;
             case  3 :
                 if (data !=  ){  
                     setPicToView(data);  
                 }
                 break ;
             default :
                 break ;
             }
         }
     }
 
public  void  startPhotoZoom(Uri uri) {
         Intent intent =  new  Intent( "com.android.camera.action.CROP" );
         intent.setDataAndType(uri,  "image/*" );
         intent.putExtra( "crop" "true" );
         intent.putExtra( "aspectX" 1 );
         intent.putExtra( "aspectY" 1 );
         intent.putExtra( "outputX" 150 );
         intent.putExtra( "outputY" 150 );
         intent.putExtra( "return-data" true );
         startActivityForResult(intent,  3 );
     }


但是小米系统下提示加载图片失败,去看了下log提示如下:
W/Worker  (18831): Exception in running a job
W/Worker  (18831): java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{43ca3940 18831:com.miui.gallery:crop/u0a6} (pid=18831, uid=10006) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
W/Worker  (18831):  at android.os.Parcel.readException(Parcel.java:1465)
W/Worker  (18831):  at android.os.Parcel.readException(Parcel.java:1419)
W/Worker  (18831):  at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2860)
W/Worker  (18831):  at android.app.ActivityThread.acquireProvider(ActivityThread.java:4448)
W/Worker  (18831):  at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2239)
W/Worker  (18831):  at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1430)
W/Worker  (18831):  at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1052)
W/Worker  (18831):  at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:909)
W/Worker  (18831):  at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:766)
W/Worker  (18831):  at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:721)
W/Worker  (18831):  at com.miui.gallery.data.UriImage.openOrDownloadInner(UriImage.java:141)
W/Worker  (18831):  at com.miui.gallery.data.UriImage.openFileOrDownloadTempFile(UriImage.java:116)
W/Worker  (18831):  at com.miui.gallery.data.UriImage.prepareInputFile(UriImage.java:210)
W/Worker  (18831):  at com.miui.gallery.data.UriImage.access$100(UriImage.java:48)
W/Worker  (18831):  at com.miui.gallery.data.UriImage$BitmapJob.run(UriImage.java:233)
W/Worker  (18831):  at com.miui.gallery.data.UriImage$BitmapJob.run(UriImage.java:225)
W/Worker  (18831):  at com.miui.gallery.app.CropImageBase$LoadBitmapDataTask.run(CropImageBase.java:1003)
W/Worker  (18831):  at com.miui.gallery.app.CropImageBase$LoadBitmapDataTask.run(CropImageBase.java:975)
W/Worker  (18831):  at com.miui.gallery.util.ThreadPool$Worker.run(ThreadPool.java:130)
W/Worker  (18831):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/Worker  (18831):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/Worker  (18831):  at java.lang.Thread.run(Thread.java:841)
W/Worker  (18831):  at com.miui.gallery.util.PriorityThreadFactory$1.run(PriorityThreadFactory.java:43)

猜测调用com.android.camera.action.CROP实际为com.miui.gallery:crop缺少权限。
<think>首先,用户的问题集中在纯血鸿蒙系统(HarmonyOS NEXT)上,通过卓易通下载安卓APP后,无法调用系统裁剪功能com.android.camera.action.CROP。用户提供的引用是关于Android系统裁剪意图的使用和问题,包括错误处理、设置参数等。 关键点是: - 引用[1]讨论了设置裁剪尺寸,但矩形不填充图像的问题。 - 引用[2]提到ActivityNotFound错误,建议在Intent跳转前检测是否存在处理该Intent的Activity。 - 引用[3]展示了Intent设置,包括aspectX/aspectY用于比例,避免设置outputX/outputY以防止拉伸,使用return-data=false并指定输出路径。 - 引用[4]描述了找不到处理Intent的Activity的错误。 用户的核心需求是解决在HarmonyOS NEXT上运行安卓APP无法调用com.android.camera.action.CROP问题。这可能是因为HarmonyOS未内置支持该Intent。 我的回答需要: - 结构化清晰,逐步解决问题。 - 使用中文。 - 生成相关问题。 - 添加引用标识到相关段落末尾。 - 确保LaTeX语法正确(虽然图片裁剪可能不涉及数学,但如果有比例计算等,需用$...$)。 解决策略: 1. **确认问题根源**:HarmonyOS NEXT是纯鸿蒙系统,可能不支持Android的特定Intent如com.android.camera.action.CROP。 2. **替代方案**: - 使用鸿蒙系统提供的裁剪API。 - 在APP内部实现裁剪功能(如使用第三方库)。 - 检测Intent可用性,避免崩溃。 3. **具体步骤**: - 在Intent调用前检查是否有Activity能处理它。 - 如果不支持,回退到自定义裁剪提示用户。 - 参考引用[3],优化Intent设置以减少问题。 4. **代码示例**:提供Java/Kotlin代码片段,演示如何安全调用。 5. **生成相关问题**:在最后添加相关问题。 回答结构: 1. **引言**:简述问题,强调在HarmonyOS上的挑战。 2. **解决方案步骤**: - 步骤1:检查Intent可用性(引用[2])。 - 步骤2:优化Intent设置(引用[3])。 - 步骤3:使用替代方法(如鸿蒙API自定义裁剪)。 3. **代码示例**:展示安全调用裁剪Intent的代码。 4. **结论**:总结建议。 5. **相关问题**。 引用标识:在相关建议后添加[^1], [^2], [^3], [^4]。 确保真实可靠: - 鸿蒙系统可能不兼容所有Android Intent,建议使用鸿蒙官方文档。 - 在APP中集成裁剪库更可靠。 最终回答: - 用中文。 - 逐步解释。 - 生成相关问题。 </think>### 解决纯血鸿蒙系统通过卓易通下载安卓APP无法调用com.android.camera.action.CROP进行图片裁剪问题 在纯血鸿蒙系统(HarmonyOS NEXT)上通过卓易通下载安卓APP后调用系统裁剪Intent `com.android.camera.action.CROP` 可能失败,原因包括:鸿蒙系统未内置该Intent的处理Activity、兼容性问题导致ActivityNotFound错误,Intent设置不当引发白屏/拉伸问题[^2][^4]。以下是我基于用户引用和鸿蒙系统特性整理的逐步解决方案。核心思路是优先检测Intent可用性,优化参数设置,并引入鸿蒙兼容替代方案。 #### 步骤1: 检测Intent可用性,避免ActivityNotFound错误 在调用裁剪Intent前,检查系统中是否有Activity能处理 `com.android.camera.action.CROP`。如果不存在,直接调用会导致崩溃(如引用[2][^2]所述)。在HarmonyOS上,安卓APP需通过兼容层运行,但纯鸿蒙内核可能缺少原生支持。 - **代码示例(Java/Kotlin)**: ```java Intent cropIntent = new Intent("com.android.camera.action.CROP"); cropIntent.setDataAndType(imageUri, "image/*"); // 检查Intent是否可处理 if (cropIntent.resolveActivity(getPackageManager()) != null) { // Intent可用,继续设置其他参数 startActivityForResult(cropIntent, CROP_REQUEST_CODE); } else { // Intent不可用,回退到自定义裁剪提示用户 Toast.makeText(context, "系统裁剪功能不支持,使用内置裁剪", Toast.LENGTH_SHORT).show(); useCustomCrop(imageUri); // 调用步骤3的自定义方法 } ``` **关键点**:此检查可防止崩溃,适用于鸿蒙系统上的安卓APP[^2]。如果检测失败,表明系统无内置裁剪组件,需跳过Intent调用。 #### 步骤2: 优化Intent参数设置,避免白屏尺寸错误 即使Intent可用,参数设置不当会导致裁剪失败(如引用[1][^3]所述)。在HarmonyOS上,确保: - 使用 `aspectX` 和 `aspectY` 设置宽高比例(如正方形则 `aspectX=1, aspectY=1`),但 **避免设置 `outputX/outputY`**,否则可能引发拉伸矩形不填充图像[^1][^3]。 - 设置 `return-data=false` 并指定输出路径(`MediaStore.EXTRA_OUTPUT`)以防止白屏问题[^3]。 - 添加权限标志以适应新系统版本。 - **代码示例优化**: ```java Uri outputUri = Uri.parse("file://" + customOutputPath); // 自定义输出路径 cropIntent.putExtra("crop", "true"); cropIntent.putExtra("scale", true); cropIntent.putExtra("aspectX", 1); // 正方形比例宽 cropIntent.putExtra("aspectY", 1); // 正方形比例高 // 不设置outputX/outputY,避免尺寸错误 cropIntent.putExtra("return-data", false); // 返回false,使用输出路径 cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri); cropIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); // 鸿蒙/N以上系统添加权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } ``` **效果**:此设置确保裁剪框正确覆盖图像(如400x600图像输出400x400正方形),减少兼容性问题[^3]。在鸿蒙测试中,部分设备可能仍失败,建议结合步骤1检测。 #### 步骤3: 使用鸿蒙兼容替代方案(推荐) 由于纯血鸿蒙系统(HarmonyOS NEXT)不再依赖Android兼容层,`com.android.camera.action.CROP` 可能完全不可用。推荐以下替代方法: 1. **集成第三方裁剪库**:在APP中直接嵌入裁剪功能,不依赖系统Intent。常用库如: - Android平台:`ucrop`(开源,支持自定义尺寸)。 - 鸿蒙平台:使用HarmonyOS的 `Image` 和 `PixelMap` API 实现裁剪(需适配鸿蒙SDK)。 - **优势**:跨平台兼容,避免系统差异。 2. **调用鸿蒙系统裁剪API**:如果APP已迁移到鸿蒙原生开发,使用HarmonyOS提供的 `@ohos.multimedia.image` 组件。 - **简单代码示例(HarmonyOS JS/Java)**: ```java // 伪代码:使用鸿蒙Image组件裁剪 Image.SourceOptions srcOpts = new Image.SourceOptions(); srcOpts.srcUri = imageUri; // 输入图像URI ImageSource imageSource = ImageSource.create(srcOpts); PixelMap pixelMap = imageSource.createPixelmap(null); // 创建裁剪区域(如400x400正方形) Region region = new Region(0, 0, 400, 400); // 起点(x,y), 宽高 PixelMap croppedMap = pixelMap.crop(region); // 保存输出 croppedMap.writeToFile(outputPath); ``` - **注意**:纯安卓APP需通过卓易通运行时调用鸿蒙API可能受限,优先集成第三方库。 3. **用户提示降级处理**:如果检测Intent失败且无法集成库,提示用户手动裁剪使用其他APP。 #### 总结建议 - **首选方案**:在HarmonyOS NEXT上,避免依赖 `com.android.camera.action.CROP`。对于安卓APP,集成 `ucrop` 等库实现内置裁剪([GitHub示例](https://github.com/Yalantis/ucrop))。 - **调试技巧**:在鸿蒙设备上Logcat检查ActivityNotFound错误,确认Intent支持情况[^2][^4]。 - **风险**:纯鸿蒙系统对安卓Intent的支持逐步弱化,长期建议迁移到鸿蒙原生开发。 通过以上步骤,可有效解决裁剪失败问题。如果仍有疑问,请提供更多错误日志以进一步分析。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值