Android中软件的静默安装,安装完成后再自动打开新安装软件(需Root)
2017-08-22 22:41
741 查看
编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/77488832
Demo下载请移步:http://download.csdn.net/download/zxc514257857/9945636
因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!
前言
需要获取Root权限,安装过程完全静默实现,注册安装、卸载、升级的广播,安装完成后自动打开新安装的软件全部代码
// AndroidManifest中权限配置 <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.RESTART_PACKAGES" /> <uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions" /> ---------------------------------------------------------------------------------------- // AndroidManifest中静态注册广播 <receiver android:name=".SilenceInstallReceiver"> <intent-filter> <action android:name="android.intent.action.PACKAGE_REPLACED"/> <action android:name="android.intent.action.PACKAGE_ADDED" /> <action android:name="android.intent.action.PACKAGE_REMOVED" /> <data android:scheme="package"/> </intent-filter> </receiver> ---------------------------------------------------------------------------------------- // MainActivity import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.net.Uri; import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private String tempPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp.apk"; private PackageInfo mPackageInfo; private Context mContext = MainActivity.this; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(RootUtils.isRooted()) { // 从assets目录中获取apk并安装 installFromAssets(); } } /** * 从assets目录中获取并安装 */ public void installFromAssets(){ try { // 根据包名判断是否安装 如果未找到包名说明包名输入错误或未安装 // 想要安装的apk的名字是testapk,其包名为com.testapk.apk mPackageInfo = getPackageManager().getPackageInfo("com.test.testapk", 0); } catch (Exception e) { mPackageInfo = null; e.printStackTrace(); } if (mPackageInfo == null) { // 启用安装新线程 new Thread(new Runnable() { @Override public void run() { Log.i(TAG , "未安装进行安装"); // 静默安装(安装其他软件或自己的升级版 无界面显示) 并启动 slientInstall(); } }).start(); } else { Log.i(TAG , "已经安装"); } } /** * 静默安装 并启动 * * @return */ public boolean slientInstall() { // 进行资源的转移 将assets下的文件转移到可读写文件目录下 createFile(); File file = new File(tempPath); boolean result = false; Process process = null; OutputStream out = null; Log.i(TAG , "file.getPath():" + file.getPath()); if (file.exists()) { System.out.println(file.getPath() + "=="); try { process = Runtime.getRuntime().exec("su"); out = process.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(out); // 获取文件所有权限 dataOutputStream.writeBytes("chmod 777 " + file.getPath() + "\n"); // 进行静默安装命令 dataOutputStream .writeBytes("LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install -r " + file.getPath()); dataOutputStream.flush(); // 关闭流操作 dataOutputStream.close(); out.close(); int value = process.waitFor(); // 代表成功 if (value == 0) { Log.i(TAG , "安装成功!"); result = true; // 失败 } else if (value == 1) { Log.i(TAG , "安装失败!"); result = false; // 未知情况 } else { Log.i(TAG , "未知情况!"); result = false; } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } if (!result) { Log.i(TAG , "root权限获取失败,将进行普通安装"); normalInstall(mContext); result = true; } } return result; } /** * 进行资源的转移 将assets下的文件转移到可读写文件目录下 */ public void createFile() { InputStream is = null; FileOutputStream fos = null; try { // 从assets文件夹中获取testapk.apk文件 is = getAssets().open("testapk.apk"); File file = new File(tempPath); file.createNewFile(); fos = new FileOutputStream(file); byte[] temp = new byte[1024]; int i = 0; while ((i = is.read(temp)) > 0) { fos.write(temp, 0, i); } } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 传统安装 * * @param context */ public void normalInstall(Context context) { // 进行资源的转移 将assets下的文件转移到可读写文件目录下 createFile(); File file = new File(tempPath); Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(android.content.Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); context.startActivity(intent); startApp(mContext); } /** * 安装后自启动apk * * @param context */ private static void startApp(Context context) { execRootShellCmd("am start -S " + context.getPackageName() + "/" + MainActivity.class.getCanonicalName() + " \n"); } /** * 执行shell命令 * * @param cmds * @return */ private static boolean execRootShellCmd(String... cmds) { if (cmds == null || cmds.length == 0) { return false; } DataOutputStream dos = null; InputStream dis = null; Process p = null; try { p = Runtime.getRuntime().exec("su");// 经过Root处理的android系统即有su命令 dos = new DataOutputStream(p.getOutputStream()); for (int i = 0; i < cmds.length; i++) { dos.writeBytes(cmds[i] + " \n"); } dos.writeBytes("exit \n"); int code = p.waitFor(); return code == 0; } catch (Exception e) { e.printStackTrace(); } finally { try { if (dos != null) { dos.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (dis != null) { dis.close(); } } catch (Exception e2) { e2.printStackTrace(); } try { if (p != null) { p.destroy(); p = null; } } catch (Exception e3) { e3.printStackTrace(); } } return false; } } ---------------------------------------------------------------------------------------- // SilenceInstallReceiver import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class SilenceInstallReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")){ String packageName = intent.getDataString(); System.out.println("升级了:" + packageName + "包名的程序"); // startApp(context); } // 接收安装广播 if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) { String packageName = intent.getDataString(); System.out.println("安装了:" +packageName + "包名的程序"); // 监测到升级后执行app的启动 只能启动自身 一般用于软件更新 startApp(context); } //接收卸载广播 if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) { String packageName = intent.getDataString(); System.out.println("卸载了:" + packageName + "包名的程序"); } } /** * 监测到升级后执行app的启动 */ public void startApp(Context context){ // 根据包名打开安装的apk Intent resolveIntent = context.getPackageManager().getLaunchIntentForPackage("com.test.testapk"); context.startActivity(resolveIntent); // 打开自身 一般用于软件升级 // Intent intent = new Intent(context, MainActivity.class); // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // context.startActivity(intent); } } ---------------------------------------------------------------------------------------- // RootUtil import android.util.Log; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; public class RootUtils { public static final String TAG = "RootUtils"; @Deprecated public static boolean isRooted() { Process process = null; try { process = Runtime.getRuntime().exec("su"); OutputStream outputStream = process.getOutputStream(); InputStream inputStream = process.getInputStream(); outputStream.write("id\n".getBytes()); outputStream.flush(); outputStream.write("exit\n".getBytes()); outputStream.flush(); process.waitFor(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine(); if (s.contains("uid=0")) return true; } catch (IOException e) { Log.e(TAG, "没有root权限"); } catch (InterruptedException e) { e.printStackTrace(); } finally { if (process != null) process.destroy(); } return false; } public static boolean checkRooted() { boolean result = false; try { result = new File("/system/bin/su").exists() || new File("/system/xbin/su").exists(); } catch (Exception e) { e.printStackTrace(); } return result; } }
Demo下载请移步:http://download.csdn.net/download/zxc514257857/9945636
因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!
相关文章推荐
- Android在一个app中实现另一个app的自动安装,安装完成后自动打开(需Root)
- android端升级下载后如何自动安装并且有提示安装完成或打开,然后点击打开
- android安卓升级版本安装后自动打开弹出完成和打开新版应用界面
- android的APP自动更新程序,检测版本,然后下载安装,但app安装后不提示“完成,打开”?
- Android自动更新安装后显示‘完成’‘打开’按钮
- [Android实例] android应用静默升级,安装完成后自动启动该应用
- android在下载app后自动安装,安装完成后不会弹出打开或完成界面
- android实现自动升级并安装打开
- 不用线程做Android软件欢迎界面,透明效果,完成后自动跳转
- 如何在vs的setup project中,设置安装完成后自动打开一个html文件?
- android 应用升级 下载安装包 完成后 自动安装apk文件
- android 应用升级 下载安装包 完成后 自动安装apk文件
- 调用Android系统安装的软件打开文件,程序停止运行
- android应用程序安装后自动打开
- 利用批处理全自动(静默)安装常用软件
- android应用程序安装后自动打开
- 利用批处理全自动(静默)安装常用软件
- android应用程序安装后自动打开
- android应用程序安装后自动打开
- 利用批处理全自动(静默)安装常用软件