【问题标题】:Using android's native Camera App to capture photos throws SecurityException使用android原生Camera App拍照会抛出SecurityException
【发布时间】:2018-03-28 12:13:46
【问题描述】:

我正在尝试从 android 设备的本机相机应用程序中拍照。为此,我首先创建一个文件,然后附加其 URI,以捕获图像并在该文件中写入输出。 对于文件提供程序,我在 AndroidManifest 文件中添加了以下内容

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

获取图片的java代码如下

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            String imageName = "image_" + Preferences.getStringForUserId(mActivity);
            photoFile = createImageFile(imageName);
            mCurrentPhotoPath = photoFile.getAbsolutePath();

        } catch (IOException ex) {
            // Error occurred while creating the File
            ex.printStackTrace();
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            try {
                if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    String authorities = "com.example.myapp.fileprovider";
                    Uri photoURI = FileProvider.getUriForFile(mActivity, authorities, photoFile);
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);

                } else {
                    Uri photoURI = Uri.fromFile(photoFile);
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                }
                mActivity.startActivityForResult(takePictureIntent, CAMERA_CODE);

            } catch (Exception ex) {
                // Error occurred while creating the File
                ex.printStackTrace();
                Toast.makeText(mActivity, ex.toString(), Toast.LENGTH_LONG).show();
            }
        }
    } else {
        Toast.makeText(mActivity, "No Camera App found in device", Toast.LENGTH_LONG).show();
    }

如 Google 在 Android 自己的文档中所述:https://developer.android.com/training/camera/photobasics.html 我添加了必要的权限

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

但没有添加相机权限,我还要求 Android M 或更高版本的运行时权限。 从谷歌文档中可以清楚地看出,如果我们想使用原生相机应用程序为我们的应用程序拍摄照片,我们不需要相机权限,那么为什么它会给我下面说明的这个异常

java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.android.camera/.Camera clip={text/uri-list U:file:/ //storage/emulated/0/Android/data/com.example.myapp/files/Pictures/myapp/image_20130-1383873550.jpg}(有附加功能)}来自ProcessRecord{d82d864 6641:com.pencilinapp.pencilin/u0a63}( pid=6641, uid=10063) 撤销权限 android.permission.CAMERA

所以我的问题是,从现在开始我是否必须同时请求相机和存储权限?为什么 Google 文档中没有说明?

我已经研究并检查了许多 stackoverflow 线程,但到目前为止没有一个给出与此问题相关的答案。

【问题讨论】:

  • “从谷歌文档中得到很明显,如果我们想使用原生相机应用程序为我们的应用程序拍摄照片,我们不需要相机权限” - 你确定吗?
  • 因为我也给了链接请看这个developer.android.com/training/camera/photobasics.html没有提到添加相机权限
  • Google 说 - 如果您通过调用现有的相机应用程序来使用相机,您的应用程序不需要请求此权限。 developer.android.com/guide/topics/media/camera.html
  • @ShaluTD 并且在我访问过的几乎所有博客中添加了相机应用程序的图像捕捉功能,我看到他们只添加了存储权限,我也这样做了,我的应用程序运行良好一段时间(也许已经从应用设置授予权限,idk ..)但最近当我检查我的图像捕获功能时,它开始给我这个异常
  • 我认为你已经将它与使用 Camera API 拍摄图像混淆了。不,我没有使用相机 API,我只是利用 Android 的相机应用程序。我也看过这个文档。是的,当然谷歌说“如果你通过调用现有的相机应用程序来使用相机,你的应用程序不需要请求这个权限”,那么他们为什么现在给出 SecurityException 呢?这就是我想知道的

标签: java android


【解决方案1】:

问题是被撤销的权限(“with revoked permission android.permission.CAMERA”)。通常,您不需要许可,但如果您请求许可(例如,在您的应用程序的先前版本中),并且用户撤销了该许可,则您不能使用ACTION_IMAGE_CAPTURE。

【讨论】:

  • 好的,所以我得到的是,在我在以前的构建中请求此权限之前,我(作为用户)可能已经拒绝了它,所以现在它给了我这个例外,对吧?那么它的解决方案必须是什么?
  • @Faizy_Flash:就您的应用而言,不再要求CAMERA 权限。对于现有安装,通过设置应用授予权限或重新安装应用。
  • 好的,谢谢,还有一个问题,如果我仍然不使用此权限 '' 我应该以编程方式检查它是否是授予与否,然后从旧用户的权限设置中询问是否允许?
  • @Faizy_Flash:嗯,你可能需要那个权限。不知道你在哪里设置了FileProvider来写照片。
  • 对不起,我的意思是... 我应该添加还是不添加?是的,我刚刚编辑了我的问题并添加了文件提供程序代码。我刚刚在模拟器上重新安装了应用程序,运行 Android M,没有相机许可,它仍然给出了异常。抱歉打扰了,但我似乎仍然没有找到解决办法
【解决方案2】:

在您的 Manifest.xml 中添加以下行:

<uses-feature
android:name="android.hardware.camera.any"
android:required="true" />

<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

更多信息请参考URL。

【讨论】:

    【解决方案3】:

    但是,并非所有 Android 设备实际上都具有这些硬件功能。因此,如果您的应用请求 CAMERA 权限,请务必在清单中包含 &lt;uses-feature&gt; 标记以声明此功能是否实际需要。 欲了解更多信息,请参阅Google Play and feature-based filtering

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="your package" >
        <uses-permission android:name="android.permission.CAMERA"/>
        <uses-permission  android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-feature android:name="android.hardware.camera2.full" />
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    来自 Marshmallow,危险的权限是:

    1. READ_CALENDAR
    2. WRITE_CALENDAR
    3. 相机
    4. READ_CONTACTS
    5. WRITE_CONTACTS
    6. GET_ACCOUNTS
    7. ACCESS_FINE_LOCATION
    8. ACCESS_COARSE_LOCATION
    9. RECORD_AUDIO
    10. READ_PHONE_STATE
    11. CALL_PHONE
    12. READ_CALL_LOG
    13. WRITE_CALL_LOG
    14. ADD_VOICEMAIL
    15. USE_SIP
    16. PROCESS_OUTGOING_CALLS
    17. BODY_SENSORS
    18. SEND_SMS
    19. RECEIVE_SMS
    20. READ_SMS
    21. RECEIVE_WAP_PUSH
    22. RECEIVE_MMS
    23. READ_EXTERNAL_STORAGE
    24. WRITE_EXTERNAL_STORAGE

    所以我认为可能需要许可...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      相关资源
      最近更新 更多