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

时间:2022-03-09 23:10:03

In my app ,i have two buttons ,one for loading the image from gallery(from device )and another one for taking pictures by accesing the camera of the device,My code is working properly on some devices ,bt in some devices ,the app crashes when clicking an image in the gallery.Can anybody help me to find out the actual propblem??

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

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);
        }
    });
}

And the xml is

而xml是

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

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

</RelativeLayout>

2 个解决方案

#1


0  

I'm not sure but... maybe on some device this "EXTERNAL_CONTENT_URI" doesn't work because there's no external storage?

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

#2


0  

This is issue in Lollypop+ devices so we have to write 2 logic to process LoolyPop below & above android versions to process the gallery Image.

这是Lollypop +设备中的问题,因此我们必须编写2个逻辑来处理Android版本下方及以上的LoolyPop以处理图库Image。

Starting Gallery Image Picker Intent,

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

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

Process the Image,

处理图像,

  • Method to receive Image Path :

    接收图像路径的方法:

    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;}
    }
    
  • Received Gallery picker intent Processing :

    收到的图库选择器意图处理:

        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();
        }
        }       
    

    - Note: Please make sure to add below class in your package. It has been copied from the Lollypop open source code.

    - 注意:请确保在您的包装中添加以下课程。它已经从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());
    }
    }
    

#1


0  

I'm not sure but... maybe on some device this "EXTERNAL_CONTENT_URI" doesn't work because there's no external storage?

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

#2


0  

This is issue in Lollypop+ devices so we have to write 2 logic to process LoolyPop below & above android versions to process the gallery Image.

这是Lollypop +设备中的问题,因此我们必须编写2个逻辑来处理Android版本下方及以上的LoolyPop以处理图库Image。

Starting Gallery Image Picker Intent,

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

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

Process the Image,

处理图像,

  • Method to receive Image Path :

    接收图像路径的方法:

    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;}
    }
    
  • Received Gallery picker intent Processing :

    收到的图库选择器意图处理:

        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();
        }
        }       
    

    - Note: Please make sure to add below class in your package. It has been copied from the Lollypop open source code.

    - 注意:请确保在您的包装中添加以下课程。它已经从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());
    }
    }