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());
}
}
}