在我的应用程序中,提供了通过相机拍摄照片并将其发送到裁剪但是当相机应用程序打开并显示已发送的图像并且用户裁剪并单击确定时,相机应用程序将显示一个Toast,
“无法保存裁剪的图像”
以下是我为它编写的代码:
public static void sendImageForCrop(final Activity activity, final Uri mImageCaptureUri){
final ArrayList<CropOption> cropOptions = new ArrayList<>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = activity.getPackageManager().queryIntentActivities(
intent, 0);
int size = list.size();
if (size == 0) {
Toast.makeText(activity, "Can not find image crop app",
Toast.LENGTH_SHORT).show();
} else {
//intent.setData(mImageCaptureUri);
intent.setDataAndType(mImageCaptureUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
try{
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File.createTempFile("temp", null, activity.getCacheDir())));
}catch(IOException ioe){
// It is unfortunate that the Photo can't be cropped.
// Show a Toast for this.
Toast.makeText(activity, "The photo couldn't be saved :(. Try clearing the App data.", Toast.LENGTH_SHORT).show();
return;
}
activity.startActivityForResult(i, CROP_FROM_CAMERA);
}
}
这是Intent对象的toString()
:
Intent { act=com.android.camera.action.CROP dat=file:///storage/emulated/0/Snap_1508218098533.jpg typ=image/* flg=0x2 (has extras) }
这可能是什么问题?
编辑:根据要求,这是清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.example"
android:versionCode="156"
android:versionName="1.2.54">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>
<uses-sdk tools:overrideLibrary="com.braintreepayments.api.core,com.android.volley,com.paypal.android.sdk.onetouch.core,com.braintreepayments.api" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.location.network"
android:required="false" />
<uses-feature
android:name="android.hardware.location"
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<uses-feature
android:name="android.hardware.microphone"
android:required="false" />
<!-- Tell the system this app requires OpenGL ES 2.0. -->
<uses-feature
android:glEsVersion="0x00015000"
android:required="true" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<application
android:name="com.example.example.UILApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@drawable/applicationlogo"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/Theme.MyTheme">
<!-- List of Activities here -->
<provider
android:name=".provider.GenericFileProvider"
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>
答案 0 :(得分:0)
我有同样的问题,但我通过更改保存的图像目录的路径修复如下 - :
File croppedImageDirectory = new File(Environment.getExternalStorageDirectory()+"/croppedImage");
或者,请参阅此答案可能会对您有所帮助 - stackoverflow.com/a/1976115
可以帮到你
答案 1 :(得分:0)
我认为问题可能在于您尝试保存的路径,
尝试使用如下
public void choosePhoto(View view) {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", int_Width_crop);
intent.putExtra("outputY", int_Height_crop);
intent.putExtra("scale", false);
intent.putExtra("return-data", true);
File photo = new File(Environment.getExternalStorageDirectory(), "cropped_image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, CHOOSE_PICTURE);
}
答案 2 :(得分:0)
我知道这对你们很多人来说都是一种被认为是黑客攻击的方法,但它确实有效!
intent.putExtra(MediaStore.EXTRA_OUTPUT, (String)null);
<强>推理强>
好吧,我查看了MarshMallow中的source图库应用程序(作物失败的地方之一;其他是照片应用程序)并找到了处理CROP请求的此方法:
private void saveOutput(Bitmap croppedImage) {
if (mSaveUri != null) {
OutputStream outputStream = null;
try {
outputStream = mContentResolver.openOutputStream(mSaveUri);
if (outputStream != null) {
croppedImage.compress(mOutputFormat, 75, outputStream);
}
} catch (IOException ex) {
// TODO: report error to caller
Log.e(TAG, "Cannot open file: " + mSaveUri, ex);
} finally {
Util.closeSilently(outputStream);
}
Bundle extras = new Bundle();
setResult(RESULT_OK, new Intent(mSaveUri.toString())
.putExtras(extras));
} else if (mSetWallpaper) {
try {
WallpaperManager.getInstance(this).setBitmap(croppedImage);
setResult(RESULT_OK);
} catch (IOException e) {
Log.e(TAG, "Failed to set wallpaper.", e);
setResult(RESULT_CANCELED);
}
} else {
Bundle extras = new Bundle();
extras.putString("rect", mCrop.getCropRect().toString());
File oldPath = new File(mImage.getDataPath());
File directory = new File(oldPath.getParent());
int x = 0;
String fileName = oldPath.getName();
fileName = fileName.substring(0, fileName.lastIndexOf("."));
// Try file-1.jpg, file-2.jpg, ... until we find a filename which
// does not exist yet.
while (true) {
x += 1;
String candidate = directory.toString()
+ "/" + fileName + "-" + x + ".jpg";
boolean exists = (new File(candidate)).exists();
if (!exists) {
break;
}
}
try {
int[] degree = new int[1];
Uri newUri = ImageManager.addImage(
mContentResolver,
mImage.getTitle(),
mImage.getDateTaken(),
null, // TODO this null is going to cause us to lose
// the location (gps).
directory.toString(), fileName + "-" + x + ".jpg",
croppedImage, null,
degree);
setResult(RESULT_OK, new Intent()
.setAction(newUri.toString())
.putExtras(extras));
} catch (Exception ex) {
// basically ignore this or put up
// some ui saying we failed
Log.e(TAG, "store image fail, continue anyway", ex);
}
}
final Bitmap b = croppedImage;
mHandler.post(new Runnable() {
public void run() {
mImageView.clear();
b.recycle();
}
});
finish();
}
您会看到声明if (mSaveUri != null) {
。它处理我们提供null Uri的情况。假设第三方应用程序可能会处理我们提供null Uri的情况。
现在,我用几个应用程序对它进行了测试,但它确实有效。但绝不是这个解决方案是理想的解决方案。