Pick image for crop from gallery and camera it\'s done for below Android 7.0 but in Android Nought it crashes in camera. I use fileprovider for it but doesn\'t work.
I have two source for crop,one is gallery and the other one is camera
the method gallery:
//take a photo from gallery
public void gallery() {
//set UUID to filename
String PHOTO_FILE_NAME = UUID.randomUUID().toString()+".jpg";
Utils.putValue(this, Constants.UserPortraitFilePath,PHOTO_FILE_NAME);
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
}
the method camera:
//take a photo from camera
public void camera() {
//check sdcard is usable or not
if (Utils.hasSdcard()) {
//set UUID to filename
String PHOTO_FILE_NAME = UUID.randomUUID().toString()+".jpg";
Utils.putValue(this,Constants.UserPortraitFilePath,PHOTO_FILE_NAME);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//set file location to DreamGo/Image
File path = Environment.getExternalStorageDirectory();
File dir = new File(path, "DreamGo/Image");
if(!dir.exists())
dir.mkdirs();
//Android N need use FileProvider get file
//uri because StrictMode System
//getUriForFile(content,provider author,file)
Uri photoURI = FileProvider.getUriForFile(context, "dream.go.provider",
new File(dir.getAbsolutePath(), PHOTO_FILE_NAME));
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, PHOTO_REQUEST_CAMERA);
}else {
showToast("no storage device");
}
}
the crop method:
//Android N crop image
public void crop(Uri uri) {
context.grantUriPermission("com.android.camera",uri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
//Android N need set permission to uri otherwise system camera don't has permission to access file wait crop
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra("crop", "true");
//The proportion of the crop box is 1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
//Crop the output image size
intent.putExtra("outputX", 800);
intent.putExtra("outputY", 800);
//image type
intent.putExtra("outputFormat", "JPEG");
intent.putExtra("noFaceDetection", true);
//true - don't return uri | false - return uri
intent.putExtra("return-data", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, PHOTO_REQUEST_CUT);
}
the onActivityResult method :
private static final int PHOTO_REQUEST_CAMERA = 0;//camera
private static final int PHOTO_REQUEST_GALLERY = 1;//gallery
private static final int PHOTO_REQUEST_CUT = 2;//image crop
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
String PHOTO_FILE_NAME = Utils.getValue(this, Constants.UserPortraitFilePath);
File path = Environment.getExternalStorageDirectory();
File dir = new File(path, "DreamGo/Image");
if(!dir.exists())
dir.mkdirs();
switch (requestCode)
{
case PHOTO_REQUEST_GALLERY:
if (data != null){
//file from gallery
File sourceFile = new File(getRealPathFromURI(data.getData()));
//blank file DreamGo/Image/uuid.jpg
File destFile = new File(dir.getAbsolutePath(), PHOTO_FILE_NAME);
Log.e("photo",data.getData().getPath());
try {
//copy file from gallery to DreamGo/Image/uuid.jpg
// otherwise crop method can't cut image without write permission
copyFile(sourceFile,destFile);
//Android N need use FileProvider to get file uri
Uri photoURI = FileProvider.getUriForFile(context, "dream.go.provider", destFile);
//cut image
crop(photoURI);
} catch (IOException e) {
e.printStackTrace();
}
}
break;
case PHOTO_REQUEST_CAMERA:
//whether sdcard is usable has been checked before use camera
File tempFile = new File(dir.getAbsolutePath(), PHOTO_FILE_NAME);
Uri photoURI = FileProvider.getUriForFile(context, "dream.go.provider", tempFile);
crop(photoURI);
break;
case PHOTO_REQUEST_CUT:
try {
if(data!=null) {
file = new File(dir.getAbsolutePath(), PHOTO_FILE_NAME);
icon.loadImage("file://" + file.getAbsolutePath());
}else {
showToast("a error happened when cut picture");
}
} catch (Exception e) {
e.printStackTrace();
}
break;
default:
break;
}
}
the realted code:
//copy sourceFile to destFile
public void copyFile(File sourceFile, File destFile) throws IOException {
if (!sourceFile.exists()) {
return;
}
FileChannel source = new FileInputStream(sourceFile).getChannel();
FileChannel destination = new FileOutputStream(destFile).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source, 0, source.size());
}
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
//file uri to real location in filesystem
public String getRealPathFromURI(Uri contentURI) {
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) {
// Source is Dropbox or other similar local file path
return contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}
public static final String getValue(Context context, String key) {
return getSharedPreference(context).getString(key, "");
}
public static final boolean putValue(Context context, String key,
String value) {
value = value == null ? "" : value;
SharedPreferences.Editor editor = getSharedPreference(context).edit();
editor.putString(key, value);
boolean result = editor.commit();
if (!result) {
return false;
}
return true;
}