แอปพลิเคชันของฉันติดตั้งแอปพลิเคชันอื่นและจำเป็นต้องติดตามแอปพลิเคชันที่ติดตั้งไว้ แน่นอนว่าสามารถทำได้โดยเพียงแค่เก็บรายการแอปพลิเคชั่นที่ติดตั้งไว้ แต่สิ่งนี้ไม่จำเป็น! ควรเป็นความรับผิดชอบของ PackageManager ในการรักษาความสัมพันธ์ที่ติดตั้งโดย (a, b) ในความเป็นจริงตาม API มันคือ:
public abstract String getInstallerPackageName (String packageName) - ดึงชื่อแพ็คเกจของแอปพลิเคชั่นที่ติดตั้งแพ็คเกจ สิ่งนี้บ่งชี้ว่าตลาดบรรจุภัณฑ์มาจากไหน
แนวทางปัจจุบัน
ติดตั้ง APK โดยใช้เจตนา
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
ถอนการติดตั้ง APK โดยใช้เจตนา:
Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package",
getPackageManager().getPackageArchiveInfo(apkUri.getPath(), 0).packageName,null));
startActivity(intent);
เห็นได้ชัดว่านี่ไม่ใช่วิธีการเช่นการติดตั้ง / ถอนการติดตั้งแพคเกจ Android Market พวกเขาใช้ PackageManager เวอร์ชันที่สมบูรณ์ยิ่งขึ้น สิ่งนี้สามารถเห็นได้โดยการดาวน์โหลดซอร์สโค้ด Android จากที่เก็บ Android Git ด้านล่างนี้เป็นวิธีการซ่อนสองวิธีที่สอดคล้องกับวิธีการแสดงเจตจำนง น่าเสียดายที่พวกเขาไม่พร้อมใช้งานสำหรับนักพัฒนาภายนอก แต่บางทีพวกเขาจะเป็นในอนาคต?
แนวทางที่ดีกว่า
การติดตั้ง APK โดยใช้ PackageManager
/**
* @hide
*
* Install a package. Since this may take a little while, the result will
* be posted back to the given observer. An installation will fail if the calling context
* lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
* package named in the package file's manifest is already installed, or if there's no space
* available on the device.
*
* @param packageURI The location of the package file to install. This can be a 'file:' or a
* 'content:' URI.
* @param observer An observer callback to get notified when the package installation is
* complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
* called when that happens. observer may be null to indicate that no callback is desired.
* @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
* {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}.
* @param installerPackageName Optional package name of the application that is performing the
* installation. This identifies which market the package came from.
*/
public abstract void installPackage(
Uri packageURI, IPackageInstallObserver observer, int flags,
String installerPackageName);
ถอนการติดตั้ง APK โดยใช้ PackageManager
/**
* Attempts to delete a package. Since this may take a little while, the result will
* be posted back to the given observer. A deletion will fail if the calling context
* lacks the {@link android.Manifest.permission#DELETE_PACKAGES} permission, if the
* named package cannot be found, or if the named package is a "system package".
* (TODO: include pointer to documentation on "system packages")
*
* @param packageName The name of the package to delete
* @param observer An observer callback to get notified when the package deletion is
* complete. {@link android.content.pm.IPackageDeleteObserver#packageDeleted(boolean)} will be
* called when that happens. observer may be null to indicate that no callback is desired.
* @param flags - possible values: {@link #DONT_DELETE_DATA}
*
* @hide
*/
public abstract void deletePackage(
String packageName, IPackageDeleteObserver observer, int flags);
ความแตกต่าง
เมื่อใช้ intents ตัวจัดการแพ็กเกจในพื้นที่จะไม่รับรู้ถึงแอปพลิเคชันที่ติดตั้งมา getInstallerPackageName (... ) จะส่งกลับค่า null โดยเฉพาะ
เมธอดที่ซ่อนอยู่ installPackage (... ) ใช้ชื่อแพ็กเกจตัวติดตั้งเป็นพารามิเตอร์และน่าจะสามารถตั้งค่านี้ได้
คำถาม
เป็นไปได้หรือไม่ที่จะระบุชื่อตัวติดตั้งแพ็คเกจโดยใช้ intents (อาจจะสามารถเพิ่มชื่อของแพ็คเกจการติดตั้งเป็นสิ่งเพิ่มเติมสำหรับเจตนาการติดตั้งได้หรือไม่)
เคล็ดลับ: หากคุณต้องการดาวน์โหลดซอร์สโค้ด Android คุณสามารถทำตามขั้นตอนที่อธิบายไว้ที่นี่: การดาวน์โหลดทรีซอร์ส เพื่อดึงไฟล์ * .java และใส่ไว้ในโฟลเดอร์ตามลำดับชั้นของแพคเกจที่คุณสามารถตรวจสอบสคริปต์เรียบร้อยนี้: ดู Android รหัสที่มาใน Eclipse