記得上一次寫簡書還是在自己剛進大學的時候,那個時候才開始接觸android開發(fā),寫出一個登陸界面都好開心。經過一年多的學習,成長為一個稍微入門的菜鳥,所以再一次打開簡書記錄一下。
目錄
1.什么是靜默安裝
2.如何實現
3.心得體會
什么是靜默安裝
在百度上瀏覽了一下,總結到了一下的解釋:
靜默安裝指的是安裝時無需任何用戶干預,直接按默認設置安裝。即在安裝過程中可以靜默安裝好預先設計集成的一些常用軟件,安裝結束以后軟件就已經可以使用。
按照我自己的話來解釋,就是以前我們最討厭的那些流氓軟件的安裝模式,及在我們用戶毫不知情的情況下,app自動安裝。
其實,這種模式并無對錯,只是看我們怎么運用。假如我們需要實現一個類似于監(jiān)聽的apk時,他需要在安裝主apk之后,自動安裝,這個時候就可以不需要用戶確定而自動安裝,這個時候就需要用到靜默安裝。
代碼實現
public class Controller {
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;
}
}
/**
* 判斷手機是否有root權限
*/
public 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;
}
/**
* 靜默安裝
*/
public 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;
}
/**
* 將文件復制到system/app 目錄
* @param apkPath 特別注意格式:該路徑不能是:/storage/emulated/0/app/QDemoTest4.apk 需要是:/sdcard/app/QDemoTest4.apk
* @return
*/
public static boolean copy2SystemApp(String apkPath){
PrintWriter PrintWriter = null;
Process process = null;
String appName = "chetou.apk",cmd;
try {
process = Runtime.getRuntime().exec("su");
PrintWriter = new PrintWriter(process.getOutputStream());
cmd = "mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system";
Log.e("copy2SystemApp", cmd);
PrintWriter.println(cmd);
cmd = "cat "+apkPath+" > /system/app/"+appName;
Log.e("copy2SystemApp", cmd);
PrintWriter.println(cmd);
cmd = "chmod 777 /system/app/"+appName +" -R";
Log.e("copy2SystemApp", cmd);
PrintWriter.println(cmd);
cmd = "mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system";
Log.e("copy2SystemApp", cmd);
PrintWriter.println(cmd);
PrintWriter.println("reboot"); //重啟
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 returnResult(int value){
// 代表成功
if (value == 0) {
return true;
} else if (value == 1) { // 失敗
return false;
} else { // 未知情況
return false;
}
}
}
這是一個封裝好的類,直接在需要的地方調用,傳入相應的參數。
下載功能
這個功能我是在網上找的別人封裝好的一個下載工具庫,他是基于okhttp來實現的下載功能。邏輯很清楚,自己上代碼
public class DownloadUtil {
private static DownloadUtil downloadUtil;
private final OkHttpClient okHttpClient;
public static DownloadUtil get() {
if (downloadUtil == null) {
downloadUtil = new DownloadUtil();
}
return downloadUtil;
}
private DownloadUtil() {
okHttpClient = new OkHttpClient();
}
/**
* @param url 下載連接
* @param destFileDir 下載的文件儲存目錄
* @param destFileName 下載文件名稱
* @param listener 下載監(jiān)聽
*/
public void download(final String url, final String destFileDir, final String destFileName, final OnDownloadListener listener) {
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 下載失敗監(jiān)聽回調
listener.onDownloadFailed(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
// 儲存下載文件的目錄
File dir = new File(destFileDir);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, destFileName);
try {
is = response.body().byteStream();
long total = response.body().contentLength();
fos = new FileOutputStream(file);
long sum = 0;
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
sum += len;
int progress = (int) (sum * 1.0f / total * 100);
// 下載中更新進度條
listener.onDownloading(progress);
}
fos.flush();
// 下載完成
listener.onDownloadSuccess(file);
} catch (Exception e) {
listener.onDownloadFailed(e);
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
try {
if (fos != null)
fos.close();
} catch (IOException e) {
}
}
}
});
}
public interface OnDownloadListener {
/**
* @param file 下載成功后的文件
*/
void onDownloadSuccess(File file);
/**
* @param progress 下載進度
*/
void onDownloading(int progress);
/**
* @param e 下載異常信息
*/
void onDownloadFailed(Exception e);
}
}
通過三個監(jiān)聽,來監(jiān)聽下載的狀態(tài)。
啟動
Intent intent1=context.getPackageManager().getLaunchIntentForPackage("com.xxx.xx.xxxxxxx");
context.startActivity(intent1);
心得體會
實現靜默安裝的前提是要獲得手機的root權限,其次其核心實現邏輯就是調用Android系統(tǒng)的pm install命令。