大家都知道,这个应用随着SIM卡的插入,而在launcher中加载显示,当拔出SIM卡后,消失。过程源码走起。
先在packages/app/Stk 看这个应用中,有广播接收:
public class BootCompletedReceiver extends BroadcastReceiver { private static final String TAG = "APPBootCompletedReceiver"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG,"onReceive action = "+action); // make sure the app icon is removed every time the device boots. if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { if (!android.os.Process.myUserHandle().isOwner()) { //Disable package for all secondary users. Package is only required for device //owner. context.getPackageManager().setApplicationEnabledSetting(context.getPackageName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0); return; } Bundle args = new Bundle(); args.putInt(StkAppService.OPCODE, StkAppService.OP_BOOT_COMPLETED); context.startService(new Intent(context, StkAppService.class) .putExtras(args)); } else if(action.equals(Intent.ACTION_USER_INITIALIZE)) { if (!android.os.Process.myUserHandle().isOwner()) { //Disable package for all secondary users. Package is only required for device //owner. context.getPackageManager().setApplicationEnabledSetting(context.getPackageName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0); return; } } } } 启动service, private void checkAndUnInstallStkApps() { for (int i = 0; i < mSimCount; i++) { if (mStkService[i] == null) { Log.d(TAG, " Unistalling Stk App for slot: " + i); StkAppInstaller.unInstall(mContext, i); } } } 发现uninstall中 pm.setComponentEnabledSetting(cName, state, PackageManager.DONT_KILL_APP);设置不可用,但是不killapp
查看源码,packagemanagerservice.java()
@Override
public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId) { if (!sUserManager.exists(userId)) return; setEnabledSetting(componentName.getPackageName(), componentName.getClassName(), newState, flags, userId, null); }pkgSetting.setEnabled(newState, userId, callingPackage);
设置可用状态
sendPackageChangedBroadcast(packageName, (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 发送系统广播,通知launcher更新(ADD,CHANGE)
StkCmdReceiver 通过SIM卡的状态,设置是否可用,可用就会加载到launcher上,不可用则不显示,但是不killapp,否则状态无法及时更新。
基本流程就是这样,看似神奇的动态加载,竟然是自身应用中的service做的操作,服了。
