---
# System prepended metadata

title: '[Video Note] [Android] Philipp Lackner - THIS Is How You Use the New Android 13 Photo Picker'
tags: [Android, Video Note]

---

### Android 13 Photo Picker 介紹與相容性  
- Android 13 提供新的 Photo Picker，可選單張或多張照片  
- 向下相容至 Android 11 或 10，舊裝置會使用傳統相簿選取器  
- 使用者體驗佳，以底部抽屜方式顯示選取器  

---

### 設定 Android Studio 專案  
![image](https://hackmd.io/_uploads/rkwyCjr1xg.png)
![image](https://hackmd.io/_uploads/S13yAjBJxx.png)

- compileSdk 和 targetSdk 設為 33  
- activity-compose 升級至 1.6.1 以上  
- 加入 coil-compose 依賴顯示圖片  

---

### 建立基本 UI 結構  
- 使用 LazyColumn 作為主要容器  
- 兩個按鈕放在 Row 中，分別為選取單張與多張圖片  
- 單張圖片用 AsyncImage 顯示 selectedImageUri  
- 多張圖片使用 items 逐一顯示 selectedImageUris  

---

### 定義狀態管理  
![image](https://hackmd.io/_uploads/SJ9zCiBJel.png)

- 使用 remember 和 mutableStateOf 定義 selectedImageUri 和 selectedImageUris  
- selectedImageUri 初始為 null  
- selectedImageUris 初始為空清單  

---

### 設定 Activity Result Launcher  
![image](https://hackmd.io/_uploads/HJln0oB1gx.png)

- 使用 rememberLauncherForActivityResult 建立 launcher  
- 單張圖片使用 PickVisualMedia contract  
- 多張圖片使用 PickMultipleVisualMedia contract  
- onResult 中更新對應狀態  

---

### 按鈕點擊事件與啟動選取器  
![image](https://hackmd.io/_uploads/HkrzyhSJxg.png)

- 點擊「選取一張圖片」呼叫單張圖片 launcher  
- 點擊「選取多張圖片」呼叫多張圖片 launcher  
- 建立 PickVisualMediaRequest 並設為 ImageOnly  

---

### 運作結果與預期效果  
- 點擊按鈕後開啟 Photo Picker UI  
- 選取圖片後自動載入畫面  
- 舊版 Android 自動回退使用傳統選取器  
 

### Terminology
- **Activity Result API**：用於啟動外部活動並接收回傳結果的新方法，取代舊版的 `startActivityForResult`。
- **Launcher**：一個可記住的變數，用來觸發並處理特定的活動結果。
- **rememberLauncherForActivityResult**：Jetpack Compose 中記住一個可重複使用的活動結果啟動器的方法。
- **ActivityResultContracts**：Android 提供的一組標準合約，用於定義活動結果的輸入與輸出格式。
- **PickVisualMedia**：一種合約，用於選擇單一媒體檔案（如圖片或影片）。
- **PickMultipleVisualMedia**：一種合約，用於選擇多個媒體檔案。
- **URI (Uniform Resource Identifier)**：一種識別資源位置的通用格式，用於標示媒體檔案。
- **MutableState**：Jetpack Compose 的一種狀態容器，用於追蹤可變值的變化。
- **remember**：在 Compose 中用於記憶變數，以避免重新組成時被重設。
- **LazyColumn**：Compose 中一種延遲渲染的垂直列表組件。
- **Row**：Compose 中的水平排列容器。
- **Button**：基本的點擊式元件，可觸發特定動作。
- **Modifier**：Compose 中用來調整 UI 元件外觀與行為的屬性集合。
- **fillMaxSize**：使元件填滿父容器的尺寸。
- **fillMaxWidth**：使元件填滿父容器的寬度。
- **horizontalArrangement**：設定 Row 中子項目的水平排列方式。
- **Arrangement.SpaceAround**：子項目均勻分布於容器內並在邊緣留白。
- **Text**：用於顯示文字的 Compose 元件。
- **AsyncImage**：由 Coil Compose 提供的非同步圖片載入元件。
- **Coil**：一個 Android 的圖片載入庫，支援 Jetpack Compose。
- **contentDescription**：提供給輔助工具（如螢幕閱讀器）的描述文字。
- **ContentScale.Crop**：圖片會裁剪以填滿容器，並保持原有比例。
- **items**：LazyColumn 中用於顯示清單資料的方法。
- **mutableStateOf**：用來建立可觀察的狀態。
- **nullable**：表示該變數可以為 null。
- **emptyList**：代表空的資料清單。
- **onClick**：當使用者點擊元件時所觸發的事件。
- **launch**：啟動指定的活動結果合約。
- **PickVisualMediaRequest**：用於設定媒體挑選行為的請求物件。
- **VisualMediaType.ImageOnly**：只允許挑選圖片的選項。
- **State hoisting**：將狀態提取到更高階元件中，以便在多個元件間共享。
- **Composable function**：可組成的 UI 函式，是 Compose UI 的基本構建單位。
- **Scaffold**：Compose 中常用的頁面結構容器。
- **Preview**：在 IDE 中預覽 Compose UI 的註解。
- **@Composable**：標記一個函式為可組成函式。
- **@OptIn**：允許使用實驗性 API 的註解。
- **rememberSaveable**：在組成期間與組件重組後保留狀態。
- **mutableStateListOf**：一種支援觀察與更新的列表狀態。
- **CoroutineScope**：用於啟動與管理協程的作用域。
- **launchInComposition**：在組成階段啟動協程的方法。
- **AmbientContext**：提供當前上下文的 Compose 屬性。
- **Intent**：用來在元件間傳遞資料與操作的訊息機制。
- **ContentResolver**：用來存取資料 URI 的系統介面。
- **BitmapFactory**：用來將檔案解碼為 Bitmap 的工具類。
- **ImageDecoder**：較新的 Android 圖像解碼方式。
- **MediaStore**：Android 中統一管理媒體檔案的資料庫。
- **FileProvider**：安全地將檔案 URI 傳遞給其他應用的機制。
- **File.createTempFile**：建立臨時檔案的方法。
- **Intent.ACTION_PICK**：舊方法用來選擇媒體檔案的 Intent 動作。
- **startActivityForResult**：已淘汰的活動結果 API。
- **onActivityResult**：處理 startActivityForResult 回傳結果的舊方法。
- **FileOutputStream**：將資料寫入檔案的輸出串流。
- **Bitmap.compress**：將 Bitmap 壓縮並輸出為檔案或串流的方法。
- **MediaType**：媒體檔案的格式類型（如 image/jpeg）。
- **Handler**：用來執行延遲或排程任務的類別。
- **postDelayed**：延遲執行某個任務的方法。
- **Glide**：另一種常用的圖片載入庫，與 Coil 作用類似。