本頁面說明在 Android 平台上測試多位使用者的重點。如要瞭解如何實作多使用者支援功能,請參閱「支援多位使用者」。
裝置路徑
下表列出幾個裝置路徑,以及如何解決這些路徑。「Path」欄中的所有值都是特定使用者的沙箱儲存空間。Android 的儲存空間功能隨著時間而變化,詳情請參閱「儲存空間」說明文件。
路徑 | 系統路徑 (選用) | 目的 |
---|---|---|
/data/user/{userId}/{app.path}
|
/data/data
|
應用程式儲存空間 |
/storage/emulated/{userId}
|
/sdcard
|
共用內部儲存空間 |
/data/media/{userId}
|
無 | 使用者媒體資料 (例如音樂、影片) |
/data/system/users/{userId}
|
無 | 每位使用者的系統設定/狀態 僅供系統應用程式存取 |
以下是使用特定使用者路徑的範例:
# to access user 10's private application data for app com.bar.foo:
$ adb shell ls /data/user/10/com.bar.foo/
跨使用者 adb 互動
在處理多位使用者時,您可以使用多個 adb
指令。部分指令僅適用於 Android 9 以上版本:
adb shell am instrument --user <userId>
會針對特定使用者執行檢測設備測試。根據預設,這會使用目前的使用者。adb install --user <userId>
會為特定使用者安裝套件。為確保所有使用者都能安裝套件,您必須為每位使用者呼叫這個方法。adb uninstall --user <userId>
會為特定使用者解除安裝套件。呼叫不含--user
旗標,為所有使用者解除安裝。adb shell am get-current-user
會取得目前 (前景) 使用者 ID。adb shell pm list users
會取得所有現有使用者的清單。adb shell pm create-user
會建立新使用者,並傳回 ID。adb shell pm remove-user
會根據 ID 移除特定使用者。adb shell pm disable --user <userId>
會為特定使用者停用套件。adb shell pm enable --user <userId>
可為特定使用者啟用套件。adb shell pm list packages --user <userId>
會列出特定使用者的套件 (-e
為啟用,-d
為停用狀態)。根據預設,這項設定一律會列出系統使用者。
下列資訊可協助您瞭解 adb
在多位使用者情況下的行為:
adb
(或更準確的adbd
Daemon) 一律會以「系統使用者」 (使用者 ID = 0) 執行,無論目前的使用者目前為哪個使用者。因此,依賴使用者的裝置路徑 (例如/sdcard/
) 一律會解析為系統使用者。詳情請參閱「裝置路徑」。如果未指定預設使用者,每個
adb
子命令都會使用不同的使用者。最佳做法是使用am get-current-user
擷取使用者 ID,然後針對任何支援--user <userId>
的指令明確使用--user <userId>
。在 Android 9 之前,所有指令都未支援明確的使用者標記。從 Android 9 開始,系統將拒絕存取次要使用者的
/sdcard
路徑。如要進一步瞭解如何在測試期間擷取檔案,請參閱「多使用者資料的內容供應器」。
多用戶資料的內容供應器
由於 adb
會以系統使用者的身分執行,且資料會在 Android 9 以上版本中進行沙箱處理,因此您必須使用內容供應器,才能從非系統使用者推送或提取任何測試資料。如果符合下列情況,則不必執行這項操作:
adbd
是以根使用者的身分執行 (透過adb root
),這項操作只能使用userdebug
或usereng
版本。您使用 Trade Federation (Tradefed) 的
ITestDevice
來推送或拉取檔案,在這種情況下,請在測試設定中使用/sdcard/
路徑 (例如,請參閱NativeDevice.java
中的pushFile
原始碼)。
當內容供應器在次要使用者中執行時,您可以使用 adb shell content
指令搭配指定的適當 user
、uri
和其他參數存取內容供應器。
應用程式開發人員可採取的解決方法
請使用 adb content
和 ContentProvider
的例項,而非 push
或 pull
指令,與測試檔案互動。
- 建立應用程式代管的
ContentProvider
例項,以便在需要時提供及儲存檔案。使用應用程式的內部儲存空間。 - 使用
adb shell content
read
或write
指令推送或提取檔案。
媒體檔案的解決方法
如要將媒體檔案推送至 SD 卡的媒體分區,請使用 MediaStore
公用 API。例如:
# push MVIMG_20190129_142956.jpg to /storage/emulated/10/Pictures
# step 1
$ adb shell content insert --user 10 --uri content://media/external/images/media/ --bind _display_name:s:foo.jpg
# step 2
$ adb shell content query --user 10 --projection _id --uri content://media/external/images/media/ --where "_display_name=\'foo.jpg\'"
# step 3
$ adb shell content write --user 10 --uri content://media/external/images/media/8022 < MVIMG_20190129_142956.jpg
安裝一般內容供應器
安裝並使用現有的內容供應器,讀取及寫入檔案至特定使用者的 /sdcard
路徑。
使用 make TradefedContentProvider
從來源建構 TradefedContentProvider.apk
:
```
# install content provider apk
$ adb install --user 10 -g TradefedContentProvider.apk
# pull some_file.txt
$ adb shell content read --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt > local_file.txt
# push local_file.txt
$ adb shell content write --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt < local_file.txt
```
Trade Federation 多使用者支援
Tradefed 是 Android 官方測試控管工具。本節將概述 Tradefed 針對多使用者測試情境提供的部分內建支援功能。
狀態檢查器
系統狀態檢查器 (SSC) 會在目標預備程序執行前執行,並在這些預備程序執行後執行清理作業。
明確定義 UserChecker
以在測試多位使用者時協助開發人員。這項測試會追蹤測試是否已變更裝置上的使用者狀態 (例如,在解構時建立使用者,但未將其移除)。此外,如果已設定 user-cleanup
,系統會在測試後自動嘗試清理,同時提供實用的錯誤訊息,以便修正測試。
<system_checker class="com.android.tradefed.suite.checker.UserChecker" >
<option name="user-cleanup" value="true" />
</system_checker>
目標準備者
目標準備工具通常用於設定具有特定設定的裝置。在多使用者測試的情況下,準備工具可用於建立特定類型的使用者,以及切換至其他使用者。
對於沒有次要使用者的裝置類型,您可以使用 CreateUserPreparer
在 AndroidTest.xml
中建立「並切換」至次要使用者。測試結束後,準備者會切換回並刪除次要使用者。
<target_preparer
class="com.google.android.tradefed.targetprep.CreateUserPreparer" >
</target_preparer>
如果裝置上已有您要的使用者類型,請使用 SwitchUserTargetPreparer
切換至現有的使用者。user-type
的常見值包括 system
或 secondary
。
<target_preparer
class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
<option name="user-type" value="secondary" />
</target_preparer>
主機導向測試
在某些情況下,測試必須在測試中切換使用者。請勿在裝置端測試架構 (例如 UI Automator) 中進行切換,因為測試程序隨時可能會遭到終止。請改用主機端測試架構,例如 Tradefed 的主機導向測試架構,這樣就能存取 ITestDevice
,並允許任何必要的使用者操作。
針對會變更使用者狀態的主控測試,請使用 UserChecker
(請參閱「狀態檢查器」),確保測試在執行後能妥善清理。