【问题标题】:android pick images from galleryandroid从图库中选择图像
【发布时间】:2011-07-15 14:47:57
【问题描述】:

我想从图库中创建一个图片选择器。我用代码

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

我的问题是在这个活动中显示了视频文件。有没有办法过滤显示的文件,以便在此活动中不显示视频文件?

【问题讨论】:

标签: android gallery action


【解决方案1】:

当然。试试这个:

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

不要忘记创建常量PICK_IMAGE,这样您就可以识别用户何时从图片库Activity回来:

public static final int PICK_IMAGE = 1;

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

这就是我所说的图片库。把它放进去,看看它是否适合你。

编辑:

这会打开 Documents 应用程序。让用户也可以使用他们可能已安装的任何图库应用:

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

【讨论】:

  • 我在这个“Android 系统”、“文档”上有 2 个选项。如果我选择 Android 系统,那么它会为我提供图库和照片。如何摆脱这个中间选项列表?
  • @Uday 只是因为您没有设置默认值。离开它:)
  • PICK_IMAGE 常量必须设置为什么?它说“无法解析符号“PICK_IMAGE”
  • @Michael PICK_IMAGE 常量保存您在这个类上确定的任何 static int 值,这将进一步用于@Override 函数onActivityResult(int requestCode, resultCode, Intent data),建议您在执行任何操作之前使用此常量检查requestCode 参数:)
  • 您可以使用以下代码(假设 RESULT_OK)从 onActivityResult(...) 方法中检索 Bitmap: Bitmap bitmap = data.getExtras().getParcelable("data");
【解决方案2】:

有时,您无法从您选择的图片中获取文件。 这是因为所选内容来自 Google+、Drive、Dropbox 或任何其他提供商。

最好的解决方案是让系统通过Intent.ACTION_GET_CONTENT 选择一个内容,然后通过内容提供者获得结果。

您可以按照下面的代码或查看我的updated gist

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

【讨论】:

  • if(resultCode == Activity.RESULT_OK) {...} 可用于检测成功/取消
  • 如何获取路径?
  • @delive,我想你可以试试new File(data.getData()).getAbsolutePath() 只是猜测,我没试过
  • Android Studio 在 getActivity().getContentResolver().openInputStream(data.getData()); 的片段中发出 FileNotFound 异常警告。
  • 这适用于不返回文件路径的某些设备。但是,我没有办法确定——一旦我有了 InputStream——如何确定图像的方向。
【解决方案3】:

如果您只是在寻找图像和多选。

看@一次https://stackoverflow.com/a/15029515/1136023

对未来很有帮助。使用MultipleImagePick个人感觉很棒。

【讨论】:

  • 使用 MultipleImagePick 作为库的最快方法是什么?它作为一个独立的项目/应用程序..
【解决方案4】:
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);


}

【讨论】:

  • 非常感谢。这个答案帮助我稍后上传图片
  • 我猜你的意思是 case 1: 而不是 case -1: 在 OnActivityResult 的 switch 中。
  • 我知道这是一个新手问题,但是,为什么我们要做所有这些来获取图片路径,那么 data.getData 会返回什么?
  • path 的值是多少?在File file = new File(path);
【解决方案5】:

你可以比这个答案更容易:

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

【讨论】:

  • 我做到了,它奏效了。如果你需要使用文件,例如发送到服务器,你必须使用其他方式,但只是为了将图像加载到 imageview,你可以做这个简单的解决方案。
  • 欢迎来到 SO!除了评论您自己的帖子,您还可以编辑您的帖子。如果您的评论应该解释答案,那么为什么不把它放在答案本身呢?就个人而言,我看不出您对这个老问题的(迟到的)答案与该问题有何关系。我是否可以建议先专注于回答尚未接受答案的问题?
  • 我找不到安卓问题。我怎么能看到只有 android 的问题?
  • 请阅读帮助页面。此外,cmets 不用于讨论网站的运作方式,您可以使用聊天室与其他用户进行实时讨论,您可以在 Meta (help->Meta) 上提出具体问题
【解决方案6】:

您可以使用此方法从图库中选择图像。只会显示图像。

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

【讨论】:

  • @Abhishek...您在哪里找到 ACTION_PICK 意图允许的附加项列表?谢谢!
  • 请不要忘记为 API 级别 23 及更高级别的 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 添加运行时权限。否则,您可能无法从图库中获取不为空的位图。见stackoverflow.com/a/35285667/3341089
  • 设置URI后调用setType会清除数据。
  • 我无法让它工作。即使我设置了return-data=true 并添加了READ_EXTERNAL_STORAGE 权限,getParcelable("data") 始终是null
【解决方案7】:

这是请求权限的完整示例(如果需要),从图库中选择图片,然后将图片转换为 bitmapfile

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

【讨论】:

  • 这无异于一个库,尤其是具有裁剪和纵横比功能。我从来不知道有这样的东西存在。非常感谢您,先生。
  • 回到这里,并没有我希望看到的第一印象那么好。用snapseed编辑时不选图,没有崩溃但没有图像,编辑后点击next时华为默认图库应用不做任何事情,从谷歌照片中选择时不编辑图像,把它带回来没有它直接。只有当我选择华为的默认图库和谷歌照片来编辑它时,它才有效。
  • 谢谢。很好的答案,第一次就很好用。
【解决方案8】:

仅从本地选择添加:

        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)

【讨论】:

    【解决方案9】:

    根据文档,仅为 API min 19 的人提供答案更新:

    在 Android 4.4(API 级别 19)及更高版本上,您可以选择使用 ACTION_OPEN_DOCUMENT Intent,该 Intent 显示系统控制的选取器 UI 控制,允许用户浏览其他应用提供的所有文件。通过这个单一的 UI,用户可以从任何受支持的应用程序中选择一个文件。

    在 Android 5.0(API 级别 21)及更高版本上,您还可以使用 ACTION_OPEN_DOCUMENT_TREE Intent,它允许用户选择一个目录供客户端应用访问。

    Open files using storage access framework - Android Docs

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

    【讨论】:

      【解决方案10】:

      我有同样的问题。我使用这个代码

      添加意图

       Intent intent = new Intent();
              intent.setType("image/*");
              intent.setAction(Intent.ACTION_GET_CONTENT);
              startActivityForResult(Intent.createChooser(intent, "Tack Image"), PICK_PHOTO);
      

      添加onActivityResult

       @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          if (requestCode == PICK_PHOTO && resultCode == Activity.RESULT_OK) {
            if (data == null) {
            //error
              return;
            }
            try {
              Uri uri = data.getData();
              File file = FileUtil.from(currentActivity, uri);
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
        }
      

      FileUtil 类

      import android.content.Context;
      import android.database.Cursor;
      import android.net.Uri;
      import android.provider.OpenableColumns;
      import android.util.Log;
      
      import java.io.File;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      
      public class FileUtil {
        private static final int EOF = -1;
        private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
      
        private FileUtil() {
      
        }
      
        public static File from(Context context, Uri uri) throws IOException {
          InputStream inputStream = context.getContentResolver().openInputStream(uri);
          String fileName = getFileName(context, uri);
          String[] splitName = splitFileName(fileName);
          File tempFile = File.createTempFile(splitName[0], splitName[1]);
          tempFile = rename(tempFile, fileName);
          tempFile.deleteOnExit();
          FileOutputStream out = null;
          try {
            out = new FileOutputStream(tempFile);
          } catch (FileNotFoundException e) {
            e.printStackTrace();
          }
          if (inputStream != null) {
            copy(inputStream, out);
            inputStream.close();
          }
      
          if (out != null) {
            out.close();
          }
          return tempFile;
        }
      
        private static String[] splitFileName(String fileName) {
          String name = fileName;
          String extension = "";
          int i = fileName.lastIndexOf(".");
          if (i != -1) {
            name = fileName.substring(0, i);
            extension = fileName.substring(i);
          }
      
          return new String[]{name, extension};
        }
      
        private static String getFileName(Context context, Uri uri) {
          String result = null;
          if (uri.getScheme().equals("content")) {
            Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
            try {
              if (cursor != null && cursor.moveToFirst()) {
                result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
              }
            } catch (Exception e) {
              e.printStackTrace();
            } finally {
              if (cursor != null) {
                cursor.close();
              }
            }
          }
          if (result == null) {
            result = uri.getPath();
            int cut = result.lastIndexOf(File.separator);
            if (cut != -1) {
              result = result.substring(cut + 1);
            }
          }
          return result;
        }
      
        private static File rename(File file, String newName) {
          File newFile = new File(file.getParent(), newName);
          if (!newFile.equals(file)) {
            if (newFile.exists() && newFile.delete()) {
              Log.d("FileUtil", "Delete old " + newName + " file");
            }
            if (file.renameTo(newFile)) {
              Log.d("FileUtil", "Rename file to " + newName);
            }
          }
          return newFile;
        }
      
        private static long copy(InputStream input, OutputStream output) throws IOException {
          long count = 0;
          int n;
          byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
          while (EOF != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
          }
          return count;
        }
      }
      

      并且您必须将 provider_paths.xml 添加到 xml 文件夹中,例如图片

      provider_paths.xml

      <?xml version="1.0" encoding="utf-8"?>
      <paths>
          <external-path name="external_files" path="."/>
      </paths>
      

      最后在 AndroidManifest.xml

      中添加
      <application
      ...>
      
      ...
            <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="${applicationId}.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                  android:name="android.support.FILE_PROVIDER_PATHS"
                  android:resource="@xml/provider_paths" />
              </provider>
      ...
      </application>
      

      希望能帮到你

      【讨论】:

        【解决方案11】:

        OPTION-1

        以下代码允许用户从任何文件资源管理器应用程序中选择图像

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

        但在某些设备中,上述解决方案不会获取带有 EXIF 信息(例如方向)的图像。因此,在这些设备中,无法按预期执行 EXIF 处理(例如更改图像方向)。

        OPTION-2

        以下代码允许用户从任何图库应用程序中选择图像

        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        startActivityForResult ( intent, PICK_IMAGE_CODE );
        

        但在某些设备中,在设置意图类型时,上述解决方案会清除意图数据(MediaStore.Images.Media.EXTERNAL_CONTENT_URI),这可能会阻碍画廊打开过程。

        OPTION-3

        最后,我建议使用下面的代码,它允许用户从任何图库应用程序中选择一个不会导致任何问题且不显示任何警告的图像

        Intent intent = new Intent ();
        intent.setAction ( Intent.ACTION_PICK );
        intent.setDataAndType ( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*" );
        startActivityForResult ( intent, PICK_IMAGE_CODE );
        

        【讨论】:

          【解决方案12】:

          Kotlin:要提示用户时打开ACTION_GET_CONTENT事件:

          val intent = Intent(Intent.ACTION_GET_CONTENT).apply { type = "image/*" }
          startActivityForResult(intent, 9998)
          

          用户选择一张图片后,在您的 Activity 的 onActivityResult 函数中处理该事件。例如,我将其显示在 ImageView 中并将其存储在应用缓存中:

          override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
              super.onActivityResult(requestCode, resultCode, data)
              if (requestCode == 9998) {
                  val uri: Uri = data?.data ?: return
                  val bytes = contentResolver.openInputStream(uri)?.readBytes() ?: return
                  imageView.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
                  File("$cacheDir/imgPicked").writeBytes(bytes)  // if needed: store to cache
              }
          }
          

          理想情况下,将9998 替换为您的应用使用的一些内部请求代码枚举。这只是为了让您可以将回调与您自己的请求区分开来。

          getParcelable("data") 不同,这不需要任何权限。

          请注意,这不会处理设置它的图像上的 Exif rotation bit,因此一些图像最终会出现方向错误 (Kotlin solution)。

          【讨论】:

            【解决方案13】:

            2021 Kotlin 解决方案与新版 Fragment:

            dependencies {
              implementation "androidx.fragment:fragment:1.3.3"
            }
            
            class YourFragment : Fragment() {
            
                private val fileChooserContract = registerForActivityResult(ActivityResultContracts.GetContent()) { imageUri ->
                    if (imageUri != null) {
                        // imageUri now contains URI to selected image
                    }
                }
            
                // ...
            
                fun openFileChooser() {
                    fileChooserContract.launch("image/*")
                }
            }
            

            【讨论】:

            • 如何设置选择器标题?
            【解决方案14】:

            感谢 mklkj。

            这是一个活动版本。

            fileChooserContract 可以选择图片。 filesChooserContract可以选择多张图片。

            class MainActivity : AppCompatActivity() {
            
                companion object {
                    private const val TAG = "MainActivity"
                }
            
                lateinit var viewBinding: ActivityMainBinding
            
                private val fileChooserContract = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
                    Log.d(TAG, "onActivityResult: uri $uri")
                }
            
                private val filesChooserContract = registerForActivityResult(ActivityResultContracts.GetMultipleContents()) { uriList ->
                    for (uri in uriList) {
                        Log.d(TAG, "onActivityResult: uri $uri")
                    }
                }
            
                override fun onCreate(savedInstanceState: Bundle?) {
                    super.onCreate(savedInstanceState)
                    viewBinding = ActivityMainBinding.inflate(layoutInflater)
                    setContentView(viewBinding.root)
            
                    viewBinding.btnPick.setOnClickListener {
                        fileChooserContract.launch("image/*")
                    }
            
                    viewBinding.btnPickMulti.setOnClickListener {
                        filesChooserContract.launch("image/*")
                    }
                }
            }
            

            【讨论】:

              【解决方案15】:

              再见 startActivityForResult()

              如今使用 AndroidX Activity 的正确方式是 Activity Result API,这是google 强烈推荐的方式

              private val selectImageFromGalleryResult = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
                  uri?.let { previewImage.setImageURI(uri) }
              }
              

              只需在需要时调用 selectImageFromGallery()

              private fun selectImageFromGallery() = selectImageFromGalleryResult.launch("image/*")
              

              【讨论】:

                【解决方案16】:

                这是 kotlin 中一个 util 方法的工作代码:

                fun launchGalleryWithFragment() {
                        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
                        intent.type = "image/*"
                        startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1001)
                    }
                

                现在重写 onActivityResult 方法:

                override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
                    super.onActivityResult(requestCode, resultCode, data)
                var path: Uri? = null
                        if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK) {
                            if(dataIntent == null || dataIntent.data == null){
                                return null
                            }
                            path = dataIntent.data
                        }
                

                }

                【讨论】:

                  【解决方案17】:

                  OnActivityResult 方法已弃用

                  val singleImageResultLauncher =
                              registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                                  if (result.resultCode == Activity.RESULT_OK) {
                                      // There are no request codes
                                      val data: Intent? = result.data
                                      val selectedImageUri: Uri? = data?.data
                                      if (null != selectedImageUri) {
                                          // Get the path from the Uri
                                          val path = getPathFromURI(selectedImageUri)
                                          findViewById<TextView>(R.id.textView).text = path
                                          findViewById<ImageView>(R.id.imageView2).setImageURI(selectedImageUri)
                                      }
                                  }
                              }
                  
                  findViewById<Button>(R.id.oneImageSelectBtn).setOnClickListener {
                              val intent = Intent()
                              intent.type = "image/*"
                              intent.action = Intent.ACTION_GET_CONTENT
                              intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
                              singleImageResultLauncher.launch(Intent.createChooser(intent, "Select Picture"))
                  
                          }
                  
                  private fun getPathFromURI(uri: Uri?): String {
                          var path = ""
                          if (contentResolver != null) {
                              val cursor = contentResolver.query(uri!!, null, null, null, null)
                              if (cursor != null) {
                                  cursor.moveToFirst()
                                  val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME)
                                  path = cursor.getString(idx)
                                  cursor.close()
                              }
                          }
                          return path
                  }
                  

                  【讨论】:

                    【解决方案18】:

                    由于startActivityForResult() is depracated,我们可以通过以下方式从图库中仅选择图片using ActivityResultLauncher

                    首先我们需要定义一个ActivityResultLauncher&lt;String[]&gt;,并在onCreate()(用于活动)或onViewCreated()(用于片段)中初始化它

                            ActivityResultLauncher<String[]> galleryActivityLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), new ActivityResultCallback<Uri>() {
                                @Override
                                public void onActivityResult(Uri result) {
                                    if (result != null) {
                                        // perform desired operations using the result Uri
                                    } else {
                                        Log.d(TAG, "onActivityResult: the result is null for some reason");
                                    }
                                }
                            });
                    

                    假设我们需要在点击submitButton 时打开图库。

                    所以在onClickListener内部我们需要调用

                    galleryActivityLauncher.launch(new String[]{"image/*"});
                    

                    这里的技巧是launch() 的参数。通过将"image/*" 添加到参数数组,我们指定文件资源管理器应仅加载图像。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多