package com.example.bnoainstaller; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); hasRoot(); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private void hasRoot() { int i = execRootCmdSilent("echo test"); // 通过执行测试命令来检测 Log.e("BNOAInstaller", "in hasRoot method, i is : " + i); if (i != -1) { if(this.checkAppExists()) { appExistsHandler(); } else { installApp(); } } else { hasNoRootPrivilegesHandler(); } } // 执行linux命令但不关注结果输出 protected static int execRootCmdSilent(String paramString) { try { Process localProcess = Runtime.getRuntime().exec("su"); Object localObject = localProcess.getOutputStream(); DataOutputStream localDataOutputStream = new DataOutputStream( (OutputStream) localObject); String str = String.valueOf(paramString); localObject = str + "\n"; localDataOutputStream.writeBytes((String) localObject); localDataOutputStream.flush(); localDataOutputStream.writeBytes("exit\n"); localDataOutputStream.flush(); localProcess.waitFor(); int result = localProcess.exitValue(); return (Integer) result; } catch (Exception localException) { localException.printStackTrace(); return -1; } } private void hasNoRootPrivilegesHandler() { AlertDialog.Builder builder = new Builder(MainActivity.this); builder.setTitle("提示"); builder.setMessage("您没有获得root权限"); builder.setPositiveButton("确认", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); MainActivity.this.finish(); } }); builder.show(); } private void installApp() { try { copyApp2SDCard("bnoa.apk"); Log.e("BNOAInstaller", "Copy app file to sdcard successfully"); copyApp2SystemAppDir(); afterInstalling(); } catch (Exception e) { e.printStackTrace(); Log.e("BNOAInstaller", e.getMessage()); Log.e("BNOAInstaller", "Copy file failed"); installFailed(); } } private void afterInstalling() { AlertDialog.Builder builder = new Builder(MainActivity.this); builder.setMessage("安装程序已将<应用>安装到您的手机了,但需要重启手机,应用才可以使用。是否重启?"); builder.setTitle("提示"); // builder.setNegativeButton("取消", new OnClickListener() { // @Override // public void onClick(DialogInterface dialog, int arg1) { // dialog.dismiss(); // MainActivity.this.finish(); // } // }); builder.setPositiveButton("重启", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { rebootDevice(); } }); builder.show(); } private void installFailed() { AlertDialog.Builder builder = new Builder(MainActivity.this); builder.setTitle("提示"); builder.setMessage("安装应用<应用>出错"); builder.setPositiveButton("确认", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); MainActivity.this.finish(); } }); builder.show(); } private void copyApp2SDCard(String fileName) throws Exception { Log.e("BNOAInstaller", "In copy app to system directory"); // 获取assets下的数据库文件流 InputStream is = this.getBaseContext().getAssets().open(fileName); // 获取应用包名 String appPath = new File("/sdcard").getAbsolutePath() + "/" + fileName; Log.e("BNOAInstaller", "Create file in sdcard success"); File app = new File(appPath); Log.e("BNOAInstaller", "after create file : " + appPath); if (app.exists()) { app.delete(); } app.createNewFile(); Log.e("BNOAInstaller", "Create file bnoa.apk in sdcard, file path: " + appPath); FileOutputStream fos = new FileOutputStream(app, true); Log.e("BNOAInstaller", "After create output stream of fos"); byte[] buffer = new byte[1024]; int count = 0; while ((count = is.read(buffer)) != -1) { fos.write(buffer, 0, count); } Log.e("BNOAInstaller", "Write bnoa.apk to sdcard complete"); app = null; fos.close(); is.close(); } private void copyApp2SystemAppDir() throws Exception { Log.e("BNOAInstaller", "In copyApp2SystemAppDir()..."); // String rwCommand = "mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system\n"; String rwCommand = "mount -o remount,rw /system\n"; // String copyCommand = "cat /sdcard/bnoa.apk > /system/app/bnoa.apk\n"; String copyCommand = "cat /sdcard/bnoa.apk > /system/app/bnoa.apk\n"; /** * 下面的chmod64Command命令非常重要,如果没有 * 这句命令,那么有的手机在bnoa.apk复制到/system/app下后,经过重启, * 应用图标也不会在屏幕上出现,应用本身也不会在系统后台运行。 * chmod 是给应用设置访问权限的 ,是linux的权限设置命令: * chod 664: -rw-r--r-- (644) 只有属主有读写权限;而属组用户和其他用户只有读权限。 */ String chmod64Command = "chmod 644 /system/app/bnoa.apk\n"; String rmAppFileCommand = "rm /sdcard/bnoa.apk\n";//删除sd卡上的APP文件 // String roCommand = "mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system\n"; String roCommand = "mount -o remount,ro /system\n"; // String lsCommand = "ls /system/app"; Process proc = Runtime.getRuntime().exec("su"); Log.e("BNOAInstaller", "After command: su"); DataOutputStream os = new DataOutputStream(proc.getOutputStream()); os.writeBytes(rwCommand); Log.e("BNOAInstaller", "After command: mount -o remount,rw /system"); os.writeBytes(copyCommand); Log.e("BNOAInstaller", "After command: cat /sdcard/bnoa.apk > /system/app/bnoa.apk"); os.writeBytes(chmod64Command); Log.e("BNOAInstaller", "After command: chmod 644 /system/app/bnoa.apk"); os.writeBytes(rmAppFileCommand); Log.e("BNOAInstaller", "After command: rm /sdcard/bnoa.apk"); os.writeBytes(roCommand); Log.e("BNOAInstaller", "After command: mount -o remount,ro /system"); os.writeBytes("exit\n"); Log.e("BNOAInstaller", "After command: exit"); os.flush(); proc.waitFor(); } private boolean checkAppExists() { try { // StringBuffer outputInfo = new StringBuffer(); Process proc = Runtime.getRuntime().exec("ls /system/app"); proc.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream())); String appName = ""; while ((appName = reader.readLine())!= null) { // outputInfo.append(appName + "\n"); // Log.e("BNOAInstaller_readLine: ", appName); appName = appName.trim(); if(appName.equals("bnoa.apk")) { return true; } } } catch (Exception e) { e.printStackTrace(); Log.e("BNOAInstaller", e.getMessage()); } return false; } private void appExistsHandler() { AlertDialog.Builder builder = new Builder(MainActivity.this); builder.setTitle("提示"); builder.setMessage("版纳OA移动端已安装,是否卸载?"); builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); MainActivity.this.finish(); } }); builder.setPositiveButton("残忍卸载", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { uninstallApp(); } }); builder.show(); } private void uninstallApp() { try { // String rwCommand = "mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system\n"; String rwCommand = "mount -o remount,rw /system\n"; String rmCommand = "rm /system/app/bnoa.apk\n"; String rmDataCommand = "rm -r /data/data/com.eruipan.bnoaapp\n";//删除已用生成的数据 // String roCommand = "mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system\n"; String roCommand = "mount -o remount,ro /system\n"; Process proc = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(proc.getOutputStream()); os.writeBytes(rwCommand); os.writeBytes(rmCommand); os.writeBytes(rmDataCommand); os.writeBytes(roCommand); os.writeBytes("exit\n"); os.flush(); proc.waitFor(); uninstallAppOverHandler(); } catch (Exception e) { Log.e("BNOAInstaller", e.getMessage()); uninstallAppFail(); } } private void uninstallAppOverHandler() { AlertDialog.Builder builder = new Builder(MainActivity.this); builder.setTitle("提示"); builder.setMessage("卸载完成"); builder.setPositiveButton("确认", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); MainActivity.this.finish(); } }); builder.show(); } private void uninstallAppFail() { AlertDialog.Builder builder = new Builder(MainActivity.this); builder.setTitle("提示"); builder.setMessage("卸载出错"); builder.setPositiveButton("确认", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); MainActivity.this.finish(); } }); builder.show(); } private void rebootDevice() { try{ Process proc = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(proc.getOutputStream()); os.writeBytes("reboot\n"); os.writeBytes("exit\n"); os.flush(); }catch(Exception e) { Log.e("BNOAInstaller", "reboot device exception : " + e.getMessage()); } } }
原文:http://www.cnblogs.com/sereneray/p/5120054.html