在API 19上使用相机拍摄图像会崩溃,但它适用于API 21及更新版本

时间:2017-10-14 20:16:34

标签: android

我有一个应用程序可以让你列出一个列表,并为每个项目添加名称,价格,描述,图像等。

我开始使用最低API级别21编写应用程序。我正在尝试将其降低到API 19,以便我可以获得一些KitKat用户。

当API 19上的用户尝试使用该应用拍照时,会出现此问题。当他们按下“拍照”按钮时,相机拉得很好,但是当他们拍照并点击勾选图像以保存图像时,相机应用程序会崩溃。

以下是相机应用日志中的错误代码。我看到的主线是:

 Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{a517eda0 12685:com.android.camera/u0a32} (pid=12685, uid=10032) that is not exported from uid 10057
Process: com.android.camera, PID: 12685
java.lang.IllegalStateException: Could not execute method of the activity at android.view.View$1.onClick(View.java:3823)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View$1.onClick(View.java:3818)
at android.view.View.performClick(View.java:4438) 
at android.view.View$PerformClick.run(View.java:18422) 
at android.os.Handler.handleCallback(Handler.java:733) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5017) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{a517eda0 12685:com.android.camera/u0a32} (pid=12685, uid=10032) that is not exported from uid 10057
at android.os.Parcel.readException(Parcel.java:1465)
at android.os.Parcel.readException(Parcel.java:1419)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2848)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:4415)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2207)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:906)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:669)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:645)
at com.android.camera.Camera.doAttach(Camera.java:1385)
at com.android.camera.Camera.onReviewDoneClicked(Camera.java:1362)
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at android.view.View$1.onClick(View.java:3818) 
at android.view.View.performClick(View.java:4438) 
at android.view.View$PerformClick.run(View.java:18422) 
at android.os.Handler.handleCallback(Handler.java:733) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5017) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
at dalvik.system.NativeStart.main(Native Method) 

而且,因为我认为这是一种权限类型,所以这是我的AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jeremy.com.wineofmine">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name="jeremy.com.wineofmine.MainActivity"

        android:screenOrientation="portrait"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name="jeremy.com.wineofmine.AddActivity"
        android:label=""
        android:parentActivityName="jeremy.com.wineofmine.MainActivity"
        android:screenOrientation="portrait" />
    <activity
        android:name="jeremy.com.wineofmine.DetailsActivity"
        android:label=""
        android:parentActivityName="jeremy.com.wineofmine.MainActivity"
        android:screenOrientation="portrait" />
    <activity
        android:name="jeremy.com.wineofmine.EditActivity"
        android:label=""
        android:parentActivityName="jeremy.com.wineofmine.MainActivity"
        android:windowSoftInputMode="stateHidden" />

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="jeremy.com.wineofmine.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

    <activity android:name="jeremy.com.wineofmine.ImageActivity"
        android:parentActivityName="jeremy.com.wineofmine.DetailsActivity"></activity>
</application>

有谁知道这里发生了什么?我不知所措。我相信我允许应用程序使用清单中的这两个权限行来访问文件。

如果有任何其他代码有用,请告诉我。

更新1:

添加相机意图代码(在我没有FLAG_GRANT_WRITE_URI_PERMISSION行之前,但由于CommonsWare的帖子我添加了它。它没有解决问题):

private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        takePictureIntent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();

            } catch (IOException ex) {

            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                photoURI = FileProvider.getUriForFile(this,
                        "jeremy.com.wineofmine.fileprovider",
                        photoFile);

                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);

            }
        }
    }

1 个答案:

答案 0 :(得分:3)

对不起,我在评论中反过来了。相机应用正在编写,因此您需要将FLAG_GRANT_WRITE_URI_PERMISSION添加到Intent

更新 ...而且,由于您尝试支持Android 4.4,因此您还需要执行this crap

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) {
  i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
else {
  ClipData clip=
    ClipData.newUri(getContentResolver(), "whatevs", outputUri);

  i.setClipData(clip);
  i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}

其中:

  • iIntent
  • outputUri是您用于EXTRA_OUTPUT
  • 的值