андроїд виберіть зображення з галереї


197

Я хочу створити вибір зображення з галереї. Я використовую код

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

Моя проблема полягає в тому, що в цій діяльності відображаються і відеофайли. Чи є спосіб фільтрувати відображені файли, щоб у цій діяльності не відображалися жодні відеофайли?


3
У цій статті чудово описано, як вибрати зображення з галереї: androidbitmaps.blogspot.com/2015/04/…
— Енді Рез

Є одне подібне питання, як у вас. stackoverflow.com/a/31382240/1835650
— TeeTracker

Відповіді:


347

Абсолютно. Спробуйте це:

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

Не забудьте також створити постійну PICK_IMAGE , щоб ви могли розпізнати, коли користувач повертається з галереї зображень Активність:

public static final int PICK_IMAGE = 1;

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

Ось так я називаю галерею зображень. Покладіть його і подивіться, чи працює він для вас.

Редагувати:

Це відкриває додаток Документи. Щоб дозволити користувачу також використовувати будь-які додатки галереї, які вони могли б встановити:

    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
Я отримую 2 варіанти цієї "Android системи", "Документи". Якщо я виберу Android System, тоді він подарує мені Галерею та Фото. Як я можу позбутися цього проміжного списку варіантів?
— Uday

4
@Uday це просто тому, що ти не встановив за замовчуванням. Просто залиште його :)
— Трістан Вілі

13
Для чого потрібно встановити константу PICK_IMAGE? Там написано "Не вдається вирішити символ" PICK_IMAGE "
— Майкл

3
@Michael константа PICK_IMAGE містить будь-яке значення статичного int, визначене вами в цьому самому класі, це додатково використовується у @Overrideфункції onActivityResult(int requestCode, resultCode, Intent data), де рекомендується використовувати цю константу для перевірки requestCodeпараметра перед тим, як робити будь-які дії :)
— Gabcvit,

Ви можете отримати Bitmap з методу onActivityResult (...) за допомогою наступного коду (припускаючи RESULT_OK): Bitmap bitmap = data.getExtras (). GetParcelable ("дані");
— Shn_Android_Dev

197

Іноді ви не можете отримати файл із обраної вами картинки. Це тому, що вибраний прийшов із Google+, Диска, Dropbox чи будь-якого іншого постачальника.

Найкраще рішення - попросити систему вибрати вміст через Intent.ACTION_GET_CONTENT і отримати результат у постачальника контенту.

Ви можете слідкувати за цим кодом нижче або переглянути мій оновлений суть .

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) {...}можна використовувати для виявлення успіху / скасування
— Thamme Gowda

Як можна пройти шлях?
— доставлять

@delive, я думаю, ти можеш спробувати. new File(data.getData()).getAbsolutePath()Просто здогадуюсь, я не пробував цього
— хтось десь

1
Попередження про виняток FileNotFound від Android Studio у фрагменті в getActivity().getContentResolver().openInputStream(data.getData());.
— Ікбал

1
Це працює на певних пристроях, на яких шлях файлу не повертається. Однак я не бачу способу визначити - як тільки я матиме InputStream - як зрозуміти орієнтацію зображення.
— Кейсі Перкінс

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


}

Велике спасибі. Ця відповідь допомогла мені завантажити зображення пізніше
— Розаріо Перейра Фернандес

Я думаю, ви маєте на увазі випадок 1: замість випадку -1: в комутаторі OnActivityResult.
— Матіас

Я знаю, що це питання про Newibe, але чому ми зробили це для отримання шляху зображення, що тоді повертає data.getData?
— moumenShobakey

яка цінність path? вFile file = new File(path);
— Раві Ванія

24

За допомогою цього методу можна вибрати зображення з галереї. Відобразяться лише зображення.

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

і перекрити onActivityResult як

    @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 ... де ви знайшли список додаткових дозволених для намірів ACTION_PICK? Дякую!
— Джонні Ву

1
Не забудьте додати дозволи на виконання для READ_EXTERNAL_STORAGE та WRITE_EXTERNAL_STORAGE для рівня api 23 та вище. Інакше ви не можете отримати растрові карти з галереї як недійсні. Дивіться stackoverflow.com/a/35285667/3341089
— огужан

1
Виклик setType після встановлення URI очистить дані.
— Таслім Осені

11

Ось повний приклад для отримання дозволу на запит (якщо потрібно), виберіть зображення з галереї, а потім перетворіть зображення в bitmapабоfile

AndroidManifesh.xml

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

Діяльність

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

Демонстраційний
https://github.com/PhanVanLinh/AndroidPickImage


Це не менше, ніж бібліотека, особливо з цією особливістю обрізання та співвідношення сторін. Я ніколи не знав, що таке існує. Дуже дякую, сер.
— Лаліт Фауздар

1
Повернутися сюди, це не так добре, як я сподівався побачити перші враження. Він не вибирає зображення під час редагування з моментальним знімком, не відбувається збій, але немає зображення, додаток для галереї huawei за замовчуванням нічого не робить, коли натискаю наступне після редагування, воно не редагує зображення, коли вибрано з google фотографій, повертає його назад без цього безпосередньо. Це добре, лише якщо я вибрав галерею за замовчуванням huawei та фотографії Google для редагування.
— Лаліт Фауздар

2

Якщо ви шукаєте лише зображення та багаторазовий вибір.

Подивіться @ раз https://stackoverflow.com/a/15029515/1136023

Це корисно для майбутнього. Я особисто відчуваю себе чудово, використовуючи MultipleImagePick .


який найшвидший спосіб використовувати MultipleImagePick як бібліотеку? Він поставляється як окремий проект / заявка ..
— ticofab

2

Просто запропонуйте оновлення відповіді для людей, які мають API 19 хв. За документи:

На Android 4.4 (рівень 19) та новіші версії ви маєте додатковий варіант використання наміру ACTION_OPEN_DOCUMENT, який відображає контрольований користувачем інтерфейс вибору, керований системою, що дозволяє користувачеві переглядати всі файли, доступні для інших програм. З цього єдиного інтерфейсу користувача можна вибрати файл із будь-якого підтримуваного додатка.

На Android 5.0 (рівень 21) та новіших версій ви також можете використовувати намір ACTION_OPEN_DOCUMENT_TREE, що дозволяє користувачеві вибрати каталог для доступу до клієнтського додатка.

Відкрийте файли, використовуючи рамки доступу для зберігання - Документи Android

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

0

Для вибору лише з місцевих додайте це:

        i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)

І це добре працює:

    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

Ви можете зробити це простіше, ніж це дає відповіді:

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

Я це роблю, і це спрацювало. якщо вам потрібно використовувати файл, наприклад, для відправки на сервер, вам доведеться використовувати інші способи, але тільки для завантаження зображення на перегляд зображень, ви можете зробити це просте рішення.
— Аліреза Тагізаде

5
Ласкаво просимо до SO! Замість того, щоб коментувати власну публікацію, ви також можете редагувати свою публікацію. Якщо ваш коментар повинен пояснити відповідь, то чому б не поставити його у самій відповіді? Особисто я не бачу, як ваша (пізня) відповідь на це старе питання пов'язана з питанням. Чи можу я запропонувати сфокусуватися на питаннях, які ще не мають прийнятої відповіді?
— cfi

1
я не можу знайти питання щодо Android. як я можу бачити лише питання щодо Android?
— Аліреза Тагізаде

3
Будь ласка, прочитайте довідкові сторінки. Крім того, коментарі не стосуються дискусій про те, як працює сайт, ви можете використовувати чати для прямого обговорення з іншими користувачами, а ви можете задавати конкретні запитання щодо Meta (довідка-> Мета)
— cfi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.