【问题标题】:How to capture an image and save it in storage and show in ImageView?如何捕获图像并将其保存在存储中并在 ImageView 中显示?
【发布时间】:2017-09-09 11:31:48
【问题描述】:

我花了几个小时尝试拍照并将其保存到手机的内部存储并将其设置为 ImageView。

我尝试了 Stackoverflow 和 youtube 的几个代码,但只是得到了 FileUriExposedException ......我不知道为什么。也许你有一个想法。

我读到您应该使用 content:// 而不是 file://,但这就是我的问题的原因吗?

我得到:

Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/test.jpg exposed beyond app through ClipData.Item.getUri()
                                                             at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
                                                             at android.net.Uri.checkFileUriExposed(Uri.java:2346)
                                                             at android.content.ClipData.prepareToLeaveProcess(ClipData.java:845)
                                                             at android.content.Intent.prepareToLeaveProcess(Intent.java:8941)
                                                             at android.content.Intent.prepareToLeaveProcess(Intent.java:8926)
                                                             at android.app.Instrumentation.execStartActivity(Instrumentation.java:1517)
                                                             at android.app.Activity.startActivityForResult(Activity.java:4225)
                                                             at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
                                                             at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
                                                             at android.app.Activity.startActivityForResult(Activity.java:4183)
                                                             at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
                                                             at ibas.orosol.BildActivity.takePicture(BildActivity.java:86)
                                                             at java.lang.reflect.Method.invoke(Native Method) 
                                                             at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                                                             at android.view.View.performClick(View.java:5637) 
                                                             at android.view.View$PerformClick.run(View.java:22429) 
                                                             at android.os.Handler.handleCallback(Handler.java:751) 
                                                             at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                             at android.os.Looper.loop(Looper.java:154) 
                                                             at android.app.ActivityThread.main(ActivityThread.java:6119) 
                                                             at java.lang.reflect.Method.invoke(Native Method) 
                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

这是我的活动

final private int REQUEST_CODE_ASK_PERMISSION = 123; //kann jegliche Zahl sein. Wir benutzens halt später
final private int CAMERA_REQUEST = 555; //kann jegliche Zahl sein. Wir benutzens halt später

private File imageFile;

private ImageView mImageView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bild);
    getSupportActionBar().setTitle("");
    getSupportActionBar().setBackgroundDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.kopf_app, null));
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    mImageView = (ImageView) findViewById(R.id.imageView);

    // wenn die Permission NICHT gegeben wurde... und was wir dann machen kommt in diesem Block
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){

        if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)){

            //Hier können wir eintragen, wieso wir eigentlich die Permission brauchen/verlangen
        }else{

            //Permission anfragen
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSION);
        }
    }
    //---------------------------------------------------------------------------------------------
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSION);

}

public void takePicture(View view) throws IOException {

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    File file = getFile();

    imageFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "test.jpg");

    Uri tempUri = Uri.fromFile(imageFile);
    String path = "sdcard/orosol/captured_image.jpg";

    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
    startActivityForResult(cameraIntent, CAMERA_REQUEST);

}


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

    String path = "sdcard/orosol/captured_image.jpg";
    if(imageFile.exists()){
        Log.i("imagefile", "exists in: " + imageFile.getAbsolutePath());
    }else{
        Log.i("imagefile", "existiert nicht!");
    }

}

【问题讨论】:

标签: android file path camera imageview


【解决方案1】:

如果您的 targetSdkVersion 为 24 或更高,我们必须使用 FileProvider 类来授予对特定文件或文件夹的访问权限,以便其他应用程序可以访问它们。

将 file:// uri 替换为 content:// uri 的步骤:

将此添加到您的清单中

 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 ...
 <application
...
<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/provider_paths"/>
</provider>
</application>
</manifest>

然后在 res 文件夹下的 xml 文件夹中创建一个 provider_paths.xml 文件。如果文件夹不存在,可能需要创建它。该文件的内容如下所示。它描述了我们希望共享对位于根文件夹 (path=".") 的外部存储的访问权限,名称为 external_files。

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

最后一步是更改下面的代码行

Uri photoURI = Uri.fromFile(createImageFile());

Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());

【讨论】:

  • 谢谢,我收到Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference 在这一行:Uri tempUri = FileProvider.getUriForFile(BildActivity.this, BuildConfig.APPLICATION_ID + ".provider", imageFile); `
  • 你从哪里得到这个异常?
  • 而不是 BuildConfig.APPLICATION_ID 使用 this.getApplicationContext().getPackageName()
  • 仍然无法正常工作:我只是在使用您的代码,但应用程序崩溃了
猜你喜欢
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多