AlertDialog 創建後未調用 show(),導致不顯示。dialog 在點擊按鈕**前**就創建並顯示,邏輯倒置。bitmap == null 判斷位置錯誤,應在選擇圖片**後**驗證。
Button uploadBtn = findViewById(R.id.upload);
uploadBtn.setOnClickListener(v -> {
// 1. 顯示來源選擇對話框
new AlertDialog.Builder(this)
.setTitle("選擇圖片來源")
.setItems(new CharSequence[]{"相冊", "相機"}, (dialog, which) -> {
if (which == 0) { // 相冊
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_GALLERY);
} else { // 相機
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 解決 Android 7+ FileUriExposedException
File photoFile = createImageFile();
Uri photoUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CAMERA);
}
})
.show(); // 關鍵:必須 show()
});
// 2. onActivityResult 處理結果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) return;
Uri imageUri;
if (requestCode == REQUEST_GALLERY) {
imageUri = data.getData();
} else if (requestCode == REQUEST_CAMERA) {
imageUri = photoFileUri; // 拍照時保存的 Uri
} else return;
// 3. 顯示上傳進度對話框
ProgressDialog progress = new ProgressDialog(this);
progress.setMessage("上傳中...");
progress.setCancelable(false);
progress.show();
// 4. 異步上傳(示例用線程,實際用 Retrofit/OkHttp)
new Thread(() -> {
try {
// 上傳邏輯...
Thread.sleep(2000); // 模擬
runOnUiThread(() -> {
progress.dismiss();
Toast.makeText(this, "上傳成功", Toast.LENGTH_SHORT).show();
});
} catch (Exception e) {
runOnUiThread(() -> {
progress.dismiss();
Toast.makeText(this, "上傳失敗: " + e.getMessage(), Toast.LENGTH_SHORT).show();
});
}
}).start();
}
AlertDialog.Builder(...).setItems(...).show() 正確顯示選項對話框。onActivityResult 確認有圖片後再創建並 show()。FileProvider 獲取 content:// URI,兼容 Android 7.0+。
// 註冊
ActivityResultLauncher galleryLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK) {
Uri uri = result.getData().getData();
startUpload(uri);
}
});
// 啟動
galleryLauncher.launch(new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
簡化請求碼管理,代碼更清晰。