日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

Android/ target=_blank class=infotextkey>安卓更新方式,網上五花八門,但是真正實現apk自動更新無痕跡的方式,少之又少,畢竟不要錢的方式,穩定的方式才能讓開發者在困難中脫穎而出。

安卓程序如何做到自動更新?安卓程序如何實現無彈框更新?

 

1,安卓apk自動更新方式?

 

a,第三方平臺更新apk,灰度發布,用友等

b,系統更新方式有彈窗contenx,通過窗體上下文方式實現更新。

c,通過安卓程序系統服務實現命令更新,自啟等。

d,通過安卓反編譯修改安卓源碼包實現自動更新。

我們采用安卓系統apk方式實現apk重啟更新上圖:

Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 


Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

 

 

整體流程:

1,我們Tomcat服務器掛載或者ftp服務器提供apkurl地址。

2,安卓程序定時拉取獲取監聽下載url地址,下載apk到本地獲取新的版本,對比當前的apk版本進行更新。

3,如果當前版本大于運行的apk程序版本進行apk更新。

4,通過我們JAVA程序執行cmd命令 adb 方式去讀取命令行執行方式返回信息進行程序更新。

5,通過adb命令把apk推送到系統程序里面,獲取apk包名實現程序重啟,即可完成安卓程序自動更新。

 

實現彈框的方式:

public boolean installApk(Context context) throws Exception {
        try {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(configPath + "App-release.apk")), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            //打開安裝應用界面
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

 

Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 


Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

?

 

這種方式不能實現自動發包,但是可以完成自動更新。

通過cmd命令操作實現apk覆蓋自動重啟:

1,連接到adb

adb connect 127.0.0.1:7555
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

2,查看連接狀態

adb devices 
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

?

3,通過adb root 命令權限。

adb root
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

?

 

4,獲取系統app權限

adb remount
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

5,把app上傳到系統里面

adb push D:app-release.apk /system/app/
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

6,查找包名重啟apk

adb shell pm list package -f
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

?

 

查看啟動Activity類名

adb shell 

dumpsys package com.instwall.launch  (進行系統shell里面去查看包名)
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

?

 

7,重啟程序(復制系統app下面的應用包名)

adb shell am start -n <應用包名>/<應用啟動Activity絕對名稱>

adb shell am start -n  com.instwall.launch/.MainActivity
Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

?

 

我們可以看到當前的程序已經啟動。但是命令行的方式還是需要手動去打命令自然不滿足我們自動更新的操作處理,至于這里為什么不用第三方平臺的問題,原因是因為我們的apk程序要支持離線更新,apk程序本身在專網里面,所以有很多限制。這里我們可以通過java 程序去代替我們執行adb 腳本命令從而實現apk自動更新,只不過步驟要寫很多。

貼幾個代碼執行腳本的代碼:

版本更新的核心處理類。

package com.instwall.launch.task;


import static com.instwall.launch.contans.Contans.configPath;
import static com.instwall.launch.utils.FileDirectoryUtils.dropVedio;
import static com.instwall.launch.utils.FileDirectoryUtils.getDownApkVersion;
import static com.instwall.launch.utils.FileDirectoryUtils.readAppInfo;
import static com.instwall.launch.utils.FileDirectoryUtils.writeAppInfo;
import static com.instwall.launch.utils.FileDirectoryUtils.writeLog;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

import com.instwall.launch.contans.Contans;
import com.instwall.launch.utils.CmdTerminalUtils;
import com.instwall.launch.utils.FileDirectoryUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * 版本更新
 */
public class UpdateVersionTask implements Runnable {
    private final Context context;

    public UpdateVersionTask(Context context) {
        this.context = context;
    }

    private static void download(String mUrl, String mPath) throws MalformedURLException {
        // 下載網絡文件
        int byteread = 0;
        int mDownloadSize = 0;
        URL url = new URL(mUrl);
        URLConnection conn = null;
        InputStream is = null;
        FileOutputStream os = null;
        try {
            conn = url.openConnection();
            is = conn.getInputStream();
            os = new FileOutputStream(mPath);
            byte[] buffer = new byte[1204];
            int length;
            while ((byteread = is.read(buffer)) != -1) {
                mDownloadSize += byteread;
                os.write(buffer, 0, byteread);
            }
            Log.i("文件下載成功-------", mPath);
            writeLog("apk down  file  success .......... " + mPath);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            //  dropFile(mPath);
            writeLog("apk down  file  error .......... " + e.getMessage());

            Log.e("文件下載失敗-------", e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            // dropFile(mPath);
            Log.e("文件下載失敗---刪除當前下載文件----", e.getMessage());
            writeLog("apk down  file  error .......... " + e.getMessage());

        } catch (Exception e) {
            e.printStackTrace();
            //  dropFile(mPath);
            Log.e("文件下載失敗---刪除當前下載文件----", e.getMessage());
            writeLog("apk down  file  error .......... " + e.getMessage());

        } finally {
            // 關閉輸出流
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 關閉輸入流
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }


    }


    @Override
    public void run() {
        try {
            download(Contans.getApiDownUrl(), configPath + "app-release.apk");
            //獲取下載的版本包
            int verson = getDownApkVersion(context, configPath + "app-release.apk");
            // writeLog("down apk  version .......... " + verson);
            int installVersion = readAppInfo();
            if (installVersion == 0) {
                installVersion = FileDirectoryUtils.getVersionCode(context);
            }
            writeLog("down now  version .......... " + installVersion);
            //如果下載的版本大于當前運行的apk版本直接安裝最新并且寫入文件
            if (verson > installVersion) {
                writeLog("down now  version .......... " + installVersion);
                //安裝apk
                CmdTerminalUtils.startApk();
                //寫入當前版本到文件夾
                writeAppInfo(verson);
                //刪除沒有下載完成的視頻
                dropVedio();
            }

        } catch (Exception e) {
            writeLog("ReportHear api  pulish   error .......... " + e.getMessage());
        }

    }

    public boolean installApk(Context context) throws Exception {
        try {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(configPath + "app-release.apk")), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            //打開安裝應用界面
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private boolean isHasInstallPermissionWithO(Context context) {
        if (context == null) {
            return false;
        }
        return context.getPackageManager().canRequestPackageInstalls();
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity(Context context) {
        if (context == null) {
            return;
        }
        Intent intent = new Intent();
        //獲取當前apk包URI,并設置到intent中(這一步設置,可讓“未知應用權限設置界面”只顯示當前應用的設置項)
        Uri packageURI = Uri.parse("package:" + context.getPackageName());
        intent.setData(packageURI);
        //設置不同版本跳轉未知應用的動作
        if (Build.VERSION.SDK_INT >= 26) {
            //intent = new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,packageURI);
            intent.setAction(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        } else {
            intent.setAction(android.provider.Settings.ACTION_SECURITY_SETTINGS);
        }
        context.startActivity(intent);
    }

}

 

1,建立連接

 /**
     * 建立連接
     *
     * @return
     */
    public static boolean firstCmd() throws IOException {

        Process process = null;
        String command = "D:\platform-tools\adb connect 127.0.0.1:7555";   //sdk所在位置
        process = Runtime.getRuntime().exec(command);
        InputStreamReader ir = new InputStreamReader(process.getInputStream());

        try {

            LineNumberReader input = new LineNumberReader(ir);
            String line;
            List<String> list = new ArrayList<>();
            while ((line = input.readLine()) != null) {
                list.add(line);
            }

            input.close();
            for (String result : list) {
                if (result.contains("device") || result.contains("already")) {
                    writeLog("adb: "+command );
                    writeLog("adb first cmd  message: "+result );
                    return true;
                }
                System.out.println("message" + result);
            }

        } catch (IOException e) {

            System.err.println("IOException" + e.getMessage());

        } finally {
            ir.close();
        }
        return false;
    }

2,賦予權限:

 /**
     * 建立連接
     *
     * @return
     */
    public static boolean twoCmd() throws IOException {

        Process process = null;


        String command = "D:\platform-tools\adb root";   //sdk所在位置
        process = Runtime.getRuntime().exec(command);

        InputStreamReader ir = new InputStreamReader(process.getInputStream());
        try {


            LineNumberReader input = new LineNumberReader(ir);

            String line;
            List<String> list = new ArrayList<>();
            while ((line = input.readLine()) != null) {
                list.add(line);
            }
            for (String result : list) {

                if (result.equals("adbd is already running as root")) {
                    writeLog("adb: "+command );
                    writeLog("adb tow cmd  message: "+result );
                    return true;
                }
                if (result.contains("device")) {
                    writeLog("adb: "+command );
                    writeLog("adb tow cmd  message: "+result );
                    return true;
                }
                System.out.println("message" + result);
            }
        } catch (IOException e) {

            System.err.println("IOException" + e.getMessage());

        } finally {
            ir.close();
        }
        return false;
    }

 

3,后面的步驟同上,把不同腳本信息的命令通過cmd執行,獲取特定的返回messge信息判斷程序命令是否執行成功。

 

 /**
     * 通過命令啟動apk
     */
    public static void startApk() {
        //定義執行成功標識,如果執行不成功一直執行到成功
        boolean flag = true;
        while (flag)
            try {
                 //執行命令
                boolean first = firstCmd();
                if (first) {
                    //執行權限
                    boolean two = twoCmd();
                    if (two) {
                        boolean three = threeCmd();
                        if (three) {
                            fourCmd();
                            fiveCmd();
                            flag = false;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

    }

我們之間通過字符串包含的方式判斷命令是否執行完成,即可完成命令的執行,從而實現我們java程序去處理adb命令從而實現apk自動更新。

Android APK 程序實現自動更新,java服務處理無彈窗,終極解決方案

 

?

故事到這里就結束了。自動更新完成,喜歡的記得關注和轉發。

分享到:
標簽:Android APK
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定