Recently, I updated a project with android 7.0 and upper. I figured out the provider problem.
When I take photo and use onActivityForResult to resize the image or show it. I find the data is null. I wonder why? I have tried several ways to get Uri.
But the data is null.
//A button click to call this.
Uri tempUri;
private void takePhoto() {
if (isSdcardExisting()) {
//create a file.
File file = new File(getExternalFilesAbsolutePath(this),HERO_IMAGE);
if(file.exists()){
try {
file.delete();
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//use a class to deal uri problem android 7.0 problem.
Uri uri = FileProvider7.getUriForFile(this,file);
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
//put some keys to intent
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
cameraIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
/*
* grant uri
*
* the temp sulution :
* tempUri = uri;
*/
FileProvider7.grantUriPermission(this,cameraIntent,uri);
startActivityForResult(cameraIntent, CODE_TAKE_PHOTO);
} else {
Toast.makeText(this, "请插入SD卡", Toast.LENGTH_LONG)
.show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if(resultCode != RESULT_OK){
return;
}else{
switch (requestCode){
case CODE_TAKE_PHOTO:
/**
* the requestCode and resultCode is right,but the data is null
* I wander how to use this.
*
* the temp solution is to define a Uri obejct to store the uri.
*
* if(tempUri != null)
* resize(tempUri);
*/
Log.d(TAG, "onActivityResult: data ---> " + data);
if(data != null){
Bundle bundle = data.getExtras();
Log.d(TAG, "onActivityResult: bundle ---> " + bundle);
if(bundle != null){
Uri resizeUri = bundle.getParcelable(MediaStore.EXTRA_OUTPUT);
Log.d(TAG, "onActivityResult: resizeUri ---> " + resizeUri);
String imageType = bundle.getString("outputFormat");
Log.d(TAG, "onActivityResult: imageType ---> " + imageType);
Uri uri = data.getData();
Log.d(TAG, "onActivityResult: getData ---> " + uri);
resize(resizeUri);
}
}
break;
case CODE_SHOW_IMAGE:
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
I found a solution that the activity needs to add action in manifest activity intent filter.But it doesn't seems to work.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rambopan.demotryusercamera">
<uses-permission android:name="android.permission.CAMERA"/>
<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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="com.android.camera.action.CROP"/>
<action android:name="android.media.action.IMAGE_CAPTURE"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</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/file_paths" />
</provider>
</application>
</manifest>
The log.The uri is ok,the data is null.(Android 5.0)
06-12 15:26:11.063 368-368/com.rambopan.demotryusercamera D/XADAX.FileProvider7: getUriForFile: ---> file:///storage/emulated/0/Android/data/com.rambopan.demotryusercamera/files/hero
06-12 15:26:32.624 368-368/com.rambopan.demotryusercamera D/XADAX.MainActivity: onActivityResult: data ---> null