使用Android的原生相机应用程序捕获照片会抛出SecurityException

时间:2018-03-28 12:13:47

标签: java android

我正试图从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" />

但没有添加Camera的权限,我也要求Android M或更高版本的运行时权限。 从谷歌文档中获取很明显,如果我们想使用原生相机应用程序为我们的应用程序捕获照片,我们不需要相机权限,那么为什么它会给我下面说明的这个例外

  

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

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

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

3 个答案:

答案 0 :(得分:1)

问题是撤销权限(“具有撤销权限android.permission.CAMERA”)。通常情况下,您不需要权限,但如果您要求获得权限(例如,在应用的先前版本中),并且用户撤消该权限,则您无法使用ACTION_IMAGE_CAPTURE

答案 1 :(得分:0)

Manifest.xml

中添加以下行
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            addListItem();
            Snackbar.make(view,  "Item added to list".concat(" ").concat(listItems.get(listItems.size-1)), 
            Snackbar.LENGTH_LONG).setAction("Undo", undoOnClickListener).show();
        }
    });
}

请参阅此URL了解更多信息。

答案 2 :(得分:0)

但是,并非所有Android设备都具有这些硬件功能。因此,如果您的应用请求CAMERA权限,那么您还需要在清单中包含<uses-feature>标记,以声明是否确实需要此功能。 有关详细信息,请参阅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. 功能(6)
  2. WRITE_CALENDAR
  3. CAMERA
  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
  25. 我认为可能需要许可......