Android靜默安裝和靜默解除安裝

yangxi_001發表於2016-01-08

靜默顧名思義就是靜靜的默默地,靜默安裝和靜默解除安裝的意思也就是說在後臺默默地安裝和解除安裝。

最近的一個app應用分發的專案中app下載的模組,下載完成之後,使用者可以通過這個app進行安裝,為了提高使用者的體驗,我就加入了靜默安裝和解除安裝功能,然後還加入了使用am命令啟動某個Activity。

這個專案中靜默的方式實現程式碼如下:

首先判斷是否有root許可權,如果有利用靜默方式,否則利用意圖實現app安裝和解除安裝操作。

package com.example.test;
 
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
 
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
 
/**
 * 描述: app安裝操作             
 * @author 吳傳龍                 
 * Email:andywuchuanlong@sina.cn 
 * QQ: 3026862225              
 * @version 建立時間: 2015年3月6日 下午3:51:14               
 * @version 最後修改時間:2015年3月6日 下午3:51:14     修改人:吳傳龍     
 */
public class ApkController {
    /**
     * 描述: 安裝
     * 修改人: 吳傳龍                                             
     * 最後修改時間:2015年3月8日 下午9:07:50
     */
    public static boolean install(String apkPath,Context context){
        // 先判斷手機是否有root許可權
        if(hasRootPerssion()){
            // 有root許可權,利用靜默安裝實現
            return clientInstall(apkPath);
        }else{
            // 沒有root許可權,利用意圖進行安裝
            File file = new File(apkPath);
            if(!file.exists())
                return false;
            Intent intent = new Intent();
            intent.setAction("android.intent.action.VIEW");
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
            context.startActivity(intent);
            return true;
        }
    }
     
    /**
     * 描述: 解除安裝
     * 修改人: 吳傳龍                                             
     * 最後修改時間:2015年3月8日 下午9:07:50
     */
    public static boolean uninstall(String packageName,Context context){
        if(hasRootPerssion()){
            // 有root許可權,利用靜默解除安裝實現
            return clientUninstall(packageName);
        }else{
            Uri packageURI = Uri.parse("package:" + packageName);
            Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,packageURI);
            uninstallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(uninstallIntent);
            return true;
        }
    }
     
    /**
     * 判斷手機是否有root許可權
     */
    private static boolean hasRootPerssion(){
        PrintWriter PrintWriter = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            PrintWriter = new PrintWriter(process.getOutputStream());
            PrintWriter.flush();
            PrintWriter.close();
            int value = process.waitFor(); 
            return returnResult(value);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(process!=null){
                process.destroy();
            }
        }
        return false;
    }
     
    /**
     * 靜默安裝
     */
    private static boolean clientInstall(String apkPath){
        PrintWriter PrintWriter = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            PrintWriter = new PrintWriter(process.getOutputStream());
            PrintWriter.println("chmod 777 "+apkPath);
            PrintWriter.println("export LD_LIBRARY_PATH=/vendor/lib:/system/lib");
            PrintWriter.println("pm install -r "+apkPath);
//          PrintWriter.println("exit");
            PrintWriter.flush();
            PrintWriter.close();
            int value = process.waitFor(); 
            return returnResult(value);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(process!=null){
                process.destroy();
            }
        }
        return false;
    }
     
    /**
     * 靜默解除安裝
     */
    private static boolean clientUninstall(String packageName){
        PrintWriter PrintWriter = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            PrintWriter = new PrintWriter(process.getOutputStream());
            PrintWriter.println("LD_LIBRARY_PATH=/vendor/lib:/system/lib ");
            PrintWriter.println("pm uninstall "+packageName);
            PrintWriter.flush();
            PrintWriter.close();
            int value = process.waitFor(); 
            return returnResult(value);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(process!=null){
                process.destroy();
            }
        }
        return false;
    }
     
    /**
     * 啟動app
     * com.exmaple.client/.MainActivity
     * com.exmaple.client/com.exmaple.client.MainActivity
     */
    public static boolean startApp(String packageName,String activityName){
        boolean isSuccess = false;
        String cmd = "am start -n " + packageName + "/" + activityName + " \n";
        Process process = null;
        try {
           process = Runtime.getRuntime().exec(cmd);
           int value = process.waitFor(); 
           return returnResult(value);
        } catch (Exception e) {
          e.printStackTrace();
        } finally{
            if(process!=null){
                process.destroy();
            }
        }
        return isSuccess;
    }
     
     
    private static boolean returnResult(int value){
        // 代表成功 
        if (value == 0) {
            return true;
        } else if (value == 1) { // 失敗
            return false;
        } else { // 未知情況
            return false;
        
    }
}

package com.example.test;
 
import java.io.File;
 
import android.support.v4.app.Fragment;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.os.Build;
/**
 * 描述: MainActivity            
 * @author 吳傳龍                 
 * Email:andywuchuanlong@sina.cn 
 * QQ: 3026862225              
 * @version 建立時間: 2015年3月9日 上午8:19:19               
 * @version 最後修改時間:2015年3月9日 上午8:19:19     修改人:吳傳龍
 */
public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    /**
     * 描述: 安裝
     * @param          
     * 修改人: 吳傳龍                                             
     * 最後修改時間:2015年3月9日 上午8:19:30
     */
    public void click1(View view){
        new Thread(){
            public void run() {
                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/jniTest.apk";
                if (ApkController.install(path, getApplicationContext())){
                    toast("安裝成功");
                }else{
                    toast("安裝失敗");
                }
            };
        }.start();
    }
     
    /**
     * 描述: 解除安裝
     * @param          
     * 修改人: 吳傳龍                                             
     * 最後修改時間:2015年3月9日 上午8:19:30
     */
    public void click2(View view){
        new Thread(){
            public void run() {
                if (ApkController.uninstall("com.example.jnitest", getApplicationContext())){
                    toast("解除安裝成功");
                }else{
                    toast("解除安裝失敗");
                }
            };
        }.start();
    }
     
    /**
     * 描述: 啟動
     * @param          
     * 修改人: 吳傳龍                                             
     * 最後修改時間:2015年3月9日 上午8:19:30
     */
    public void click3(View view){
        if (ApkController.startApp("com.example.jnitest","com.example.jnitest.MainActivity")) {
            toast("啟動成功");
        }
    }
     
     
    public void toast(final String text){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();;
            }
        });
    }
 
}

?

要用其他的方式實現靜默方式,可以通過偽裝成系統應用,這就要給app打上系統應用的簽名,但是這些簽名在小米等手機上是沒用的,所以這裡不做介紹。還有就是通過把應用放在system/app的目錄下也可以實現。

相關文章