为什么拍照时会发生FileNotFoundException:?

时间:2019-02-21 08:49:47

标签: android android-camera android-contentprovider

我尝试拍照,并通过以下代码将照片保存到内部:

public void startCamera() {


        picPath = getFilesDir() + File.separator + "AitrixShot" + ".jpg";

        if (Build.VERSION.SDK_INT >= 23) {
            if (!hasCameraPhoneAuth()) {
                mActivity.requestPermissions(authCameraArr, authCameraRequestCode);
                return;
            }
        }

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        if (Build.VERSION.SDK_INT > 24) {

            ContentValues contentValues = new ContentValues(1);
            contentValues.put(MediaStore.Images.Media.DATA, picPath);
            Uri uri = mActivity.getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, contentValues);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            mActivity.startActivityForResult(intent, FlyManager_TAG_LIST.TAKE_PHOTO_REQUEST);
        }

    }

我还像下面这样在AndroidManifest.xml中添加了提供程序:

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

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

            <activity
                android:name=".CoverActivity"
                android:theme="@style/AppTheme.NoActionBar">
            </activity>

            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="${applicationId}.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_path" />
            </provider>
                     .
                     .
                     .

provider_path.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path path="Android/data/com.example.aitrixflymanager/" name="files_root" />
    <files-path path="." name="file_root" />

</paths>

但是它仍然显示以下错误:

2019-02-21 16:35:55.870 6177-6177/? E/CAM_StateSavePic: exception while saving result to URI: Optional.of(content://media/internal/images/media/191)
    java.io.FileNotFoundException: Can't access /data/user/0/com.example.aitrixflymanager/files/AitrixShot/plane_shot_20190221_163548.jpg
        at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:144)
        at android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:625)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1267)
        at android.content.ContentResolver.openOutputStream(ContentResolver.java:1009)
        at android.content.ContentResolver.openOutputStream(ContentResolver.java:985)
        at com.android.camera.captureintent.state.StateSavingPicture.onEnter(StateSavingPicture.java:85)
        at com.android.camera.captureintent.stateful.StateMachineImpl.jumpToState(StateMachineImpl.java:63)
        at com.android.camera.captureintent.stateful.StateMachineImpl.processEvent(StateMachineImpl.java:112)
        at com.android.camera.captureintent.state.StateReadyForCapture$31.onClick(StateReadyForCapture.java:943)
        at android.view.View.performClick(View.java:6305)
        at android.view.View$PerformClick.run(View.java:24840)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6501)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

我错过了什么吗?预先感谢。

5 个答案:

答案 0 :(得分:0)

鉴于picPath错误,您串联了“ .jpg”。

picPath = getFilesDir() + File.separator + "test" + ".jpg";  //is not picPath

答案 1 :(得分:0)

您必须在AndroidManifest中放置应用程序ID而不是$ {applicationId}

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

答案 2 :(得分:0)

使用以下几行:

private final String capture_dir = Environment.getExternalStorageDirectory() + "/Images";
path = capture_dir + System.currentTimeMillis() + ".jpg";

在清单中,

 <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="{your package name}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

provider_paths.xml,

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

答案 3 :(得分:0)

尝试此代码。

//Global key for Photo Request.
public static final int PHOT_REQUEST_CODE = 1;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

   // mRealm = Realm.getDefaultInstance();
    pickImage = findViewById(R.id.pickImage);
    linearLayout = findViewById(R.id.linearLayout);
    listing_image = findViewById(R.id.listing_image);


    pickImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_PICK);
            intent.setType("image/*");
            startActivityForResult(intent, PHOT_REQUEST_CODE);
        }
    });

}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

    if (requestCode == PHOT_REQUEST_CODE && resultCode == RESULT_OK){

        Uri contentURI = data.getData();
        try {
            String fileString = contentURI.getPath(); //Image Path.
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
            String path = saveImage(bitmap);
            //Toast.makeText(MainActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
            listing_image.setImageBitmap(bitmap);
            ByteArrayOutputStream baos=new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
            byte [] b=baos.toByteArray();
            String temp= Base64.encodeToString(b, Base64.DEFAULT);

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show();
        }
    }

答案 4 :(得分:0)

  

尝试此代码,可能会对您有所帮助

 File photoFile= new File(picPath); 
 Uri uri = null;  
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        uri = FileProvider.getUriForFile(c.getApplicationContext(),
                                packagename,
                                photoFile);


                    } else {
                        uri = Uri.fromFile(photoFile);
                                               }