Android 从相册获取图片 - 在某些设备上出错
Android getting pictures from photo's gallery - error on some devices
我的应用程序有一个功能,可以打开照片库和 select 图像以在 ImageView 中显示。奇怪的是,在我的三星 Galaxy S5 上,代码可以完美运行,但是当我在 ASUS Zenphone 或摩托罗拉 Moto X 上尝试时,代码就无法运行并且应用程序崩溃。
所有设备都具有相同的 Android 版本 (5.0)
这是我的代码示例:
打算打开相册:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMG_SDCARD);
Activity 结果:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
File file = null;
if(data != null && requestCode == IMG_SDCARD && resultCode == getActivity().RESULT_OK){
Uri img = data.getData();
String[] cols = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(img, cols, null, null, null);
cursor.moveToFirst();
int indexCol = cursor.getColumnIndex(cols[0]);
String imgString = cursor.getString(indexCol);
cursor.close();
file = new File(imgString);
if(file != null){
wd.getImage().setResizedBitmap(file, 1200, 700);
wd.getImage().setMimeFromImgPath(file.getPath());
}
}
if(wd.getImage().getBitmap() != null){
imageView.setImageBitmap(wd.getImage().getBitmap());
}
}
你们见过这样的东西吗?
在不同设备之间从相册中获取图像可能存在差异?
编辑
这是日志错误:
01-21 10:34:01.066 30243-30243/com.inthecheesefactory.lab.designlibrary E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.inthecheesefactory.lab.designlibrary, PID: 30243
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65539, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/image:4904 flg=0x1 }} to activity {com.inthecheesefactory.lab.designlibrary/br.com.amais.viumeupet.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:3559)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3602)
at android.app.ActivityThread.access00(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1334)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5289)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
at java.io.File.fixSlashes(File.java:179)
at java.io.File.<init>(File.java:128)
at br.com.amais.viumeupet.Fragment1.onActivityResult(Fragment1.java:285)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:153)
at br.com.amais.viumeupet.MainActivity.onActivityResult(MainActivity.java:231)
at android.app.Activity.dispatchActivityResult(Activity.java:6220)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3555)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3602)
at android.app.ActivityThread.access00(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1334)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5289)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
没有要求 ACTION_GET_CONTENT
return 给你一个来自 MediaStore
的 Uri
。即使是这样,也没有要求您的代码会为您提供您具有读取权限的文件的路径。在你的例子中,imgString
是 null
,这并不奇怪。
相反,摆脱所有这些(包括 wd
是什么)并使用 image-loading library, like Picasso,它可以将 Uri
带到图像并处理所有加载并为您调整大小(在后台线程上)并更新您的 ImageView
.
如果您坚持自己这样做,请创建一个后台线程,然后使用 ContentResolver
和 openInputStream()
和 getType()
等方法,以及 BitmapFactory
。
public static final int GALLERY_INTENT_REQUEST_CODE = 0x000005;
要打开图库并获取所选图像的路径,请使用以下代码:
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
mActPanelFragment.startActivityForResult(photoPickerIntent, ActivityConstantUtils.GALLERY_INTENT_REQUEST_CODE);
之后在 onActivityResult() 方法中获取路径
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
(requestCode == ActivityConstantUtils.GALLERY_INTENT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
try {
String imagePath = getFilePath(data);
// TODO: Here you set data to preview screen
}catch(Exception e){}
}
}
private String getFilePath(Intent data) {
String imagePath;
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imagePath = cursor.getString(columnIndex);
cursor.close();
return imagePath;
}
我的应用程序有一个功能,可以打开照片库和 select 图像以在 ImageView 中显示。奇怪的是,在我的三星 Galaxy S5 上,代码可以完美运行,但是当我在 ASUS Zenphone 或摩托罗拉 Moto X 上尝试时,代码就无法运行并且应用程序崩溃。
所有设备都具有相同的 Android 版本 (5.0)
这是我的代码示例:
打算打开相册:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMG_SDCARD);
Activity 结果:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
File file = null;
if(data != null && requestCode == IMG_SDCARD && resultCode == getActivity().RESULT_OK){
Uri img = data.getData();
String[] cols = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(img, cols, null, null, null);
cursor.moveToFirst();
int indexCol = cursor.getColumnIndex(cols[0]);
String imgString = cursor.getString(indexCol);
cursor.close();
file = new File(imgString);
if(file != null){
wd.getImage().setResizedBitmap(file, 1200, 700);
wd.getImage().setMimeFromImgPath(file.getPath());
}
}
if(wd.getImage().getBitmap() != null){
imageView.setImageBitmap(wd.getImage().getBitmap());
}
}
你们见过这样的东西吗?
在不同设备之间从相册中获取图像可能存在差异?
编辑
这是日志错误:
01-21 10:34:01.066 30243-30243/com.inthecheesefactory.lab.designlibrary E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.inthecheesefactory.lab.designlibrary, PID: 30243
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65539, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/image:4904 flg=0x1 }} to activity {com.inthecheesefactory.lab.designlibrary/br.com.amais.viumeupet.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:3559)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3602)
at android.app.ActivityThread.access00(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1334)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5289)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
at java.io.File.fixSlashes(File.java:179)
at java.io.File.<init>(File.java:128)
at br.com.amais.viumeupet.Fragment1.onActivityResult(Fragment1.java:285)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:153)
at br.com.amais.viumeupet.MainActivity.onActivityResult(MainActivity.java:231)
at android.app.Activity.dispatchActivityResult(Activity.java:6220)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3555)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3602)
at android.app.ActivityThread.access00(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1334)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5289)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
没有要求 ACTION_GET_CONTENT
return 给你一个来自 MediaStore
的 Uri
。即使是这样,也没有要求您的代码会为您提供您具有读取权限的文件的路径。在你的例子中,imgString
是 null
,这并不奇怪。
相反,摆脱所有这些(包括 wd
是什么)并使用 image-loading library, like Picasso,它可以将 Uri
带到图像并处理所有加载并为您调整大小(在后台线程上)并更新您的 ImageView
.
如果您坚持自己这样做,请创建一个后台线程,然后使用 ContentResolver
和 openInputStream()
和 getType()
等方法,以及 BitmapFactory
。
public static final int GALLERY_INTENT_REQUEST_CODE = 0x000005;
要打开图库并获取所选图像的路径,请使用以下代码:
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
mActPanelFragment.startActivityForResult(photoPickerIntent, ActivityConstantUtils.GALLERY_INTENT_REQUEST_CODE);
之后在 onActivityResult() 方法中获取路径
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
(requestCode == ActivityConstantUtils.GALLERY_INTENT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
try {
String imagePath = getFilePath(data);
// TODO: Here you set data to preview screen
}catch(Exception e){}
}
}
private String getFilePath(Intent data) {
String imagePath;
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imagePath = cursor.getString(columnIndex);
cursor.close();
return imagePath;
}