android chọn hình ảnh từ thư viện


196

Tôi muốn tạo một trình chọn ảnh từ thư viện. Tôi sử dụng mã

 intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
 startActivityForResult(intent, TFRequestCodes.GALLERY);

Vấn đề của tôi là trong hoạt động này và các tập tin video được hiển thị. Có cách nào để lọc các tệp được hiển thị để không có tệp video nào được hiển thị trong hoạt động này không?


3
Bài viết này mô tả độc đáo cách chọn hình ảnh từ thư viện: androidbitmaps.blogspot.com/2015/04/ Kẻ
Andy Res

Có một câu hỏi tương tự như bạn. stackoverflow.com/a/31382240/1835650
TeeTracker

Câu trả lời:


345

Chắc chắn rồi. Thử cái này:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);

Cũng đừng quên tạo PICK_IMAGE không đổi , để bạn có thể nhận ra khi người dùng quay lại từ thư viện ảnh Hoạt động:

public static final int PICK_IMAGE = 1;

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == PICK_IMAGE) {
        //TODO: action
    }
}

Đó là cách tôi gọi bộ sưu tập hình ảnh. Đặt nó vào và xem nếu nó làm việc cho bạn.

BIÊN TẬP:

Điều này mang đến ứng dụng Tài liệu. Để cho phép người dùng cũng sử dụng bất kỳ ứng dụng thư viện nào họ có thể đã cài đặt:

    Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
    getIntent.setType("image/*");

    Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    pickIntent.setType("image/*");

    Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});

    startActivityForResult(chooserIntent, PICK_IMAGE);

6
Tôi nhận được 2 tùy chọn trên "Hệ thống Android", "Tài liệu" này. Nếu tôi chọn Hệ thống Android, thì nó sẽ hiển thị cho tôi Thư viện và Ảnh. Làm thế nào để tôi thoát khỏi danh sách tùy chọn trung gian này?
Uday

4
@Uday đơn giản là vì bạn chưa đặt mặc định. Cứ để đó đi :)
Tristan Wiley

13
Hằng số PICK_IMAGE phải được đặt thành gì? Nó nói "Không thể giải quyết biểu tượng" PICK_IMAGE "
Michael

3
@ Michael các PICK_IMAGE liên tục nắm giữ bất kỳ int tĩnh giá trị xác định bởi bạn trên lớp này rất, đây là tiếp tục sử dụng trên @Overridechức năng onActivityResult(int requestCode, resultCode, Intent data), nơi nó được đề nghị mà bạn sử dụng liên tục này để kiểm tra các requestCodethông số trước khi thực hiện bất kỳ hành động :)
Gabriel Checchia Vitali

Bạn có thể truy xuất Bitmap từ phương thức onActivityResult (...) bằng mã sau (giả sử RESULT_OK): Bitmap bitmap = data.getExtras (). GetParcelable ("data");
Shn_Android_Dev

197

Đôi khi, bạn không thể lấy một tập tin từ hình ảnh bạn chọn. Đó là vì người được chọn đến từ Google+, Drive, Dropbox hoặc bất kỳ nhà cung cấp nào khác.

Giải pháp tốt nhất là yêu cầu hệ thống chọn một nội dung qua Intent.ACTION_GET_CONTENT và nhận kết quả với nhà cung cấp nội dung.

Bạn có thể làm theo mã dưới đây hoặc nhìn vào của tôi ý chính được cập nhật .

public void pickImage() {
  Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
  intent.setType("image/*");
  startActivityForResult(intent, PICK_PHOTO_FOR_AVATAR);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {
        if (data == null) {
            //Display an error
            return;
        }
        InputStream inputStream = context.getContentResolver().openInputStream(data.getData());
        //Now you can do whatever you want with your inpustream, save it as file, upload to a server, decode a bitmap...
    }
}

14
if(resultCode == Activity.RESULT_OK) {...}có thể được sử dụng để phát hiện thành công / hủy bỏ
Thamme Gowda

Làm thế nào bạn có thể có được con đường?
delive

@delive, tôi nghĩ bạn có thể thử new File(data.getData()).getAbsolutePath()Chỉ là một phỏng đoán, tôi đã không thử nó
Ai đó ở đâu đó

1
Cảnh báo ngoại lệ FileNotFound của Android Studio trong đoạn getActivity().getContentResolver().openInputStream(data.getData());.
Iqbal

1
Điều này hoạt động trên các thiết bị nhất định trong đó đường dẫn của tệp không được trả lại. Tuy nhiên, tôi thấy không có cách nào để xác định - một khi tôi có InputStream - làm thế nào để tìm ra hướng của hình ảnh.
Casey Perkins

30
public void FromCamera() {

    Log.i("camera", "startCameraActivity()");
    File file = new File(path);
    Uri outputFileUri = Uri.fromFile(file);
    Intent intent = new Intent(
            android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
    startActivityForResult(intent, 1);

}

public void FromCard() {
    Intent i = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(i, 2);
}

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == 2 && resultCode == RESULT_OK
            && null != data) {

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

        Cursor cursor = getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();

        bitmap = BitmapFactory.decodeFile(picturePath);
        image.setImageBitmap(bitmap);

        if (bitmap != null) {
            ImageView rotate = (ImageView) findViewById(R.id.rotate);

        }

    } else {

        Log.i("SonaSys", "resultCode: " + resultCode);
        switch (resultCode) {
        case 0:
            Log.i("SonaSys", "User cancelled");
            break;
        case -1:
            onPhotoTaken();
            break;

        }

    }

}

protected void onPhotoTaken() {
    // Log message
    Log.i("SonaSys", "onPhotoTaken");
    taken = true;
    imgCapFlag = true;
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 4;
    bitmap = BitmapFactory.decodeFile(path, options);
    image.setImageBitmap(bitmap);


}

Cảm ơn rât nhiều. Câu trả lời này đã giúp tôi tải lên hình ảnh sau này
Rosário Pereira Fernandes

Tôi đoán bạn có nghĩa là trường hợp 1: thay vì trường hợp -1: trong công tắc trong OnActivityResult.
Mathias

Tôi biết đó là một câu hỏi của newibe nhưng, tại sao chúng tôi đã làm tất cả những điều này để có được đường dẫn hình ảnh, data.getData trả về sau đó là gì?
moumenShobakey

giá trị của là pathgì? trongFile file = new File(path);
Ravi Vaniya ngày

23

Bạn có thể sử dụng phương pháp này để chọn hình ảnh từ thư viện. Chỉ hình ảnh sẽ được hiển thị.

public void pickImage() {
    Intent intent = new Intent(Intent.ACTION_PICK,
            MediaStore.Images.Media.INTERNAL_CONTENT_URI);
    intent.setType("image/*");
    intent.putExtra("crop", "true");
    intent.putExtra("scale", true);
    intent.putExtra("outputX", 256);
    intent.putExtra("outputY", 256);
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("return-data", true);
    startActivityForResult(intent, 1);
}

và ghi đè lênActivityResult như

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }
        if (requestCode == 1) {
            final Bundle extras = data.getExtras();
            if (extras != null) {
                //Get image
                Bitmap newProfilePic = extras.getParcelable("data");
            }
        }
    }

2
@Abhishek ... bạn đã tìm thấy danh sách các tính năng bổ sung được phép cho mục đích ACTION_PICK ở đâu? Cảm ơn!
Johnny Wu

1
Xin đừng quên thêm quyền truy cập cho READ_EXTERNAL_STORAGE và WRITE_EXTERNAL_STORAGE cho api cấp 23 trở lên. Nếu không, bạn có thể không nhận được bitmap từ thư viện như không null. Xem stackoverflow.com/a353285667/3341089
oguzhan

1
Gọi setType sau khi cài đặt URI sẽ xóa dữ liệu.
TASlim Oseni

11

Dưới đây là một ví dụ đầy đủ cho phép yêu cầu (nếu cần), chọn hình ảnh từ thư viện, sau đó chuyển đổi hình ảnh sang bitmaphoặcfile

AndroidManifesh.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Hoạt động

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button_pick_image.setOnClickListener {
            pickImage()
        }
    }

    private fun pickImage() {
        if (ActivityCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            val intent = Intent(
                Intent.ACTION_PICK,
                MediaStore.Images.Media.INTERNAL_CONTENT_URI
            )
            intent.type = "image/*"
            intent.putExtra("crop", "true")
            intent.putExtra("scale", true)
            intent.putExtra("aspectX", 16)
            intent.putExtra("aspectY", 9)
            startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                READ_EXTERNAL_STORAGE_REQUEST_CODE
            )
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICK_IMAGE_REQUEST_CODE) {
            if (resultCode != Activity.RESULT_OK) {
                return
            }
            val uri = data?.data
            if (uri != null) {
                val imageFile = uriToImageFile(uri)
                // todo do something with file
            }
            if (uri != null) {
                val imageBitmap = uriToBitmap(uri)
                // todo do something with bitmap
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            READ_EXTERNAL_STORAGE_REQUEST_CODE -> {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // pick image after request permission success
                    pickImage()
                }
            }
        }
    }

    private fun uriToImageFile(uri: Uri): File? {
        val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = contentResolver.query(uri, filePathColumn, null, null, null)
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                val columnIndex = cursor.getColumnIndex(filePathColumn[0])
                val filePath = cursor.getString(columnIndex)
                cursor.close()
                return File(filePath)
            }
            cursor.close()
        }
        return null
    }

    private fun uriToBitmap(uri: Uri): Bitmap {
        return MediaStore.Images.Media.getBitmap(this.contentResolver, uri)
    }

    companion object {
        const val PICK_IMAGE_REQUEST_CODE = 1000
        const val READ_EXTERNAL_STORAGE_REQUEST_CODE = 1001
    }
}

Bản giới thiệu
https://github.com/PhanVanLinh/AndroidPickImage


Điều này không gì khác hơn một thư viện, đặc biệt là với tính năng cắt xén và tỷ lệ khung hình đó. Tôi không bao giờ biết một điều như vậy tồn tại. Cảm ơn ngài rất nhiều.
Lalit Fauzdar

1
Quay lại đây, thật không tốt khi tôi hy vọng nhìn thấy những ấn tượng đầu tiên. Nó không chọn hình ảnh khi được chỉnh sửa bằng snapseed, không có sự cố nhưng không có hình ảnh, ứng dụng thư viện mặc định của huawei không làm gì khi tôi nhấp vào tiếp theo sau khi chỉnh sửa, nó không chỉnh sửa hình ảnh khi được chọn từ google photos, mang nó trở lại không có nó trực tiếp Nó chỉ hoạt động tốt nếu tôi chọn thư viện mặc định của huawei và google photos để chỉnh sửa nó.
Lalit Fauzdar


1

Chỉ để cung cấp bản cập nhật cho câu trả lời cho những người có API tối thiểu 19, theo các tài liệu:

Trên Android 4.4 (API cấp 19) trở lên, bạn có thêm tùy chọn sử dụng mục đích ACTION_OPEN_DOCUMENT, hiển thị giao diện người dùng chọn điều khiển hệ thống được kiểm soát cho phép người dùng duyệt tất cả các tệp mà các ứng dụng khác đã có sẵn. Từ giao diện người dùng duy nhất này, người dùng có thể chọn một tệp từ bất kỳ ứng dụng được hỗ trợ nào.

Trên Android 5.0 (API cấp 21) trở lên, bạn cũng có thể sử dụng ý định ACTION_OPEN_DOCUMENT_TREE, cho phép người dùng chọn thư mục cho ứng dụng khách truy cập.

Mở tệp bằng khung truy cập lưu trữ - Tài liệu Android

     val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
     intent.type = "image/*"
     startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)

0

Để chỉ chọn từ địa phương thêm này:

        i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)

Và điều này làm việc tốt đẹp:

    val i = Intent(Intent.ACTION_GET_CONTENT,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    i.type = "image/*"
    i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)
    startActivityForResult(Intent.createChooser(i,"Select Photo"),pickImageRequestCode)

-7

Bạn có thể làm điều đó dễ dàng hơn câu trả lời này:

Uri Selected_Image_Uri = data.getData();
ImageView imageView = (ImageView) findViewById(R.id.loadedimg);
imageView.setImageURI(Selected_Image_Uri);

Tôi làm nó, và nó đã làm việc. Nếu bạn cần sử dụng để gửi ví dụ để gửi đến máy chủ, bạn phải sử dụng các cách khác nhưng chỉ để tải hình ảnh vào chế độ xem hình ảnh, bạn có thể thực hiện giải pháp dễ dàng này.
Alireza Taghizadeh

5
Chào mừng đến với SO! Thay vì bình luận về bài đăng của riêng bạn, bạn cũng có thể chỉnh sửa bài đăng của mình. Nếu bình luận của bạn được cho là để giải thích câu trả lời, thì tại sao bạn không đặt nó vào câu trả lời? Cá nhân, tôi không thấy câu trả lời (muộn) của bạn cho câu hỏi cũ này có liên quan đến câu hỏi như thế nào. Tôi có thể đề nghị tập trung vào việc trả lời các câu hỏi trước mà chưa có câu trả lời được chấp nhận không?
cfi

1
Tôi không thể tìm thấy câu hỏi Android. Làm thế nào tôi có thể chỉ nhìn thấy câu hỏi Android?
Alireza Taghizadeh

3
Xin vui lòng đọc các trang trợ giúp. Ngoài ra, các bình luận không dành cho các cuộc thảo luận về cách trang web hoạt động, bạn có thể sử dụng các phòng trò chuyện để thảo luận trực tiếp với những người dùng khác và bạn có thể đặt câu hỏi cụ thể về Meta (trợ giúp-> Meta)
cfi
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.