web-dev-qa-db-ja.com

自己更新アプリ

TL:DR;バージョン ;)

  • 私のアプリはユーザーの操作なしで実行する必要があります(自動起動などが機能します)

  • ユーザーの操作なしで(apkを介して)自分自身を更新する必要があります

  • ルート権限を取得されたデバイスが可能です

問題:

  • サーバーから新しいapkをクエリすると機能します
  • (表示?)インテントでapkを開始すると、「アプリのインストール」プロンプトが表示され、ユーザーの確認が必要になります

ユーザーの操作なしでこれを解決するにはどうすればよいですか?

http://code.google.com/p/auto-update-apk-client/ これは解決策のようですが、より良いアプローチが必要です。

私はすでにこれを見つけました: Androidにプログラムでアプリケーションをインストールする

しかし、それは私の問題を解決しません。

23
Thkru

解決しました! :D

rootedデバイスでのみ機能しますが、完全に機能します。 unix cmd "pm"(packageManager)を使用すると、rootとして実行するときにsdcardからapksをインストールできます。

これが将来一部の人々に役立つことを願っています。

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" />
35
Thkru

私の提案は、アプリを更新する代わりにプラグインメカニズムを使用することです。 Webからクラスを動的にロードし、ユーザーの操作なしでアプリ内で実行できます。インターネット全体に広がる多くのリソースがあります:

Android/dalvikでJavaクラスを動的にロードする方法は?

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

5
Zielony

su -cが機能しない場合は、su 0を試してください(ルート化されたデバイスのみがsuを実行できます!)

完全な答えは次のようになります。

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