Nhận / chọn một hình ảnh từ ứng dụng Thư viện tích hợp sẵn của Android theo chương trình


271

Tôi đang cố gắng mở một hình ảnh / hình ảnh trong ứng dụng có sẵn trong Thư viện từ bên trong ứng dụng của mình.

Tôi có một URI của hình ảnh (hình ảnh nằm trên thẻ SD).

Bạn có đề nghị nào không?


Tôi đã cập nhật câu trả lời của mình để cung cấp thêm mã kiểm tra để đảm bảo rằng bạn truy xuất kết quả chính xác.
Anthony Forloney

nhìn vào câu trả lời của tôi, nó là một bản cập nhật cho mã của hcpl và nó cũng hoạt động cho trình quản lý tệp astro và trình quản lý tệp oi.
điên

15
Ai đó nên cập nhật câu hỏi, "Nhận / chọn một hình ảnh từ Android ...". Câu hỏi hiện tại diễn giải rằng tôi có hình ảnh và tôi muốn hiển thị nó thông qua ứng dụng thư viện mặc định.
Vikas

@Vikas, có vẻ như bạn đúng. Tôi không nhớ chính xác những gì tôi đã cố gắng thực hiện hơn một năm trước và tại sao tất cả các câu trả lời (bao gồm cả câu trả lời mà tôi đã chọn làm giải pháp) thực sự trả lời cho một câu hỏi khác ...
Michael Kessler

Thật ra, tôi không biết có đúng không khi thay đổi hoàn toàn câu hỏi. Có 36 người đã thêm câu hỏi vào mục yêu thích của họ ...
Michael Kessler

Câu trả lời:


351

Đây là một giải pháp hoàn chỉnh. Tôi vừa cập nhật mã ví dụ này với thông tin được cung cấp trong câu trả lời dưới đây của @mad. Ngoài ra, hãy kiểm tra giải pháp bên dưới từ @Khobaib giải thích cách xử lý ảnh picasa.

Cập nhật

Tôi vừa xem lại câu trả lời ban đầu của mình và tạo một dự án Android Studio đơn giản, bạn có thể kiểm tra từ github và nhập trực tiếp trên hệ thống của mình.

https://github.com/hanscappelle/SO-2169649

(lưu ý rằng nhiều lựa chọn tập tin vẫn cần làm việc)

Lựa chọn hình ảnh duy nhất

Với sự hỗ trợ cho hình ảnh từ các nhà thám hiểm tập tin nhờ người dùng điên.

public class BrowsePictureActivity extends Activity {

    // this is the action code we use in our intent, 
    // this way we know we're looking at the response from our own action
    private static final int SELECT_PICTURE = 1;

    private String selectedImagePath;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViewById(R.id.Button01)
                .setOnClickListener(new OnClickListener() {

                    public void onClick(View arg0) {

                        // in onCreate or any event where your want the user to
                        // select a file
                        Intent intent = new Intent();
                        intent.setType("image/*");
                        intent.setAction(Intent.ACTION_GET_CONTENT);
                        startActivityForResult(Intent.createChooser(intent,
                                "Select Picture"), SELECT_PICTURE);
                    }
                });
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
            }
        }
    }

    /**
     * helper to retrieve the path of an image URI
     */
    public String getPath(Uri uri) {
            // just some safety built in 
            if( uri == null ) {
                // TODO perform some logging or show user feedback
                return null;
            }
            // try to retrieve the image from the media store first
            // this will only work for images selected from gallery
            String[] projection = { MediaStore.Images.Media.DATA };
            Cursor cursor = managedQuery(uri, projection, null, null, null);
            if( cursor != null ){
                int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                String path = cursor.getString(column_index);
                cursor.close();
                return path;
            }
            // this is our fallback here
            return uri.getPath();
    }

}

Chọn nhiều ảnh

Vì ai đó đã yêu cầu thông tin đó trong một bình luận và tốt hơn là nên thu thập thông tin.

Đặt một tham số bổ sung EXTRA_ALLOW_MULTIPLEcho ý định:

intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);

Và trong kiểm tra xử lý kết quả cho tham số đó:

if (Intent.ACTION_SEND_MULTIPLE.equals(data.getAction()))
        && Intent.hasExtra(Intent.EXTRA_STREAM)) {
    // retrieve a collection of selected images
    ArrayList<Parcelable> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    // iterate over these images
    if( list != null ) {
       for (Parcelable parcel : list) {
         Uri uri = (Uri) parcel;
         // TODO handle the images one by one here
       }
   }
} 

Lưu ý rằng điều này chỉ được hỗ trợ bởi API cấp 18+.


Nó không hoạt động khi tôi sử dụng trình quản lý tập tin Astro. Bất cứ ý tưởng tại sao?
Rohith Nandakumar

@hcpl Cảm ơn bạn đã trả lời. Bạn có thể vui lòng cho tôi biết làm thế nào để có được nhiều hình ảnh ...?
Noby

28
Chụp một bức ảnh dường như không còn hoạt động trên phiên bản Android 4.4 mới nhất (KitKat) nữa. Cột _data từ truy vấn trả về giá trị null.
Christopher Masser

1
@hcpl Bạn không có nghĩa là 'Intent.hasExtra', ý bạn là 'data.hasExtra' - giả sử dữ liệu là tham số Ý định của bạn trong onActivityResult ().
IgorGanapolsky 27/12/13

2
Mã này đang hoạt động hoàn hảo preKitkat, nhưng từ đó có các nhà cung cấp tài liệu. Trong câu trả lời của tôi, tôi viết về những việc cần làm trong kitkat.
abbath

135

Đây là một bản cập nhật cho mã tốt mà hcpl đã đăng. nhưng điều này hoạt động với trình quản lý tệp OI, trình quản lý tệp astro VÀ bộ sưu tập phương tiện (đã được kiểm tra). vì vậy tôi đoán nó sẽ hoạt động với mọi trình quản lý tập tin (có nhiều người khác được đề cập không?). đã làm một số sửa chữa cho mã ông viết.

public class BrowsePicture extends Activity {

    //YOU CAN EDIT THIS TO WHATEVER YOU WANT
    private static final int SELECT_PICTURE = 1;

    private String selectedImagePath;
    //ADDED
    private String filemanagerstring;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ((Button) findViewById(R.id.Button01))
        .setOnClickListener(new OnClickListener() {

            public void onClick(View arg0) {

                // in onCreate or any event where your want the user to
                // select a file
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,
                        "Select Picture"), SELECT_PICTURE);
            }
        });
    }

    //UPDATED
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();

                //OI FILE Manager
                filemanagerstring = selectedImageUri.getPath();

                //MEDIA GALLERY
                selectedImagePath = getPath(selectedImageUri);

                //DEBUG PURPOSE - you can delete this if you want
                if(selectedImagePath!=null)
                    System.out.println(selectedImagePath);
                else System.out.println("selectedImagePath is null");
                if(filemanagerstring!=null)
                    System.out.println(filemanagerstring);
                else System.out.println("filemanagerstring is null");

                //NOW WE HAVE OUR WANTED STRING
                if(selectedImagePath!=null)
                    System.out.println("selectedImagePath is the right one for you!");
                else
                    System.out.println("filemanagerstring is the right one for you!");
            }
        }
    }

    //UPDATED!
    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        if(cursor!=null)
        {
            //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
            //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
            int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }
        else return null;
    }

1
Làm cách nào để truy xuất hình ảnh Bitmap từ đường dẫn OI?
Vikas

2
nhìn vào mã tại các dòng với nhận xét // NGAY BÂY GIỜ CHÚNG TÔI CÓ MONG MUỐN CỦA CHÚNG TÔI ... đây là tất cả những gì bạn cần. sau đó sử dụng lớp BitmapFactory để lấy bitmap từ một đường dẫn
tức là

Cảm ơn! Bạn có một điểm tốt, không bao giờ thử các trình quản lý tệp khác :).
hcpl

2
Tôi cũng muốn đóng con trỏ :)
pssandstrom

7
Cũng có thể thay đổi else return null;trong getPath(Uri uri)để return uri.getPath();và thoát khỏi những người đầu tiên filemanagerstring = selectedImageUri.getPath();kiểm tra. Bằng cách này, bạn chỉ cần thực hiện một cuộc gọi đến getPath(Uri)và lấy lại đường dẫn (bất kể đó là Thư viện hoặc trình quản lý tệp đã được sử dụng).
ashughes

24

Các phương thức của hcpl hoạt động hoàn hảo trước KitKat, nhưng không hoạt động với API DocumentsProvider. Đối với điều đó, chỉ cần làm theo hướng dẫn chính thức của Android dành cho người cung cấp tài liệu: https://developer.android.com/guide/topics/providers/document-provider.html -> mở tài liệu, phần Bitmap.

Đơn giản là tôi đã sử dụng mã của hcpl và mở rộng nó: nếu tệp có đường dẫn được truy xuất đến hình ảnh ném ngoại lệ, tôi gọi hàm này:

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
        ParcelFileDescriptor parcelFileDescriptor =
             getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return image;
}

Đã thử nghiệm trên Nexus 5.


Câu trả lời thực sự hữu ích, nên được sử dụng để chọn ảnh từ ứng dụng "Ảnh".
Arun Badole

Tôi đã thử điều này trên cả tệp cục bộ và máy chủ, hoạt động cho cả hai.
Arun Badole

11

dựa trên mã trên, tôi đã phản ánh mã như dưới đây, có thể phù hợp hơn:

public String getPath(Uri uri) {
    String selectedImagePath;
    //1:MEDIA GALLERY --- query from MediaStore.Images.Media.DATA
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if(cursor != null){
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        selectedImagePath = cursor.getString(column_index);
    }else{
        selectedImagePath = null;
    }

    if(selectedImagePath == null){
        //2:OI FILE Manager --- call method: uri.getPath()
        selectedImagePath = uri.getPath();
    }
    return selectedImagePath;
}

11

Tôi đã đi qua giải pháp từ @hcpl & @mad. Giải pháp của hcpl hỗ trợ tốt cho hình ảnh cục bộ trong thư viện & mad đã cung cấp một giải pháp tốt hơn trên đó - nó cũng giúp tải hình ảnh OI / Astro / Dropbox. Nhưng trong ứng dụng của tôi, khi làm việc trên thư viện picasa hiện được tích hợp trong Thư viện Android, cả hai giải pháp đều thất bại.

Tôi đã tìm kiếm và phân tích một chút và cuối cùng đã đưa ra một giải pháp tốt hơn và thanh lịch khắc phục hạn chế này. Cảm ơn Dimitar Darazhanski cho blog của anh ấy, điều đó đã giúp tôi trong trường hợp này, tôi đã sửa đổi một chút để dễ hiểu hơn. Đây là giải pháp của tôi đi -

public class BrowsePicture extends Activity {

//YOU CAN EDIT THIS TO WHATEVER YOU WANT
private static final int SELECT_PICTURE = 1;

private String selectedImagePath;
//ADDED
private String filemanagerstring;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ((Button) findViewById(R.id.Button01))
    .setOnClickListener(new OnClickListener() {

        public void onClick(View arg0) {

            // in onCreate or any event where your want the user to
            // select a file
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent,
                    "Select Picture"), SELECT_PICTURE);
        }
    });
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            Log.d("URI VAL", "selectedImageUri = " + selectedImageUri.toString());
            selectedImagePath = getPath(selectedImageUri);

            if(selectedImagePath!=null){         
                // IF LOCAL IMAGE, NO MATTER IF ITS DIRECTLY FROM GALLERY (EXCEPT PICASSA ALBUM),
                // OR OI/ASTRO FILE MANAGER. EVEN DROPBOX IS SUPPORTED BY THIS BECAUSE DROPBOX DOWNLOAD THE IMAGE 
                // IN THIS FORM - file:///storage/emulated/0/Android/data/com.dropbox.android/...
                System.out.println("local image"); 
            }
            else{
                System.out.println("picasa image!");
                loadPicasaImageFromGallery(selectedImageUri);
            }
        }
    }
}


// NEW METHOD FOR PICASA IMAGE LOAD
private void loadPicasaImageFromGallery(final Uri uri) {
    String[] projection = {  MediaColumns.DATA, MediaColumns.DISPLAY_NAME };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
    if(cursor != null) {
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(MediaColumns.DISPLAY_NAME);
        if (columnIndex != -1) {
            new Thread(new Runnable() {
                // NEW THREAD BECAUSE NETWORK REQUEST WILL BE MADE THAT WILL BE A LONG PROCESS & BLOCK UI
                // IF CALLED IN UI THREAD 
                public void run() {
                    try {
                        Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                        // THIS IS THE BITMAP IMAGE WE ARE LOOKING FOR.
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }).start();
        }
    }
    cursor.close();
}


public String getPath(Uri uri) {
    String[] projection = {  MediaColumns.DATA};
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
    if(cursor != null) {
        //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
        //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
        String filePath = cursor.getString(columnIndex);
        cursor.close();
        return filePath;
    }
    else 
        return uri.getPath();               // FOR OI/ASTRO/Dropbox etc
}

Kiểm tra nó và cho tôi biết nếu có một số vấn đề với nó. Tôi đã thử nghiệm nó và nó hoạt động tốt trong mọi trường hợp.

Hy vọng điều này sẽ giúp tất cả mọi người.


10

Giả sử bạn có một thư mục hình ảnh trong thư mục thẻ SD của bạn chỉ cho hình ảnh.

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// tells your intent to get the contents
// opens the URI for your image directory on your sdcard
intent.setType("file:///sdcard/image/*"); 
startActivityForResult(intent, 1);

Sau đó, bạn có thể quyết định những gì bạn muốn làm với nội dung trở lại trong hoạt động của bạn.

Đây là một ví dụ để lấy tên đường dẫn cho hình ảnh, hãy kiểm tra điều này với mã của bạn chỉ để đảm bảo bạn có thể xử lý các kết quả quay lại. Bạn có thể thay đổi mã khi cần thiết để phù hợp hơn với nhu cầu của bạn.

protected final void onActivityResult(final int requestCode, final int
                     resultCode, final Intent i) {
    super.onActivityResult(requestCode, resultCode, i);

  // this matches the request code in the above call
  if (requestCode == 1) {
      Uri _uri = i.getData();

    // this will be null if no image was selected...
    if (_uri != null) {
      // now we get the path to the image file
     cursor = getContentResolver().query(_uri, null,
                                      null, null, null);
     cursor.moveToFirst();
     String imageFilePath = cursor.getString(0);
     cursor.close();
     }
   }

Lời khuyên của tôi là cố gắng để lấy hình ảnh hoạt động chính xác, tôi nghĩ vấn đề là nội dung của việc truy cập hình ảnh trên sdcard. Hãy xem Hiển thị hình ảnh trên thẻ sd .

Nếu bạn có thể có được điều đó và chạy, có thể bằng ví dụ cung cấp một nhà cung cấp chính xác, bạn sẽ có thể tìm ra cách giải quyết cho mã của mình.

Giữ cho tôi cập nhật bằng cách cập nhật câu hỏi này với tiến trình của bạn. Chúc may mắn


@Anthony, cảm ơn bạn đã phản hồi. Thật không may, nó không làm việc cho tôi. Tôi nhận được lỗi tiếp theo: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.GET_CONTENT typ=file:///sdcard/images/* }
Michael Kessler

Bạn cần gọi startActivityforResultvà cung cấp một hoạt động. Đó là những gì tôi đã đề cập đến về việc quyết định điều gì tiếp theo, điều xấu của tôi.
Anthony Forloney

Nó vẫn không hoạt động ... Tôi kiểm tra xem thư mục có tồn tại không và có tệp hình ảnh bên trong thư mục không. Tôi gọi startActivityForResult(intent, 1);và vẫn gặp lỗi này ... Mã này nằm bên ngoài Hoạt động, nhưng tôi có một tham chiếu đến hoạt động và gọi startActivityForResultphương thức trên tham chiếu đó - có lẽ đây là lý do?
Michael Kessler

Không, không nên là lý do, đó là gì 1đi qua của bạn? Hãy thửIMAGE_PICK
Anthony Forloney

1
Thông số thứ hai chỉ là thứ gì đó đối với tôi, phải không? Đây chỉ là một int sẽ được trả lại cho tôi cùng với kết quả. Đã thử cũng Intent.ACTION_PICKthay Intent.ACTION_GET_CONTENT. Bạn có ý nghĩa IMAGE_PICKgì? Không có một hằng số như vậy. Tôi cũng đã thử intent.setData(Uri.fromFile(new File("/sdcard/image/")));. Tôi đã thử tất cả các kết hợp có thể có của những thứ này và dường như không có gì hoạt động ...
Michael Kessler

10

đây là bài đánh giá của tôi về chủ đề này, thu thập tất cả thông tin ở đây, cộng với các câu hỏi tràn ngăn xếp có liên quan khác. Nó trả về hình ảnh từ một số nhà cung cấp, trong khi xử lý các điều kiện hết bộ nhớ và xoay hình ảnh. Nó hỗ trợ thư viện, picasa và quản lý tập tin, như hộp thả. Cách sử dụng rất đơn giản: là đầu vào, hàm tạo nhận bộ giải quyết nội dung và uri. Đầu ra là bitmap cuối cùng.

/**
 * Creates resized images without exploding memory. Uses the method described in android
 * documentation concerning bitmap allocation, which is to subsample the image to a smaller size,
 * close to some expected size. This is required because the android standard library is unable to
 * create a reduced size image from an image file using memory comparable to the final size (and
 * loading a full sized multi-megapixel picture for processing may exceed application memory budget).
 */

public class UserPicture {
    static int MAX_WIDTH = 600;
    static int MAX_HEIGHT = 800;
    Uri uri;
    ContentResolver resolver;
    String path;
    Matrix orientation;
    int storedHeight;
    int storedWidth;

    public UserPicture(Uri uri, ContentResolver resolver) {
        this.uri = uri;
        this.resolver = resolver;
    }

    private boolean getInformation() throws IOException {
        if (getInformationFromMediaDatabase())
            return true;

        if (getInformationFromFileSystem())
            return true;

        return false;
    }

    /* Support for gallery apps and remote ("picasa") images */
    private boolean getInformationFromMediaDatabase() {
        String[] fields = { Media.DATA, ImageColumns.ORIENTATION };
        Cursor cursor = resolver.query(uri, fields, null, null, null);

        if (cursor == null)
            return false;

        cursor.moveToFirst();
        path = cursor.getString(cursor.getColumnIndex(Media.DATA));
        int orientation = cursor.getInt(cursor.getColumnIndex(ImageColumns.ORIENTATION));
        this.orientation = new Matrix();
        this.orientation.setRotate(orientation);
        cursor.close();

        return true;
    }

    /* Support for file managers and dropbox */
    private boolean getInformationFromFileSystem() throws IOException {
        path = uri.getPath();

        if (path == null)
            return false;

        ExifInterface exif = new ExifInterface(path);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                                               ExifInterface.ORIENTATION_NORMAL);

        this.orientation = new Matrix();
        switch(orientation) {
            case ExifInterface.ORIENTATION_NORMAL:
                /* Identity matrix */
                break;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                this.orientation.setScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                this.orientation.setRotate(180);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                this.orientation.setScale(1, -1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                this.orientation.setRotate(90);
                this.orientation.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                this.orientation.setRotate(90);
                break;
            case ExifInterface.ORIENTATION_TRANSVERSE:
                this.orientation.setRotate(-90);
                this.orientation.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                this.orientation.setRotate(-90);
                break;
        }

        return true;
    }

    private boolean getStoredDimensions() throws IOException {
        InputStream input = resolver.openInputStream(uri);
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options);

        /* The input stream could be reset instead of closed and reopened if it were possible
           to reliably wrap the input stream on a buffered stream, but it's not possible because
           decodeStream() places an upper read limit of 1024 bytes for a reset to be made (it calls
           mark(1024) on the stream). */
        input.close();

        if (options.outHeight <= 0 || options.outWidth <= 0)
            return false;

        storedHeight = options.outHeight;
        storedWidth = options.outWidth;

        return true;
    }

    public Bitmap getBitmap() throws IOException {
        if (!getInformation())
            throw new FileNotFoundException();

        if (!getStoredDimensions())
            throw new InvalidObjectException(null);

        RectF rect = new RectF(0, 0, storedWidth, storedHeight);
        orientation.mapRect(rect);
        int width = (int)rect.width();
        int height = (int)rect.height();
        int subSample = 1;

        while (width > MAX_WIDTH || height > MAX_HEIGHT) {
            width /= 2;
            height /= 2;
            subSample *= 2;
        }

        if (width == 0 || height == 0)
            throw new InvalidObjectException(null);

        Options options = new Options();
        options.inSampleSize = subSample;
        Bitmap subSampled = BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options);

        Bitmap picture;
        if (!orientation.isIdentity()) {
            picture = Bitmap.createBitmap(subSampled, 0, 0, options.outWidth, options.outHeight,
                                          orientation, false);
            subSampled.recycle();
        } else
            picture = subSampled;

        return picture;
    }
}

Người giới thiệu:


9

Có hai hướng dẫn hữu ích về trình chọn hình ảnh với mã nguồn có thể tải xuống ở đây:

Cách tạo bộ chọn ảnh Android

Cách chọn và cắt ảnh trên Android

Tuy nhiên, đôi khi ứng dụng sẽ buộc phải đóng, bạn có thể khắc phục bằng cách thêm thuộc tính android: configChanges vào hoạt động chính trong tệp Manifest như:

<activity android:name=".MainActivity"
                  android:label="@string/app_name" android:configChanges="keyboardHidden|orientation" >

Có vẻ như API camera bị mất kiểm soát với định hướng nên điều này sẽ giúp ích cho nó. :)


7

Giải pháp bên dưới hoạt động cho 2.3 (Gingerbread) -4.4 (Kitkat), 5.0 (Lollipop) và 6.0 (Marshmallow) cũng:

Bước 1 Mã để mở thư viện để chọn ảnh:

public static final int PICK_IMAGE = 1;
private void takePictureFromGalleryOrAnyOtherFolder() 
{
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
}

Bước 2 Mã để nhận dữ liệu trong onActivityResult:

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == Activity.RESULT_OK) {
               if (requestCode == PICK_IMAGE) {
                    Uri selectedImageUri = data.getData();
                    String imagePath = getRealPathFromURI(selectedImageUri);
                   //Now you have imagePath do whatever you want to do now
                 }//end of inner if
             }//end of outer if
      }

 public String getRealPathFromURI(Uri contentUri) {
        //Uri contentUri = Uri.parse(contentURI);

        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = null;
        try {
            if (Build.VERSION.SDK_INT > 19) {
                // Will return "image:x*"
                String wholeID = DocumentsContract.getDocumentId(contentUri);
                // Split at colon, use second item in the array
                String id = wholeID.split(":")[1];
                // where id is equal to
                String sel = MediaStore.Images.Media._ID + "=?";

                cursor = context.getContentResolver().query(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        projection, sel, new String[] { id }, null);
            } else {
                cursor = context.getContentResolver().query(contentUri,
                        projection, null, null, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        String path = null;
        try {
            int column_index = cursor
                    .getColumnIndex(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            path = cursor.getString(column_index).toString();
            cursor.close();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        return path;
    }

Nó hoạt động với tôi Tôi đang sử dụng Nexus 5 với Marshmallow. Điện thoại nào bạn đang sử dụng.
Pankaj

Tôi cũng sử dụng google nexus nhưng đã chần chừ để lấy tên hình ảnh hoặc đường dẫn của thư viện của tôi đã chọn hình ảnh tôi nhận được null
Erum

java.lang.SecurityException: Quyền từ chối: đọc com.android.providers.media.MediaProvider uri nội dung: // media / bên ngoài / hình ảnh / phương tiện từ pid = 31.332, uid = 11859 yêu cầu ERIC.READ_EXTERNAL_STORAGE, hoặc cấp nhận được lỗi này
Erum

Bạn có thêm quyền mà nó hiển thịREAD_EXTERNAL_STORAGE
Pankaj

vâng tôi đã thêm quyền trong tệp kê khai nhưng tôi không thêm bất kỳ quyền nào trong các tệp java khi chạy
Erum

6

Để hiển thị hình ảnh và video hãy thử điều này:

    Intent intent = new Intent();
    intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent, 1);
    startActivityForResult(Intent.createChooser(intent,"Wybierz plik"), SELECT_FILE);

5

Chỉ trong trường hợp nó giúp; Tôi làm điều này để có được Bitmap:

InputStream is = context.getContentResolver().openInputStream(imageUri);
Bitmap bitmap = BitmapFactory.decodeStream(is);

Đây là câu trả lời dễ nhất (và là câu trả lời duy nhất phù hợp với tôi). Thật tuyệt vời!
Derlin

5

Câu trả lời trên là đúng. Tôi gặp phải một vấn đề khác trong đó trong HTC M8, ứng dụng của tôi gặp sự cố khi chọn hình ảnh từ thư viện. Tôi nhận được giá trị null cho đường dẫn hình ảnh. Tôi đã sửa và tối ưu hóa với giải pháp sau. trong phương thức onActivityResult

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if ((requestCode == RESULT_LOAD_IMAGE) && (resultCode == RESULT_OK)) {
     if (data != null) {

            Uri selectedImageUri = null;
            selectedImageUri = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

            Cursor imageCursor = mainActivity.getContentResolver().query(
                    selectedImageUri, filePathColumn, null, null, null);

            if (imageCursor == null) {
                return;
            }

            imageCursor.moveToFirst();
            int columnIndex = imageCursor.getColumnIndex(filePathColumn[0]);
            picturePath = imageCursor.getString(columnIndex);
            if (picturePath == null) {
                picturePath = selectedImageUri.getPath();
                String wholeID = DocumentsContract
                        .getDocumentId(selectedImage);

                // Split at colon, use second item in the array
                String id = wholeID.split(":")[1];

                String[] column = { MediaStore.Images.Media.DATA };

                // where id is equal to
                String sel = MediaStore.Images.Media._ID + "=?";

                Cursor cursor = mainActivity.getContentResolver().query(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        column, sel, new String[] { id }, null);

                columnIndex = cursor.getColumnIndex(column[0]);

                if (cursor.moveToFirst()) {
                    picturePath = cursor.getString(columnIndex);
                }

                cursor.close();
            }
            picturePathAbs = new File(picturePath).getAbsolutePath();
            imageCursor.close();
        }

}


Tôi phải đối mặt với vấn đề tương tự và imagePath luôn là null. Tôi thử giải pháp cho bạn nhưng không hiệu quả, cộng với đó getDocumentId yêu cầu> API 19
Stoycho Andreev

3
package com.ImageConvertingDemo;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;
import android.widget.ImageView;

public class MyActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        EditText tv = (EditText)findViewById(R.id.EditText01);
        ImageView iv = (ImageView)findViewById(R.id.ImageView01);
        FileInputStream in;
        BufferedInputStream buf;
            try 
            {
                in = new FileInputStream("/sdcard/smooth.png");
                buf = new BufferedInputStream(in,1070);
                System.out.println("1.................."+buf);
                byte[] bMapArray= new byte[buf.available()];
                tv.setText(bMapArray.toString());
                buf.read(bMapArray);
                Bitmap bMap = BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);

                /*for (int i = 0; i < bMapArray.length; i++) 
                {
                System.out.print("bytearray"+bMapArray[i]);
                }*/
                iv.setImageBitmap(bMap);
                //tv.setText(bMapArray.toString());
                //tv.setText(buf.toString());
                if (in != null) 
                {
                    in.close();
                }
                if (buf != null) 
                {
                    buf.close();
                }

            } 
            catch (Exception e) 
            {
                Log.e("Error reading file", e.toString());
            }
    }
}

1
Bạn không hiểu câu hỏi trước khi trả lời. Ngoài ra, bạn không bao gồm bất kỳ mô tả nào về những gì bạn cố gắng làm. Ngoài ra, mã của bạn phá vỡ một số tiêu chuẩn lập trình Java được thiết lập tốt.
Torben

3
public class BrowsePictureActivity extends Activity {

    // this is the action code we use in our intent, 
    // this way we know we're looking at the response from our own action
    private static final int SELECT_PICTURE = 1;

    private String selectedImagePath;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ((Button) findViewById(R.id.Button01))
                .setOnClickListener(new OnClickListener() {

                    public void onClick(View arg0) {

                        // in onCreate or any event where your want the user to
                        // select a file
                        Intent intent = new Intent();
                        intent.setType("image/*");
                        intent.setAction(Intent.ACTION_GET_CONTENT);
                        startActivityForResult(Intent.createChooser(intent,
                                "Select Picture"), SELECT_PICTURE);
                    }
                });
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
            }
        }
    }

    /**
     * helper to retrieve the path of an image URI
     */
    public String getPath(Uri uri) {
            // just some safety built in 
            if( uri == null ) {
                // TODO perform some logging or show user feedback
                return null;
            }
            // try to retrieve the image from the media store first
            // this will only work for images selected from gallery
            String[] projection = { MediaStore.Images.Media.DATA };
            Cursor cursor = managedQuery(uri, projection, null, null, null);
            if( cursor != null ){
                int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            }
            // this is our fallback here
            return uri.getPath();
    }

}

3

Truy xuất một loại tệp cụ thể

Ví dụ này sẽ nhận được một bản sao của hình ảnh.

static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri
        ...
    }
}

Mở một loại tệp cụ thể

Khi chạy trên 4.4 hoặc cao hơn, bạn yêu cầu mở tệp được quản lý bởi ứng dụng khác

static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri
        ...
    }
}

Nguồn chính thức


2

Bổ sung cho các câu trả lời trước, nếu bạn gặp vấn đề với việc đi đúng đường (như AndroZip), bạn có thể sử dụng cách này:

  public String getPath(Uri uri ,ContentResolver contentResolver) {
        String[] projection = {  MediaStore.MediaColumns.DATA};
        Cursor cursor;
        try{
            cursor = contentResolver.query(uri, projection, null, null, null);
        } catch (SecurityException e){
            String path = uri.getPath();
            String result = tryToGetStoragePath(path);
            return  result;
        }
        if(cursor != null) {
            //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
            //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
            String filePath = cursor.getString(columnIndex);
            cursor.close();
            return filePath;
        }
        else
            return uri.getPath();               // FOR OI/ASTRO/Dropbox etc
    }

    private String tryToGetStoragePath(String path) {
        int actualPathStart = path.indexOf("//storage");
        String result = path;

        if(actualPathStart!= -1 && actualPathStart< path.length())
            result = path.substring(actualPathStart+1 , path.length());

        return result;
    }

Có ai cần biết uri của hình ảnh ở đây không? Nếu tôi chỉ muốn chọn một hình ảnh tùy ý từ thư viện thì sao?
IgorGanapolsky 27/12/13

Ý định mà bạn sẽ nhận được từ thư viện sẽ cung cấp cho bạn url
bugraoral

1

Vui lòng tìm câu trả lời cho việc chọn hình ảnh duy nhất từ ​​thư viện

import android.app.Activity;
import android.net.Uri;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public class PickImage extends Activity {

    Button btnOpen, btnGet, btnPick;
    TextView textInfo1, textInfo2;
    ImageView imageView;

    private static final int RQS_OPEN_IMAGE = 1;
    private static final int RQS_GET_IMAGE = 2;
    private static final int RQS_PICK_IMAGE = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_pick);
        btnOpen = (Button)findViewById(R.id.open);
        btnGet = (Button)findViewById(R.id.get);
        btnPick = (Button)findViewById(R.id.pick);
        textInfo1 = (TextView)findViewById(R.id.info1);
        textInfo2 = (TextView)findViewById(R.id.info2);
        imageView = (ImageView) findViewById(R.id.image);

        btnOpen.setOnClickListener(btnOpenOnClickListener);
        btnGet.setOnClickListener(btnGetOnClickListener);
        btnPick.setOnClickListener(btnPickOnClickListener);
    }

    View.OnClickListener btnOpenOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("image/*");

            startActivityForResult(intent, RQS_OPEN_IMAGE);
        }
    };

    View.OnClickListener btnGetOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_GET_CONTENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("image/*");

            startActivityForResult(intent, RQS_OPEN_IMAGE);
        }
    };

    View.OnClickListener btnPickOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, RQS_PICK_IMAGE);
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {


            if (requestCode == RQS_OPEN_IMAGE ||
                    requestCode == RQS_GET_IMAGE ||
                    requestCode == RQS_PICK_IMAGE) {

                imageView.setImageBitmap(null);
                textInfo1.setText("");
                textInfo2.setText("");

                Uri mediaUri = data.getData();
                textInfo1.setText(mediaUri.toString());
                String mediaPath = mediaUri.getPath();
                textInfo2.setText(mediaPath);

                //display the image
                try {
                    InputStream inputStream = getBaseContext().getContentResolver().openInputStream(mediaUri);
                    Bitmap bm = BitmapFactory.decodeStream(inputStream);

                   ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    byte[] byteArray = stream.toByteArray();

                    imageView.setImageBitmap(bm);

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

0

Cách nhanh nhất để mở hình ảnh từ thư viện hoặc máy ảnh.

Tham khảo gốc: lấy hình ảnh từ thư viện trong Android lập trình

Phương pháp sau sẽ nhận được hình ảnh từ thư viện hoặc máy ảnh và sẽ hiển thị nó trong ImageView. Hình ảnh được chọn sẽ được lưu trữ nội bộ.

mã cho xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.exampledemo.parsaniahardik.uploadgalleryimage.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="20dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Capture Image and upload to server" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Below image is fetched from server"
        android:layout_marginTop="5dp"
        android:textSize="23sp"
        android:gravity="center"
        android:textColor="#000"/>

    <ImageView
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_gravity="center"
        android:layout_marginTop="10dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher"
        android:id="@+id/iv"/>

</LinearLayout>

Lớp JAVA

import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.androidquery.AQuery;
import org.json.JSONException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity implements AsyncTaskCompleteListener{

    private ParseContent parseContent;
    private Button btn;
    private ImageView imageview;
    private static final String IMAGE_DIRECTORY = "/demonuts_upload_camera";
    private final int CAMERA = 1;
    private AQuery aQuery;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        parseContent = new ParseContent(this);
        aQuery = new AQuery(this);

        btn = (Button) findViewById(R.id.btn);
        imageview = (ImageView) findViewById(R.id.iv);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent, CAMERA);
            }
        });

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == this.RESULT_CANCELED) {
            return;
        }
        if (requestCode == CAMERA) {
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            String path = saveImage(thumbnail);
            try {
                uploadImageToServer(path);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    private void uploadImageToServer(final String path) throws IOException, JSONException {

        if (!AndyUtils.isNetworkAvailable(MainActivity.this)) {
            Toast.makeText(MainActivity.this, "Internet is required!", Toast.LENGTH_SHORT).show();
            return;
        }

        HashMap<String, String> map = new HashMap<String, String>();
        map.put("url", "https://demonuts.com/Demonuts/JsonTest/Tennis/uploadfile.php");
        map.put("filename", path);
        new MultiPartRequester(this, map, CAMERA, this);
        AndyUtils.showSimpleProgressDialog(this);
    }

    @Override
    public void onTaskCompleted(String response, int serviceCode) {
        AndyUtils.removeSimpleProgressDialog();
        Log.d("res", response.toString());
        switch (serviceCode) {

            case CAMERA:
                if (parseContent.isSuccess(response)) {
                    String url = parseContent.getURL(response);
                    aQuery.id(imageview).image(url);
                }
        }
    }

    public String saveImage(Bitmap myBitmap) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
        File wallpaperDirectory = new File(
                Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
        // have the object build the directory structure, if needed.
        if (!wallpaperDirectory.exists()) {
            wallpaperDirectory.mkdirs();
        }

        try {
            File f = new File(wallpaperDirectory, Calendar.getInstance()
                    .getTimeInMillis() + ".jpg");
            f.createNewFile();
            FileOutputStream fo = new FileOutputStream(f);
            fo.write(bytes.toByteArray());
            MediaScannerConnection.scanFile(this,
                    new String[]{f.getPath()},
                    new String[]{"image/jpeg"}, null);
            fo.close();
            Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());

            return f.getAbsolutePath();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return "";
    }
}

0

đây là ví dụ của tôi, có thể không chính xác như trường hợp của bạn.


giả sử rằng bạn nhận được định dạng base64 từ nhà cung cấp API của mình, đặt tên tệp và phần mở rộng tệp, lưu nó vào vị trí nhất định trong hệ thống tệp.

public static void shownInBuiltInGallery(final Context ctx, String strBase64Image, final String strFileName, final String strFileExtension){

new AsyncTask<String, String, File>() {
    @Override
    protected File doInBackground(String... strBase64Image) {

        Bitmap bmpImage = convertBase64StringToBitmap(strBase64Image[0], Base64.NO_WRAP);

        if(bmpImage == null) {
            cancel(true);
            return null;
        }

        byte[] byImage = null;

        if(strFileExtension.compareToIgnoreCase(FILE_EXTENSION_JPG) == 0) {
            byImage = convertToJpgByte(bmpImage); // convert bitmap to binary for latter use
        } else if(strFileExtension.compareToIgnoreCase(FILE_EXTENSION_PNG) == 0){
            byImage = convertToPngByte(bmpImage); // convert bitmap to binary for latter use
        } else if(strFileExtension.compareToIgnoreCase(FILE_EXTENSION_BMP) == 0){
            byImage = convertToBmpByte(bmpImage); // convert bitmap to binary for latter use
        } else {
            cancel(true);
            return null;
        }

        if(byImage == null) {
            cancel(true);
            return null;
        }

        File imageFolder = ctx.getExternalCacheDir();

        if(imageFolder.exists() == false){
            if(imageFolder.mkdirs() == false){
                cancel(true);
                return null;
            }
        }

        File imageFile = null;

        try {
            imageFile = File.createTempFile(strFileName, strFileExtension, imageFolder);
        } catch (IOException e){
            e.printStackTrace();
        }

        if(imageFile == null){
            cancel(true);
            return null;
        }

        if (imageFile.exists() == true) {
            if(imageFile.delete() == false){
                cancel(true);
                return null;
            }
        }

        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream(imageFile.getPath());
            fos.write(byImage);
            fos.flush();
            fos.close();
        } catch (java.io.IOException e) {
            e.printStackTrace();
        } finally {
            fos = null;
        }

        return imageFile;
    }

    @Override
    protected void onPostExecute(File file) {
        super.onPostExecute(file);

            String strAuthority = ctx.getPackageName() + ".provider";
            Uri uriImage = FileProvider.getUriForFile(ctx, strAuthority, file);

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uriImage, "image/*");
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            ctx.startActivity(intent);

    }
}.execute(strBase64Image);}

Đừng quên thiết lập một nhà cung cấp tệp thích hợp ở vị trí đầu tiên trong AndroidManifest.xml

        <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">

        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"/>
    </provider>

trong đó đường dẫn tệp là một xml trong ... / res / xml / file_path.xml

<?xml version="1.0" encoding="utf-8"?>

<external-files-path name="external_files" path="Accessory"/>

<external-path name="ex_Download" path="Download/" />
<external-path name="ex_Pictures" path="Pictures/" />

<external-files-path name="my_Download" path="Download/" />
<external-files-path name="my_Pictures" path="Pictures/" />
<external-cache-path name="my_cache" path="." />

<files-path name="private_Download" path="Download/" />
<files-path name="private_Pictures" path="Pictures/" />
<cache-path name="private_cache" path="." />


Câu chuyện dài, ban đầu có nhà cung cấp tệp, chuyển Uri đến Ý định cho nguồn hình ảnh đã biết và có thể truy cập, nếu không, hãy lưu ảnh ở vị trí mong muốn và sau đó chuyển vị trí (dưới dạng Uri) sang Ý định.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.