无法获取相机

时间:2017-12-13 06:01:41

标签: java android android-camera-intent mediastore file-uri

我正在尝试制作相机活动,拍摄照片并将其保存到SD卡。但我发现我的代码破坏了用于获取File Uri的方法以及putExtra()方法。

调用startCamera()函数时,相机意图不会启动并终止活动。

private void startCamera(int actionCode) {
    //Create a camera intent
    Intent camera_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    switch (actionCode) {
        case CAM_REQ_CODE:
        File photo_file = null;
        try {
            photo_file = setUpPhotoFile();
        } catch (IOException e) {
            e.printStackTrace();
            photo_file = null;
            photo_path = null;
        }
        // Continue only if the File was successfully created
        if (photo_file != null) {
            photo_path = photo_file.getAbsolutePath();
            Uri photoURI = Uri.fromFile(photo_file);  //works
            //Uri photoURI = FileProvider.getUriForFile(InStore.this,"babygroot.iamgroot.fileprovider", photo_file);
            // PROBLEM!! how to overcome putExtra method to pass photo URI to MediaStore.EXTRA_OUTPUT
            camera_intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(camera_intent, CAM_REQ_CODE);
        }
        break;
        default:
            break;
    }
}

这是我的表现:

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

    <!-- To auto-complete the email text field in the login form with the user's emails -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-feature android:name="android.hardware.camera" />
    <!--<uses-feature android:name="android.hardware.camera2" /> -->
    <uses-feature android:name="android.hardware.camera.autofocus" />


    <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">

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

        <activity android:name=".LoginScreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".QRCode"
            android:parentActivityName=".LoginScreen" />
        <activity
            android:name=".SignUp"
            android:parentActivityName=".LoginScreen" />
        <activity
            android:name=".InStore"
            android:parentActivityName=".QRCode" />
        <activity android:name=".CheckOut" />
    </application>

</manifest>

InStore活动是使用相机功能的地方。

这是失败时的堆栈跟踪

Process: babygroot.iamgroot, PID: 26238
    java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Pictures/IAMGROOTPics/IMG_20171213_141445_787397456.jpg
                  at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:712)
                  at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:401)
                  at babygroot.iamgroot.InStore.startCamera(InStore.java:172)
                  at babygroot.iamgroot.InStore.showCameraPreview(InStore.java:111)
                  at babygroot.iamgroot.InStore.access$000(InStore.java:28)
                  at babygroot.iamgroot.InStore$1.onClick(InStore.java:63)
                  at android.view.View.performClick(View.java:5646)
                  at android.view.View$PerformClick.run(View.java:22459)
                  at android.os.Handler.handleCallback(Handler.java:761)
                  at android.os.Handler.dispatchMessage(Handler.java:98)
                  at android.os.Looper.loop(Looper.java:156)
                  at android.app.ActivityThread.main(ActivityThread.java:6523)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

RES / XML / 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.example.package.babygroot.iamgroot/files/Pictures" />
</paths>

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.package.babygroot.iamgroot/files/Pictures" />
</paths>

2 个答案:

答案 0 :(得分:1)

问题是android现在不允许读取其他应用程序的文件,这就是为什么你的代码崩溃了。见7.0 behaviour changes

请参阅本教程,使用FileProvider https://drivy.engineering/android-fileprovider/

执行任务

您基本上声明了一个共享文件位置,以便应用程序可以在那里进行读写操作。然后在那里创建一个文件,并使用该文件的Uri打开相机意图。

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="shared" path="shared/"/>
</paths>

最明确的文件声明

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="<your provider authority>"
    android:exported="false"
    android:grantUriPermissions="true">
  <meta-data
      android:name="android.support.FILE_PROVIDER_PATHS"
      android:resource="@xml/file_provider_paths"/>
</provider>

最后

Uri sharedFileUri = FileProvider.getUriForFile(this, <your provider auhtority>, sharedFile);

答案 1 :(得分:0)

就我而言

        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, "Image File name");
        mCapturedImageURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intentPicture.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
        startActivityForResult(intentPicture,REQUEST_IMAGE_CAPTURE);

上面的代码工作正常。

尝试用此替换您的代码。

并处理onActivityResult以获取活动中的图片。

Hpe有帮助!