【问题标题】:Camera Crash when retrieving photo检索照片时相机崩溃
【发布时间】:2019-08-30 09:29:13
【问题描述】:

我在尝试从相机中检索照片时遇到问题

我试图让用户使用相机应用程序拍照,然后在应用程序中显示它的预览。

我还需要在应用程序的稍后阶段访问该文件(但这不是问题)

我遇到了以下崩溃:

Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{41f55850 10769:com.sec.android.app.camera/u0a84} (pid=10769, uid=10084) that is not exported from uid 10119

我关注了This link 和其他几个人。我的 Galaxy S8+ 等设备没有问题。仅此运行 Android 4.4.4 API 19 的设备。

Android 清单:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">

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

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="Android/data/com.example.app/files/Pictures" />
</paths>

PhotoActivity.java

    private File setUpPhotoFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    String imageFileName = "IMG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",   /* suffix */
            storageDir      /* directory */
    );
    return image;
}

单击按钮时启动相机意图:

if (isCameraApplicationAvailable(PhotoActivity.this)) {
                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);


                File f = null;
                try {
                    f = setUpPhotoFile();
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(PhotoActivity.this, BuildConfig.APPLICATION_ID + ".provider", f));
                } catch (IOException e) {
                   // Handle exception
                }
                List<ResolveInfo> resolvedIntentActivities = getPackageManager().queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);
                for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities) {
                    String packageName = resolvedIntentInfo.activityInfo.packageName;

                    grantUriPermission(packageName, Uri.fromFile(f), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
                takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivityForResult(takePictureIntent, ACTION_TAKE_PHOTO);
            }

完成后处理图片:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ACTION_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
        handleCameraPhoto();
    }
}

我不明白为什么它只是 4.4.4 的问题,而不是其他操作系统的问题。

当发生崩溃时,并不是说我的应用程序崩溃了,而是说相机已停止工作,我只能在查看没有过滤器的日志时才能查看崩溃,这意味着崩溃不在我的应用程序中?

【问题讨论】:

标签: java android


【解决方案1】:

根据@MikeM 的评论,我使用Uri.fromFile(file) 而不是使用FileProvider 来获取Uri。

正在这样做:

grantUriPermission(packageName, Uri.fromFile(f), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

什么时候我应该这样做:

grantUriPermission(packageName, FileProvider.getUriForFile(PhotoActivity.this, BuildConfig.APPLICATION_ID + ".provider", f), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

这解决了我遇到的问题

谢谢@MikeM

【讨论】:

    【解决方案2】:

    出于安全原因使用文件提供程序,您必须在您的意图中使用标志。所以在你的takePictureIntent 中使用addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); or addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

    这是 Android

    【讨论】:

      【解决方案3】:

      我认为一个简单的检查将解决您的问题。

            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
             grantUriPermission(packageName, Uri.fromFile(f), 
      Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 
      
          takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_READ_URI_PERMISSION);
              }
      

      【讨论】:

        【解决方案4】:

        您遇到此问题是因为您尚未在 google 上的应用搜索中指定运行时权限,以便在这样做之后以编程方式指定运行时权限,您的问题应该得到解决。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-07-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多