先说说权限问题:
【android】getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()的作用
getCacheDir()方法用于获取/data/data//cache目录
getFilesDir()方法用于获取/data/data//files目录
通过Context.getExternalFilesDir()方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据
通过Context.getExternalCacheDir()方法可以获取到 SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
可见这两个是一样的,不过一个在内存储中,一个在外存储中(以上目录都是完全可读可写的)
但是有时候我们需要保存下载文件就会存储到其它目录
使用Environment.getExternalStorageDirectory() 获取扩展卡目录并自行处理。
但是在Android4.4的时候,把这个权限加了限制,不能再写了。幸好 5.0 的时候,又回来了,又可以使用扩展卡了
--------------------------------------------------------------------------------------------
那么看看我的问题:
设置自定义背景,选中一张图片,裁剪,保存,保存路径是扩展卡的自定义路径,在4.4以下没有问题,4.4以上不可以。
后来,我加了判断
if (FileUtil.isExternalStorageWritable()) {
backgroundFilePath = Environment.getExternalStorageDirectory().getPath() + "/weiwo/";
} else {
backgroundFilePath = context.getFilesDir().getParent() + "/weiwo/";
}
但是还是不行。
经过今天晚上的调试,及对整个应用权限的思考,发现问题并不出在上面的代码。
先看看裁剪代码
/**
* 调用android系统自带的图片裁剪,把用户选择的图片 裁剪成适合用户手机的大小
*
* @param imagePath
*/
public void startPhotoZoom(int resultCode, Intent data) {
View v = listMyBackground.get(0);
if (resultCode == Activity.RESULT_OK) {
// 获得裁剪图片的uri
Uri uri = data.getData();
// 调用intent跳转的裁间页面
Intent intent = new Intent("com.android.camera.action.CROP");
// 传入裁剪图片的路径uri和需要裁剪的格式
intent.setDataAndType(uri, "image/*");
// 可裁剪状态
intent.putExtra("crop", true);
intent.putExtra("scale", true);
/** 此保存会导致小图放大(但是不是图片放大,是画面放大,图片在中间,没有放大) **/
// intent.putExtra("outputX", v.getWidth());
// intent.putExtra("outputY", v.getHeight());
intent.putExtra("aspectX", v.getWidth());
intent.putExtra("aspectY", v.getHeight());
intent.putExtra("return-data", false);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
/** 不用file,直接使用路径,不行 **/
File file = new File(getBackgroundFilename());
Uri uri1 = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri1);
startActivityForResult(intent, 5);
}
}
这里有两个参数是需要注意的
intent.putExtra("return-data", false);
return-data=false 即裁剪后不返回图片。如果为true则返回,返回后可通过 Bitmap bitmap = data.getParcelableExtra("data"); 获取返回值
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri1);
MediaStore.EXTRA_OUTPUT 参数为一个Uri,此参数会让裁剪的应用(调用系统裁剪应用或者第三方)自行保存裁剪后的图片到uri路径。
那么问题就在这里。
Android4.4不能使用扩展卡,所以判断以后 使用了应用自己的目录,而不是扩展卡目录。这样就是让第三方的裁剪应用把图片保存到自己的APP目录下,这显然是不可能的,可以通过一些文件管理应用查看权限,这个目录只有应用本身才可以读写的,其它应用没有读写权限。所以保存失败了。
这样一来,扩展卡不能保存,第三方又不能跨APP保存,所以失败了。
修改方法:
使用返回数据,而不是让裁剪应用保存裁剪后的图片,即:
intent.putExtra("return-data", true);
startActivityForResult(intent, 5);
在返回处理中使用
Bitmap bitmap = data.getParcelableExtra("data");
获取返回的裁剪图片,然后再自己保存到自己的应用目录(比如:getFilesDir())下就可以。
这样就没有问题了。
好纠结,做为一个后端开发工程师,闲暇时光自己开发Android应用,没有太多时间去处理这些事情,拖了这么久,终于解决了,可以安心睡觉了~