您的位置:首页 > 移动开发 > Android开发

Android中如何禁用其他应用,并且不在桌面显示

2016-02-16 14:32 731 查看

1.首先需要系统签名。

2.达到的效果:

应用被禁用后,图标也从桌面上消失。

3.参考Settings源码,最终实现的代码如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testdiableapp"
android:versionCode="1"
android:sharedUserId="android.uid.system"
android:versionName="1.0" >

<permission
android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
android:protectionLevel="signatureOrSystem"/>
........


public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}

private void init(){
Button bt  = (Button)findViewById(R.id.dis);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
EditText text = (EditText)findViewById(R.id.input);
String packageName = text.getText().toString();
PackageManager pm = getPackageManager();
pm.setApplicationEnabledSetting(packageName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);
}
});

Button en  = (Button)findViewById(R.id.en);
en.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
EditText text = (EditText)findViewById(R.id.input);
String packageName = text.getText().toString();
PackageManager pm = getPackageManager();
pm.setApplicationEnabledSetting(packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
}
});
}

}


4.Settings中的源码分析:



从这段代码可以看出,进入设置的App管理中,如果是system app,就会显示“DISABLE“,非system app,则会显示“UNINSTALL“。

如下图:



当点击DISABLE之后,弹出对话框确认是否执行DISABLE动作:

case DLG_DISABLE:
return new AlertDialog.Builder(getActivity())
.setTitle(getActivity().getText(R.string.app_disable_dlg_title))
.setMessage(getActivity().getText(R.string.app_disable_dlg_text))
.setPositiveButton(R.string.dlg_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Disable the app
new DisableChanger(getOwner(), getOwner().mAppEntry.info,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
.execute((Object)null);
}
})
.setNegativeButton(R.string.dlg_cancel, null)
.create();


点击确认执行:

static class DisableChanger extends AsyncTask<Object, Object, Object> {
final PackageManager mPm;
final WeakReference<InstalledAppDetails> mActivity;
final ApplicationInfo mInfo;
final int mState;

DisableChanger(InstalledAppDetails activity, ApplicationInfo info, int state) {
mPm = activity.mPm;
mActivity = new WeakReference<InstalledAppDetails>(activity);
mInfo = info;
mState = state;
}

@Override
protected Object doInBackground(Object... params) {
mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0);
return null;
}
}


调用PackageManager的setApplicationEnabledSetting()最终会进入到PackageManagerService的setEnabledSetting()函数:



在这个函数中会检查APP是否有android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE权限。

而这个权限是只有system app才能使用的,这也是为什么APP需要系统签名。(非system app即便在AndroidManifest.xml中强制写上,安装时也不会写入/data/system/packages.xml

安装后package.xml中的内容:

<package name="com.example.testdiableapp" codePath="/system/app/TestDisable.apk"
 nativeLibraryPath="/data/data/com.example.testdiableapp/lib" flags="1"
 ft="152e863d9e0" it="152e8a98806" ut="152e8a98806" version="1" sharedUserId="1000">
<sigs count="1">
<cert index="1" />
</sigs>
</package>

5.最后的效果图:

以禁用联系人(com.android.contacts)这个APP来Demo:

禁用前:





在Demo中输入要被com.android.contacts:



禁用后联系人图标已经消失了:





测试在4.0.3 -> 6.0.1 上运行没有问题。

其余版本没有测试过。


Demo App下载地址:http://download.csdn.net/detail/xxooyc/9433068
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: