【问题标题】:Android FileProvider Causing Camera/Gallery to Crash at RandomAndroid FileProvider导致相机/画廊随机崩溃
【发布时间】:2016-09-13 21:50:19
【问题描述】:

美好的一天。

借助从开发人员指南获得的帮助,我能够让我的应用程序的照片捕捉正常工作。该活动通常涉及捕获一张或多张图像(例如在 photogrid 相机拼贴应用程序中)。它大部分时间都可以在大多数设备上运行,除了我自己的设备(Android 5.0.1)。问题是,相机/图库应用程序崩溃,在堆栈跟踪中给我一个安全权限拒绝错误,我已经搜索了解决方案并实施了它们,但无济于事。崩溃通常是随机的,但更有可能发生在以下情况: 1.我正在拍第二张照片 2. 我的相机设置为最高分辨率:13MP(在较低分辨率下几乎不会发生)

虽然在其他情况下很少发生,但它的出现让我发疯。这是我的代码:

片段

    private void dispatchTakePictureIntent(boolean isQuestionImage) {
            Intent takePictureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

            if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {

                File photoFile = null;
                try {
                    photoFile = createImageFile(isQuestionImage);
                } catch (IOException ex) {
                    Log.e("photofile part", "Error: "+ex);
                }

                if (photoFile != null) {
                    Uri photoURI = FileProvider.getUriForFile(getActivity(),
                            "com.operator.u_learn.fileprovider", photoFile);

                    if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
                        takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                        takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                    }
                    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
                        List<ResolveInfo> resolvedIntentActivities = getActivity()
                                .getPackageManager()
                                .queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);

                          for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities) {
                               String packageName = resolvedIntentInfo.activityInfo.packageName;

                                getActivity().grantUriPermission(packageName,
                                    photoURI,
                     Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        }
                    }

                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);

                    if(isQuestionImage)
                        startActivityForResult(takePictureIntent, REQUEST_QUESTION_IMAGE_CAPTURE);
                    else
                        startActivityForResult(takePictureIntent, REQUEST_EXPLANATION_IMAGE_CAPTURE);

                    //revoke permissions after use
                    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
                        getActivity().revokeUriPermission(photoURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    }

                }
            }
        }

AndroidManifest.xml

<provider


android:name="android.support.v4.content.FileProvider"


android:authorities="com.operator.u_learn.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data


android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"></meta-

data>
        </provider>

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths 

xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" 

path="Android/data/com.operator.u_learn/files/Pictures" />
</paths>

这是我得到的错误

E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: 

com.android.gallery3d, PID: 18974


java.lang.SecurityException: Permission Denial: opening 

provider android.support.v4.content.FileProvider from 

ProcessRecord{3b596555 18974:com.android.gallery3d/u0a42} 

(pid=18974, uid=10042) that is not exported from uid 10221
                                                       at 

android.os.Parcel.readException(Parcel.java:1540)
                                                       at 

android.os.Parcel.readException(Parcel.java:1493)

【问题讨论】:

    标签: android android-camera android-fileprovider


    【解决方案1】:

    根据我的经验,您的相机模块被之前的活动锁定。您可以通过运行预览另一个相机应用并立即切换到您的相机应用预览屏幕来检查它。

    最高分辨率可能会使它更频繁地出现,因为它需要更多时间才能发布。

    如您所知,厂商+硬件+摄像头驱动+操作系统+厂商默认的摄像头应用组合在Android设备中有几种不同的实现方式。有些允许通过自动释放以前访问的应用程序(LG Nexus 5)来访问相机 api,而另一些则崩溃(LG G2 手机)。

    要解决这个问题,如果我的诊断正确,我建议您在启动之前添加大约Thread.sleep(500); 的睡眠计数器。

    或者,try-catch Camera.open() 方法。如果它被其他处理器锁定,它可能会给出RuntimeException。但根据我的经验,Camera API 非常不可靠,所以让我们在几乎每一行 api 命令中都包含 try-catch 代码。

    虽然这个答案不能解决 Gallery 崩溃问题,但相机可以。

    【讨论】:

    • 我也想到了使用延迟,等我恢复电源后我会试试这个。但只是为了澄清,我应该将 Thread.sleep 放在哪里?编辑:即使我尝试忽略文件提供程序并使用 URI.fromFile 方法,它有时仍然崩溃但没有给出错误消息。我会尽快尝试解决方案
    • @Mofe-hendyEjegi // 在您第一次尝试使用 Camera api 之前。
    • 很好,真的很有帮助,我一直在测试,没有更多的崩溃。但它确实失败了一次,所以我会继续试验,谢谢。我会在完成测试后立即标记为已回答
    • @Mofe-hendyEjegi // 可能有助于将睡眠时间调整为“1000”。
    • 是的,睡眠时间越长,出错的可能性就越小。但是tbh我真的不喜欢处理机会,虽然我一直在 startActivityForResult 方法之前和之后调用睡眠
    猜你喜欢
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 2019-05-03
    相关资源
    最近更新 更多