Android系统 实现静默安装
Android实现静默安装需要用到一些隐藏的api接口,第三方apk无法直接调用其接口。所以实现这个功能需要编写到然后去系统中编译生成apk。这里记录下自己实现的静默安装功能的代码。
主要代码:
public class InstallPackageActivity extends AppCompatActivity {
private String APK_NAME = "TencentVideo.apk";
private String mAutoStartPackageName;
private int INSTALL_COMPLETE = 1;
private Button click;
private Context mContext = InstallPackageActivity.this;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
if (msg.arg1 == 1) {
Toast.makeText(getApplicationContext(), "安装成功", Toast.LENGTH_SHORT).show();
Log.i("liu", "Installation success!");
changeButtonState(true);
} else {
Toast.makeText(getApplicationContext(), "安装失败", Toast.LENGTH_SHORT).show();
Log.i("liu", "Installation failure!");
click.setEnabled(true);
click.setText(mContext.getResources().getString(R.string.button_silent_install_app_fail));
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_install_package);
click = (Button) this.findViewById(R.id.click);
click.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
installApp();
changeButtonState(false);
}
});
}
private void installApp() {
String fileName = Environment.getExternalStorageDirectory() + "/" + APK_NAME;
if (!new File(fileName).exists()) {
Log.e("liu", "file name is not exists!");
return;
}
String packageName;
int installFlags = 0;
Uri uri = Uri.fromFile(new File(fileName));
PackageManager pm = getPackageManager();
PackageInfo info = pm.getPackageArchiveInfo(fileName, PackageManager.GET_ACTIVITIES);
if (info != null) {
packageName = info.applicationInfo.packageName;
Log.i("liu", "packageName -> " + packageName);
try {
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
Log.i("liu", "packageInfo -> " + packageInfo);
if (packageInfo != null) {
installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
mAutoStartPackageName = packageName;
PackageInstallObserver observer = new PackageInstallObserver();
pm.installPackage(uri, observer, installFlags, mAutoStartPackageName);
}
}
private void changeButtonState(boolean isEnable) {
click.setEnabled(isEnable);
if (isEnable) {
click.setText(mContext.getResources().getString(R.string.button_silent_install_app_complete));
} else {
click.setText(mContext.getResources().getString(R.string.button_silent_installing_app));
}
}
class PackageInstallObserver extends IPackageInstallObserver.Stub {
public void packageInstalled(String packageName, int returnCode) {
Log.i("liu", "send message to main thread!");
Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
msg.arg1 = returnCode;
mHandler.sendMessage(msg);
}
}
}
上面的代码看情况复制进去即可使用,主要的安装在installApp()方法中,安装完成之后会调用packageInstalled方法,returnCode返回1表示安装成功。
添加权限
需要添加如下权限
<!-- 安装app需要的权限 -->
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
编写Android.mk文件
上面的代码编写完成之后,在系统中编译还需要编写Android.mk文件。
源码下载地址:https://download.csdn.net/download/qq_33088619/10996981
最终的代码结构如图
把当前整个工程放到源码的package/app目录下,然后cd android/package/app/SlientInstall目录,然后mm即可编译成apk,目前我只在6.0,7.1,8.1的系统上尝试过。