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


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.