android4.4.4 獲取系統相冊圖片出錯的問題(二)

呵呵,今天很高興,因爲自己正式步入準爸爸階段了!特此記錄下!
好吧,今天,我接着上次的問題講解,如何從android4.4以上系統進行選圖而避免報錯,而

android4.4.4 獲取系統相冊圖片出錯的問題(一)
中介紹的那種方式,其實在性能方面的話,還是一般,因爲每次讀取一張圖片,它都要在本地生成一張,造成存儲空間的浪費。今天介紹的這種方法,是根據網上的不同的資料進行的整理。

第一步:也就是我們調轉到我們的系統相冊進行圖片的選擇

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);// ACTION_OPEN_DOCUMENT
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("image/jpeg");
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {/**4.4系統以上**/
                startActivityForResult(intent, SELECT_PIC_KITKAT);
            } else {
                startActivityForResult(intent, SELECT_PIC);
            }

第二步自然就是在onActivityResult中進行處理

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
        case SELECT_PIC_KITKAT:
            if (resultCode != Activity.RESULT_OK) {
                return;
            }
            String path = "";
            if (DocumentsContract.isDocumentUri(MainActivity.this,
                    data.getData())) {
//              path = selectImage(MainActivity.this, data);
                 path = getPath(data);
            } else {
                path = getPath(MainActivity.this, data);
            }
            Message msg = new Message();
            msg.obj = path;
            handler.sendMessage(msg);
            break;
        case SELECT_PIC:
            if (resultCode != Activity.RESULT_OK) {
                return;
            }
            Message msg1 = new Message();
            msg1.obj = getPath(data);
            handler.sendMessage(msg1);
            break;
        }
    }

好,關鍵代碼來了,如下:

public static String getPath(final Context context, Intent data) {
        Uri uri = data.getData();
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            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];
                }
                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

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

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            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);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }

/**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context
     *            The context.
     * @param uri
     *            The Uri to query.
     * @param selection
     *            (Optional) Filter used in the query.
     * @param selectionArgs
     *            (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri,
            String selection, String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = { column };

        try {
            cursor = context.getContentResolver().query(uri, projection,
                    selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri
                .getAuthority());
    }

    /**
     * @param uri
     *            The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri
                .getAuthority());
    }

現在就是通過handler進行本地的顯示:

private Handler handler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(android.os.Message msg) {
            String path = (String) msg.obj;
            // Bitmap myBitmap = getLoacalBitmap(path);
            Bitmap bitmap = LocalImageCompression.comp(path);
            img.setImageBitmap(bitmap);
        };
    };

其中用到了一個通過本地路徑進行圖片的處理,主要是相冊圖片的size太大了,顯示不了,

/**
     * @方法說明:圖片按比例大小壓縮方法(根據路徑獲取圖片並壓縮)
     * @方法名稱:getimage
     * @param srcPath
     * @return
     * @返回值:Bitmap
     */
    public static Bitmap comp(String srcPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        /** 開始讀入圖片,此時把options.inJustDecodeBounds 設回true了**/
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);/** 此時返回bm爲空**/

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        /** 現在主流手機比較多是800*480分辨率,所以高和寬我們設置爲**/
        float hh = 800f;/** 這裏設置高度爲800f**/
        float ww = 480f;/** 這裏設置寬度爲480f**/
        /** 縮放比。由於是固定比例縮放,只用高或者寬其中一個數據進行計算即可**/
        int be = 1;/** be=1表示不縮放**/
        if (w > h && w > ww) {/** 如果寬度大的話根據寬度固定大小縮放**/
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {/** 如果高度高的話根據寬度固定大小縮放**/
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;/** 設置縮放比例**/
        /** 重新讀入圖片,注意此時已經把options.inJustDecodeBounds 設回false了**/
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        return compressImage(bitmap);/** 壓縮好比例大小後再進行質量壓縮**/
    }

源碼地址:http://yunpan.cn/cJ8WZm9NsnvuX (提取碼:3719)

發佈了42 篇原創文章 · 獲贊 3 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章