Self updating app

吃可爱长大的小学妹 提交于 2019-12-20 08:29:33

问题


TL:DR; version ;)

  • my app should run without user interaction (autostart etc works)

  • it should update itself (via apk) without any user interaction

  • rooted devices are possible

.

problem:

  • querying a newer apk from a server works
  • when starting the apk with a (view?) intent, the "install app" prompt pops and needs a user confirmation

How do I solve this without any user interaction?

http://code.google.com/p/auto-update-apk-client/ This seems to be a solution, but there must be better approach.

I already found this: Install Application programmatically on Android

but that doesn't solve my problem.


回答1:


Solved it! :D

It just works in rooted devices but works perfectly. Using the unix cmd "pm" (packageManager) allows you to install apks from sdcard, when executing it as root.

Hope this could help some people in the future.

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

Required permissions:

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



回答2:


My suggestion is to use plugin mechanism instad of updating the app. You can dynamically load classes from the Web and run them inside your app without any user interaction. There is a lot of resources spread across the Internet:

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

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




回答3:


If su -c doesn't work, try su 0 (only rooted devices can do su!)

The full answer looks like this:

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

With this class defined:

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
        }
    }
}


来源:https://stackoverflow.com/questions/14982174/self-updating-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!