ActivityResultLauncher 用于上传头像

Posted

技术标签:

【中文标题】ActivityResultLauncher 用于上传头像【英文标题】:ActivityResultLauncher for uploading profile picture 【发布时间】:2022-01-05 23:11:38 【问题描述】:

我想从手机图库中挑选一张图片作为用户的个人资料图片上传到应用中。我想获取它的 URI,以便将其存储在用户数据库中。

activityResultLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(), result -> 
                if (result.getResultCode() == RESULT_OK && result.getData()!= null) 
                    Bundle data = result.getData().getExtras();
                    Uri myUri = (Uri) data.get("data");
                    profilePic.setImageURI(myUri);
                
        );

    uploadPicture.setOnClickListener(view -> 
        Intent imagePickerIntent = new Intent(Intent.ACTION_PICK, 
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        imagePickerIntent.setType("image/*");
        activityResultLauncher.launch(imagePickerIntent);
    );

现在我可以在此处输入代码并打开图库并浏览图片,但是当我选择一个并尝试从图库返回我的应用程序时应用程序崩溃。谁能告诉我如何修复我的代码?谢谢

【问题讨论】:

你不应该将ACTION_PICK 用于图像——这就是GetContent 合约的用途。即使您使用的是ACTION_PICK,是什么让您相信它会为您提供额外的回报?根据ACTION_PICK's documentation,它只返回一个Uri,没有别的。 【参考方案1】:

Activity 的启动方法。

 private void selectImage()
    Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    activityResultLauncher.launch(intent);

然后,按如下方式覆盖 onRequestPermissionsResult():

 @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_CODE_STORAGE_PERMISSION && grantResults.length > 0)
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            selectImage();
        else 
            Toast.makeText(this, "Permission Denied!", Toast.LENGTH_SHORT).show();
        
    

另一种,方法如下:

 private void displayResult()
    activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
            result -> 
                if (result.getResultCode() == Activity.RESULT_OK)
                    Intent data = result.getData();
                    if (data != null)
                        Uri selectedImageUri = data.getData();
                        if (selectedImageUri != null)
                            try 
                                InputStream inputStream = getContentResolver().openInputStream(selectedImageUri);
                                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                                noteBinding.imageNote.setImageBitmap(bitmap);
                                selectedImagePath = getPathFormatUri(selectedImageUri);
                            catch (Exception e)
                                Toast.makeText(CreateNoteActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                            
                        
                    
                
            );

另一种返回图片 url/path 的方法。

 private String getPathFormatUri(Uri contentUri)
    String filePath;
    Cursor cursor = getContentResolver()
            .query(contentUri,null,null,null,null);
    if (cursor == null)
        filePath = contentUri.getPath();
    else 
        cursor.moveToFirst();
        int index = cursor.getColumnIndex("_data");
        filePath = cursor.getString(index);
        cursor.close();
    

    return filePath;

【讨论】:

以上是关于ActivityResultLauncher 用于上传头像的主要内容,如果未能解决你的问题,请参考以下文章

将多个 Mime 类型传递给 ActivityResultLauncher.launch()

在Android中以ActivityResultLauncher方式进行页面跳转传递参数拍照或选择文件,以及调用系统应用打开各种类型的指定文件

安卓Android开发:以ActivityResultLauncher方式进行页面跳转传递参数拍照或选择文件,以及调用系统应用打开各种类型的指定文件

Activity 结果 API 的 ActivityResultLauncher launch() 方法不仅会调用合约的 createIntent() 方法,还会调用 parseResult()

Android ActivityResultContracts 替代 startActivityForResult

Android 在 registerForActivityResult 中使用对象