【问题标题】:Self updating app自我更新应用
【发布时间】:2013-02-05 14:11:35
【问题描述】:

TL:DR;版本;)

  • 我的应用应该在没有用户交互的情况下运行(自动启动等工作)

  • 它应该在没有任何用户交互的情况下自行更新(通过 apk)

  • root 设备是可能的

.

问题:

  • 从服务器查询较新的 apk 有效
  • 使用(查看?)意图启动 apk 时,会弹出“安装应用程序”提示并需要用户确认

如何在没有任何用户交互的情况下解决此问题?

http://code.google.com/p/auto-update-apk-client/ 这似乎是一个解决方案,但必须有更好的方法。

我已经找到了这个:Install Application programmatically on Android

但这并不能解决我的问题。

【问题讨论】:

    标签: android apk updating self-updating


    【解决方案1】:

    解决了! :D

    它只适用于 root 设备,但运行良好。 使用 unix cmd "pm" (packageManager) 允许您在以 root 身份执行时从 sdcard 安装 apk。

    希望这可以帮助将来的一些人。

    public static void installNewApk()
    {
            try
            {
                Runtime.getRuntime().exec(new String[] {"su", "-c", "pm install -r /mnt/internal/Download/fp.apk"});
            }
            catch (IOException e)
            {
                System.out.println(e.toString());
                System.out.println("no root");
            }
    }
    

    所需权限:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    【讨论】:

    • 它给了我错误代码 139,即分段错误。但是我的平板电脑已经root了。知道为什么吗?
    • 你能告诉我在有根的平板电脑上运行这段代码需要什么权限吗?
    • 什么也没发生。它既没有给出任何错误,也没有安装apk。我的设备已植根。知道为什么它不起作用吗?
    • 非root手机可以这样吗?
    • 第一句:“它只适用于有根设备...”,如前所述^^
    【解决方案2】:

    我的建议是使用插件机制来更新应用程序。您可以从 Web 动态加载类并在您的应用程序中运行它们,而无需任何用户交互。互联网上有很多资源:

    How to load a Java class dynamically on android/dalvik?

    http://android-developers.blogspot.com/2011/07/custom-class-loading-in-dalvik.html

    【讨论】:

    • 好主意,我会试一试,但无论如何我认为使用 apk 更新会更健壮且不易出错。
    • 是的,Selvin,也许我应该试试这个:code.google.com/p/auto-update-apk-client ...但是根设备方法呢?是否有可能在cmd上安装apk?
    【解决方案3】:

    如果su -c 不起作用,请尝试su 0(只有root 设备可以使用!)

    完整答案如下所示:

    private void installNewApk()
        {
            String path = mContext.getFilesDir().getAbsolutePath() + "/" + LOCAL_FILENAME;
            mQuickLog.logD("Install at: " + path);
            ProcessUtils.runProcessNoException(mQuickLog, "su", "0", "pm", "install", "-r", path);
        }
    

    定义了这个类:

    public class ProcessUtils {
        Process process;
        int errCode;
        public ProcessUtils(String ...command) throws IOException, InterruptedException{
            ProcessBuilder pb = new ProcessBuilder(command);
            this.process = pb.start();
            this.errCode = this.process.waitFor();
        }
    
        public int getErrCode() {
            return errCode;
        }
    
        public String getOutput() throws IOException {
            InputStream inputStream = process.getInputStream();
            InputStream errStream = process.getErrorStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line + System.getProperty("line.separator"));
            }
    
            br = new BufferedReader(new InputStreamReader(errStream));
            while ((line = br.readLine()) != null) {
                sb.append(line + System.getProperty("line.separator"));
            }
            return sb.toString();
        }
    
    
        public static String runProcess(String ...command) throws IOException, InterruptedException {
            ProcessUtils p = new ProcessUtils(command);
            if (p.getErrCode() != 0) {
                // err
            }
            return p.getOutput();
        }
    
        public static void runProcessNoException(String ...command) {
            try {
                runProcess(command);
            } catch (InterruptedException | IOException e) {
                // err
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-12
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多