我有几个小时试图拍照并将其保存到手机的内部存储空间并将其设置为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!");
}
}
答案 0 :(得分:1)
如果您的targetSdkVersion为24或更高,我们必须使用FileProvider类来访问特定文件或文件夹,以使其可供其他应用访问。
使用content:// uri:
替换file:// 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文件。如果文件夹不存在,则可能需要创建文件夹。该文件的内容如下所示。它描述了我们希望在名称为external_files的根文件夹(path =&#34;。&#34;)之间共享对外部存储的访问。
<?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());