首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android Dialog 選擇圖片來源(相冊/相機)的正確顯示邏輯與進度條管理

     編輯:程式設計綜合問答

原代碼問題

  • 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();
}

關鍵修正點

  1. AlertDialog.Builder(...).setItems(...).show() 正確顯示選項對話框。
  2. 進度對話框在 onActivityResult 確認有圖片後再創建並 show()。
  3. 相機拍照使用 FileProvider 獲取 content:// URI,兼容 Android 7.0+。
  4. 上傳耗時操作放入背景線程,UI 更新回主線程。

現代替代:Activity Result API (AndroidX)


// 註冊
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));

簡化請求碼管理,代碼更清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved