使用ActivityResultLauncher上传图片遇URI为空崩溃问题求助
头像上传功能崩溃修复与废弃API替代方案
问题根源
你的代码里有几个关键问题导致崩溃和功能失效:
- 回调里重新定义了局部变量
imageUriPath,没给成员变量赋值,导致GetImageInView()调用时imageUriPath为null - 获取Bitmap后没把它设置到ImageView上
- 还在使用已废弃的
MediaStore.Images.Media.getBitmap()方法 - 上传逻辑里用的
imagePath变量从未被赋值,应该用选中的图片URI Tag变量没初始化,Log打印会报错
修复后的完整代码
public class Profile extends AppCompatActivity { private ImageView ProfileImg; private final String Tag = "ProfileActivity"; // 初始化Tag private Uri imageUriPath; // 只保留这个URI变量即可,去掉冗余的imagePath private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); progressBar = findViewById(R.id.progressBar); Button btnUpload = findViewById(R.id.btnUploadPhoto); Button btnLogOut = findViewById(R.id.btnLogOut); ProfileImg = findViewById(R.id.profile_img); btnLogOut.setOnClickListener(view -> { FirebaseAuth.getInstance().signOut(); startActivity(new Intent(Profile.this, MainActivity.class) .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP)); finish(); }); ProfileImg.setOnClickListener(view -> { Intent photoIntent = new Intent(Intent.ACTION_PICK); photoIntent.setType("image/*"); NewStartActivityForResult.launch(photoIntent); }); btnUpload.setOnClickListener(view -> { uploadImage(); }); } private final ActivityResultLauncher<Intent> NewStartActivityForResult = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { Intent GotResults = result.getData(); if (GotResults == null) { Log.d(Tag, "Intent data is null"); return; } // 直接给成员变量赋值,不要重新定义局部变量 imageUriPath = GotResults.getData(); GetImageInView(); } }); private void uploadImage() { // 先判断URI是否为空,避免崩溃 if (imageUriPath == null) { Toast.makeText(this, "请先选择图片", Toast.LENGTH_SHORT).show(); return; } FirebaseStorage.getInstance() .getReference("images/" + UUID.randomUUID().toString()) .putFile(imageUriPath) .addOnCompleteListener(task -> { if (task.isSuccessful()) { Toast.makeText(Profile.this, "图片上传成功!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(Profile.this, "上传失败:" + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } }); } private void GetImageInView() { if (imageUriPath == null) return; Bitmap bitmap = null; try { // 用ImageDecoder替代已废弃的MediaStore.getBitmap if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { ImageDecoder.Source source = ImageDecoder.createSource(getContentResolver(), imageUriPath); bitmap = ImageDecoder.decodeBitmap(source); } else { // 兼容Android P以下版本 bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUriPath); } // 将Bitmap设置到ImageView ProfileImg.setImageBitmap(bitmap); } catch (IOException e) { Log.e(Tag, "加载图片失败", e); Toast.makeText(this, "图片加载失败", Toast.LENGTH_SHORT).show(); } } }
关键修改说明
- 变量赋值修复:去掉回调里的局部
imageUriPath定义,直接给成员变量赋值,确保后续方法能拿到正确的URI - 废弃API替换:使用
ImageDecoder替代MediaStore.getBitmap(),同时保留低版本兼容逻辑 - UI绑定:在
GetImageInView()中调用ProfileImg.setImageBitmap(bitmap),把选中的图片显示出来 - 空值判断:在
uploadImage()里先检查URI是否为空,避免上传空值引发崩溃 - Tag初始化:给Tag变量赋值,避免Log打印时的空指针异常
内容的提问来源于stack exchange,提问作者Pavlos Katsioulis
相关产品推荐
相关产品推荐

