ด้วยความที่แอนดรอยด์เป็นระบบปฏิบัติการณ์แบบเปิด จึงทำให้การติดตั้งแอปลงในเครื่องสามารถทำได้หลายวิธี และในบางครั้งนักพัฒนาแอปอย่างเราก็ต้องการเช็คว่าแอปถูกติดตั้งมาจากที่ใดหรือติดตั้งด้วยวิธีไหน
เพราะเวลาติดตั้งแอปลงในอุปกรณ์แอนดรอยด์ (ยกเว้นการติดตั้งผ่าน ADB หรือ Recovery Mode) จะต้องติดตั้งผ่านแอปตัวใดตัวหนึ่งเสมอ ซึ่งจะเรียกแอปดังกล่าวว่า Installer และนอกจากนี้ในอุปกรณ์แอนดรอยด์ก็จะมีแอปที่เรียกว่า Package Installer ติดตั้งอยู่ด้วย เพื่อรองรับการติดตั้งผ่าน Sideload
วิธีตรวจสอบ
โดย Package Name จะมีคำสั่งดังกล่าวให้ใช้งานอยู่ โดยที่ Android 11 (API Level 30) จะต้องใช้คำสั่ง getInstallSourceInfo
ส่วนเวอร์ชันที่ต่ำกว่านั้นให้ใช้ getInstallerPackageName
แทน และกำหนด Package Name ที่ต้องการตรวจสอบได้เลย
val packageManager: PackageManager = /* ... */
val installerPackageName = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
packageManager.getInstallSourceInfo(packageName).installingPackageName
} else {
packageManager.getInstallerPackageName(packageName)
}
ผลลัพท์ที่ได้หรือ installerPackageName
จะเป็นไปตามนี้
com.android.vending
- ติดตั้งผ่าน Google Playcom.huawei.appmarket
- ติดตั้งผ่าน Huawei AppGallerycom.amazon.venezia
- ติดตั้งผ่าน Amazon Appstorecom.sec.android.app.samsungapps
- ติดตั้งผ่าน Galaxy Store ของ Samsungcom.heytap.market
- ติดตั้งผ่าน App Market ของ HeyTapcom.vivo.appstore
- ติดตั้งผ่าน V-Appstore ของ VIVOcom.xiaomi.market
- ติดตั้งผ่าน Xiaomi Marketcom.apkpure.aegon
- ติดตั้งผ่าน APKPurecom.google.android.packageinstaller
- ติดตั้งผ่าน Sideload ไม่ว่าจะโหลดไฟล์ APK จาก Google Chrome หรือติดตั้งผ่าน Firebase App Distribution ก็ตามnull
- ไม่ทราบแหล่งที่มา อาจจะ Pre-install อยู่ในเครื่องตั้งแต่แรกหรือติดตั้งผ่าน ADB
คำสั่งเพิ่มเติมสำหรับ Android 13 (API Level 33)
เพราะคำสั่ง getInstallSourceInfo
ให้ผลลัพธ์ออกมาเป็น InstallSourceInfo จึงทำให้นักพัฒนาสามารถเช็คข้อมูลผ่านคำสั่งอื่น ๆ ในคลาสดังกล่าวนอกเหนือจาก installingPackageName
ได้ด้วย และหนึ่งในนั้นก็คือค่าที่เรียกว่า packageSource
// API level 33 only
val packageName: String = /* ... */
val packageManager: PackageManager = /* ... */
val info: InstallSourceInfo = packageManager.getInstallSourceInfo(packageName)
val source: Int = source.packageSource
สำหรับ source
จะเป็นค่า Integer ที่ Installer จะกำหนดไว้ในระหว่างทำการติดตั้งแอปให้ (อาจจะไม่ได้กำหนดค่านี้ก็ได้) โดยค่าที่เป็นไปได้จะมีดังนี้
PACKAGE_SOURCE_UNSPECIFIED
(0) - Installer ไม่ได้กำหนดค่าPACKAGE_SOURCE_OTHER
(1) - ไม่สามารถระบุที่มาของ Installer ได้PACKAGE_SOURCE_STORE
(2) - ติดตั้งผ่าน Android App StorePACKAGE_SOURCE_LOCAL_FILE
(3) - ติดตั้งจากไฟล์ในเครื่อง เช่น ติดตั้งผ่าน File ManagerPACKAGE_SOURCE_DOWNLOADED_FILE
(4) - ติดตั้งจากไฟล์ที่ได้มาจากการดาวน์โหลด ในกรณีที่ File Manager รู้ว่าไฟล์ได้มาจากการดาวน์โหลดก็จะได้เป็นค่านี้แทน
และจากการทดสอบบน Google Pixel 4 (Android 13) ได้ผลลัพธ์ดังนี้
- ติดตั้งผ่าน Google Play ได้เป็น
PACKAGE_SOURCE_UNSPECIFIED
- ติดตั้งผ่าน Google Chrome ได้เป็น
PACKAGE_SOURCE_DOWNLOADED_FILE
- ติดตั้งผ่าน Firebase App Distribution ได้เป็น
PACKAGE_SOURCE_LOCAL_FILE
- ติดตั้งผ่าน ADB ได้เป็น
PACKAGE_SOURCE_UNSPECIFIED
- ติดมากับเครื่องตั้งแต่แรก ได้เป็น
PACKAGE_SOURCE_UNSPECIFIED
จะเห็นว่าการติดตั้งผ่าน Google Play ที่ควรจะได้ PACKAGE_SOURCE_STORE
แต่กลับได้ PACKAGE_SOURCE_UNSPECIFIED
แทน