从图库加载图像时应用程序崩溃

Posted

技术标签:

【中文标题】从图库加载图像时应用程序崩溃【英文标题】:App crashes when loading image from gallery 【发布时间】:2015-05-28 12:14:44 【问题描述】:

在我的应用程序中,我有两个按钮,一个用于从画廊(从设备)加载图像,另一个用于通过访问设备的相机拍照,我的代码在某些设备上正常工作,bt 在某些设备上,单击图库中的图像时应用程序崩溃。有人可以帮我找出实际的问题吗??

public class MainActivity extends ActionBarActivity 
private static int RESULT_LOAD_IMAGE = 1;
private static final int CAMERA_REQUEST = 1888;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);
    buttonLoadImage.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View arg0) 

            Intent i = new Intent(
                    Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

            startActivityForResult(i, RESULT_LOAD_IMAGE);
        
    );
    this.imageView = (ImageView)this.findViewById(R.id.imgView);
    Button photoButton = (Button) this.findViewById(R.id.button2);
    photoButton.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View v) 
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);
        
    );

而xml是

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_ android:layout_>
<ImageView android:id="@+id/imgView"
    android:layout_
    android:layout_
    android:layout_weight="1"></ImageView>
<RelativeLayout
    android:id="@+id/relativeLayout1"
    android:layout_
    android:layout_
    android:background="@android:color/black" >
<Button android:id="@+id/buttonLoadPicture"
    android:layout_
    android:layout_

    android:layout_weight="0"
    android:text="Load Picture"
    android:layout_gravity="center"></Button>
    <Button
        android:id="@+id/button2"
        android:layout_
        android:layout_
        android:text="Take Picture"
        android:layout_alignParentRight="true"/>

</RelativeLayout>

【问题讨论】:

您应该为异常提供堆栈跟踪。布局代码也没有帮助。 你添加了 android.permission.READ_EXTERNAL_STORAGE 吗? 【参考方案1】:

我不确定,但是......也许在某些设备上,这个“EXTERNAL_CONTENT_URI”不起作用,因为没有外部存储?

【讨论】:

【参考方案2】:

这是 Lollypop+ 设备中的问题,因此我们必须编写 2 个逻辑来处理低于和高于 android 版本的 LoolyPop 以处理图库图像。

启动图库图像选择器意图,

Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        mContext.startActivityForResult(
                Intent.createChooser(intent, "Complete action using"),
                DigitalCareContants.IMAGE_PICK);

处理图像,

获取图片路径的方法:

private static String getPath(final Context context, final Uri uri) 

final boolean isKitKat = Build.VERSION.SDK_INT >= 19;


if (isKitKat && DocumentsContract.isDocumentUri(uri)) 

    if (isExternalStorageDocument(uri)) 
        final String docId = DocumentsContract.getDocumentId(uri);
        final String[] split = docId.split(":");
        final String type = split[0];

        if ("primary".equalsIgnoreCase(type)) 
            return Environment.getExternalStorageDirectory() + "/"
                    + split[1];
        
    

    else if (isDownloadsDocument(uri)) 

        final String id = DocumentsContract.getDocumentId(uri);
        long mId = Long.parseLong(id);
        Uri mUri = Uri.parse("content://downloads/public_downloads");
        final Uri contentUri = ContentUris.withAppendedId(mUri, mId);

        return getDataColumn(context, contentUri, null, null);
    

    else if (isMediaDocument(uri)) 
        final String docId = DocumentsContract.getDocumentId(uri);
        final String[] split = docId.split(":");
        final String type = split[0];

        Uri contentUri = null;
        if ("image".equals(type)) 
            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
         else if ("video".equals(type)) 
            contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
         else if ("audio".equals(type)) 
            contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        

        final String selection = "_id=?";
        final String[] selectionArgs = new String[]  split[1] ;

        return getDataColumn(context, contentUri, selection,
                selectionArgs);
    


else if ("content".equalsIgnoreCase(uri.getScheme())) 
    return getDataColumn(context, uri, null, null);


else if ("file".equalsIgnoreCase(uri.getScheme())) 
    return uri.getPath();


return null;

收到画廊选择器意图处理:

    if(requestcode == 1000)
    
    String[] filePathColumn =  MediaStore.Images.Media.DATA ;
    Uri selectedImage = data.getData();

    if (Build.VERSION.SDK_INT >= 19) 
        InputStream input;
        Bitmap bitmap;
        String picturePath = getPath(mActivity, selectedImage);
        try 
            input = mActivity.getContentResolver().openInputStream(
                    selectedImage);
            bitmap = BitmapFactory.decodeStream(input);
            Log.d("IMAGE", "Received Image Bitmap : " + bitmap);
            Log.d("IMAGE", "Received Image Bitmap Path : " + picturePath);
         catch (FileNotFoundException e1) 

        
     else 
        Log.d(TAG, "Android Version is 18 below");
        Cursor cursor = mActivity.getContentResolver().query(
                selectedImage, filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        Log.d("IMAGE", "Received Image Bitmap Path : " + picturePath);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Bitmap bitmap = BitmapFactory.decodeFile(picturePath, options);
        Log.d("IMAGE", "Received Image Bitmap : " + bitmap);
        Log.d("IMAGE", "Received Image Bitmap Path : " + picturePath);
        cursor.close();
    
           

- 注意:请确保在您的包中添加以下类。它是从 Lollypop 开源代码中复制而来的。

  public class DocumentsContract 
  private static final String DOCUMENT_URIS =
"com.android.providers.media.documents " +
"com.android.externalstorage.documents " +
"com.android.providers.downloads.documents " +
"com.android.providers.media.documents";

private static final String PATH_DOCUMENT = "document";
private static final String TAG = DocumentsContract.class.getSimpleName();

public static String getDocumentId(Uri documentUri) 
final List<String> paths = documentUri.getPathSegments();
if (paths.size() < 2) 
    throw new IllegalArgumentException("Not a document: " + documentUri);


if (!PATH_DOCUMENT.equals(paths.get(0))) 
    throw new IllegalArgumentException("Not a document: " + documentUri);

return paths.get(1);


public static boolean isDocumentUri(Uri uri) 
final List<String> paths = uri.getPathSegments();
Log.d(TAG, "paths[" + paths + "]");
if (paths.size() < 2) 
    return false;

if (!PATH_DOCUMENT.equals(paths.get(0))) 
    return false;

return DOCUMENT_URIS.contains(uri.getAuthority());


【讨论】:

以上是关于从图库加载图像时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

将图像从图库上传到 Firebase 存储时应用程序崩溃

从相机中选择图像时无法交付结果,但从图库中选择图像时没有问题

从图库中裁剪的 android-image 无法正常工作

从相机/图库加载图像位图时会旋转 [Android 9]

应用程序在图像捕获中崩溃

从 Assets.xcassets 加载图像时 iOS 应用程序崩溃