Android实现多个apk文件安装

来源:互联网 发布:oppor9root软件 编辑:程序博客网 时间:2024/05/22 01:36

有时一个大项目可能需要多个功能app,在安装或者升级时如果需要分别安装升级显得比较繁琐,如果能把多个app放在一个Install.apk里面统一升级就显得比较方便了,也可以有选择的升级部分app;

首先,将小模块生成的apk放到项目的assets文件夹中

 

java代码:

package com.example.comminstall;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener{private Button mInstall_1, mInstall_2; ArrayList<String> packagNameList; private MyReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//定义两个按钮以便能直观的看到安装过程及效果 mInstall_1 = (Button) findViewById(R.id.id_button_install_01);        mInstall_2 = (Button) findViewById(R.id.id_button_install_02);                mInstall_1.setOnClickListener(this);        mInstall_2.setOnClickListener(this);initpackagNameList();// 监听系统新安装程序的广播  receiver = new MyReceiver();  IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);// 注册广播机制  filter.addDataScheme("package"); // 必须添加这项,否则拦截不到广播  registerReceiver(receiver, filter);// 注册广播机制}@Overridepublic void onClick(View v) {Intent intent = null;switch (v.getId()) {case R.id.id_button_install_01:if (detectApk("com.example.install_01")) {//安装过,直接启动intent = new Intent();ComponentName comName = new ComponentName("com.example.install_01","com.example.install_01.MainActivity");intent.setComponent(comName);startActivity(intent);}else {//未安装过,先安装File fileDir = getFilesDir();final String cachePath = fileDir.getAbsolutePath()+"/install_01.apk";retrieveApkFromAssets(this, "install_01.apk", cachePath);installConfirm(this, cachePath);//普通安装}break;case R.id.id_button_install_02:if (detectApk("com.example.install_02")) {//安装过,直接启动// 组件名称,第一个参数是包名,也是主配置文件Manifest里设置好的包名 第二个是类名,要带上包名intent = new Intent().setComponent(new ComponentName("com.example.install_02", "com.example.install_02.MainActivity"));startActivity(intent);}else {//未安装过,先安装File fileDir = getFilesDir();final String cachePath = fileDir.getAbsolutePath()+"/install_02.apk";retrieveApkFromAssets(this, "install_02.apk", cachePath);installConfirm(this, cachePath);//普通安装}break;default:break;}}// 捆绑安装public boolean retrieveApkFromAssets(Context context, String fileName,String path) {boolean bRet = false;try {File file = new File(path);//新建文件if (file.exists()) {//如果存在则返回return true;} else {file.createNewFile();InputStream is = context.getAssets().open(fileName);FileOutputStream fos = new FileOutputStream(file);byte[] temp = new byte[1024];int i = 0;while ((i = is.read(temp)) != -1) {fos.write(temp, 0, i);//向缓冲区写数据}fos.flush();//强制刷新缓冲区,输出fos.close();//关闭输出流is.close();//关闭输入流bRet = true;}} catch (IOException e) {Toast.makeText(context, e.getMessage(), 2000).show();e.printStackTrace();}return bRet;}public void installConfirm(final Context context, final String filePath) {// 修改apk权限try {String command = "chmod 777" + " " + filePath;Runtime runtime = Runtime.getRuntime();runtime.exec(command);//以管理员身份运行修改apk权限命令} catch (IOException e) {e.printStackTrace();}// install the apk.//普通模式安装,调用系统IntentIntent intent = new Intent(Intent.ACTION_VIEW);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//将一个新的view置于台前intent.setDataAndType(Uri.parse("file://" + filePath),"application/vnd.android.package-archive");//打开apk格式的文件context.startActivity(intent);}/**  * 检测是否已经安装  *   * @param packageName  * @return true已安装 false未安装  */ private boolean detectApk(String packageName) { return this.packagNameList.contains(packageName.toLowerCase()); } private void initpackagNameList() {// 初始化小模块列表packagNameList = new ArrayList<String>();PackageManager manager = this.getPackageManager();List<PackageInfo> pkgList = manager.getInstalledPackages(0);for (int i = 0; i < pkgList.size(); i++) {PackageInfo pI = pkgList.get(i);packagNameList.add(pI.packageName.toLowerCase());}}/**  *   * 设置广播监听  *   */private class MyReceiver extends BroadcastReceiver {public void onReceive(Context context, Intent intent) {if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {System.out.println("getDataString = "+intent.getDataString());String packName = intent.getDataString().substring(8); Log.e(intent.getDataString() + "====", packName);// packName为所安装的程序的包名 packagNameList.add(packName.toLowerCase());// 删除file目录下的所有以安装的apk文件File file = getFilesDir();File[] files = file.listFiles();for (File f : files) {if (f.getName().endsWith(".apk")) {f.delete();}}}}}}

在主页面设置了两个按钮在此不再列出

在AndroidManifest.xml中别忘了设置android:sharedUserId="android.uid.system"以获得系统权限,但是在安装的时候需要根据目标系统进行重新签名,否则可能安装不成功;
0 0
原创粉丝点击