監聽 Intent.ACTION_PACKAGE_ADDED 廣播,解析新安裝包信息,發送 INSTALL_SHORTCUT 廣播請求桌面創建快捷方式。
// 1. 清單文件註冊接收器
<receiver android:name=".InstallShortcutReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
// 2. 接收器代碼
public class InstallShortcutReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) return;
String packageName = intent.getData().getSchemeSpecificPart();
if (packageName == null) return;
// 可選:過濾系統應用、無啟動器 Activity 的應用
if (!hasLauncherActivity(context, packageName)) return;
createShortcut(context, packageName);
}
private boolean hasLauncherActivity(Context ctx, String pkg) {
Intent main = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(pkg);
return !ctx.getPackageManager().queryIntentActivities(main, 0).isEmpty();
}
private void createShortcut(Context ctx, String pkg) {
PackageManager pm = ctx.getPackageManager();
ApplicationInfo appInfo;
try {
appInfo = pm.getApplicationInfo(pkg, PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
return;
}
Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, pm.getApplicationLabel(appInfo));
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER).setPackage(pkg));
// 圖標資源
Context pkgCtx = ctx.createPackageContext(pkg, Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
ShortcutIconResource icon = ShortcutIconResource.fromContext(pkgCtx, appInfo.icon);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
ctx.sendBroadcast(shortcut);
}
}
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.BROADCAST_PACKAGE_ADDED" /> <!-- 系統簽名權限,普通應用無法聲明 -->
注意:BROADCAST_PACKAGE_ADDED 為系統簽名權限,**普通 Launcher 應用無法直接接收**。實際開發中通常由**系統預置 Launcher** 或**擁有系統簽名的應用**實現;第三方 Launcher 需輪詢 PackageManager 或用 UsageStatsManager 監控新安裝。
// 定時掃描新安裝包(每小時/每天)
private void scanNewPackages() {
List<PackageInfo> all = pm.getInstalledPackages(0);
for (PackageInfo pi : all) {
if (isNewlyInstalled(pi.packageName) && hasLauncherActivity(pi.packageName)) {
createShortcut(pi.packageName);
markAsProcessed(pi.packageName); // SharedPreferences 記錄
}
}
}
「自動創建快捷方式」核心是
INSTALL_SHORTCUT廣播,**但廣播接收權限限制極大**。第三方 Launcher 采用「定時掃描 + 記錄已處理」是工程上可落地的妥協方案。