1. ホーム
  2. android

[解決済み] Android: プログラムで .apk をインストールする [重複].

2022-03-14 20:03:50

質問

に助けてもらって作りました。 Androidダウンロードバイナリーファイルの問題 Androidにプログラムによるアプリケーションをインストールする .

自動更新と自動インストールを一度に行いたいのですが。ローカルなので、非市場アプリケーションです。

以下は、そのための私のコードです。

public void Update(String apkurl){
    try {
        URL url = new URL(apkurl);
        HttpURLConnection c = (HttpURLConnection) url.openConnection();
        c.setRequestMethod("GET");
        c.setDoOutput(true);
        c.connect();

        String PATH = Environment.getExternalStorageDirectory() + "/download/";
        File file = new File(PATH);
        file.mkdirs();
        File outputFile = new File(file, "app.apk");
        FileOutputStream fos = new FileOutputStream(outputFile);

        InputStream is = c.getInputStream();

        byte[] buffer = new byte[1024];
        int len1 = 0;
        while ((len1 = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len1);
        }
        fos.close();
        is.close();//till here, it works fine - .apk is download to my sdcard in download file

        Intent promptInstall = new Intent(Intent.ACTION_VIEW)
            .setData(Uri.parse(PATH+"app.apk"))
            .setType("application/android.com.app");
        startActivity(promptInstall);//installation is not working

    } catch (IOException e) {
        Toast.makeText(getApplicationContext(), "Update error!", Toast.LENGTH_LONG).show();
    }
}  

私のパーミッションは INTERNET , WRITE_EXTERNAL_STORAGE , INSTALL_PACKAGES および DELETE_PACKAGES .

インテント時 promptInstall が読み込まれると、アプリがクラッシュします =/。

つまり、パーミッションが足りないのか、私のコードが間違っているのか、あるいはもっと良い方法があるのでしょうか?

解決方法は?

問題を解決しました。私は setData(Uri)setType(String) .

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "app.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

これで正しく、自動更新が機能するようになりました。助けてくれてありがとうございます。)

2016.7.20に編集しました。

久しぶりに、別のプロジェクトで再びこの更新方法を使うことになった。以前の解決策では多くの問題が発生しました。その間に多くのことが変わったので、別のアプローチでこれを行う必要がありました。以下はそのコードです。

    //get destination to update file and set Uri
    //TODO: First I wanted to store my update .apk file on internal storage for my app but apparently android does not allow you to open and install
    //aplication with existing package from there. So for me, alternative solution is Download directory in external storage. If there is better
    //solution, please inform us in comment
    String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
    String fileName = "AppName.apk";
    destination += fileName;
    final Uri uri = Uri.parse("file://" + destination);

    //Delete update file if exists
    File file = new File(destination);
    if (file.exists())
    //file.delete() - test this, I think sometimes it doesnt work
        file.delete();

    //get url of app on server
    String url = Main.this.getString(R.string.update_app_url);

    //set downloadmanager
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    request.setDescription(Main.this.getString(R.string.notification_description));
    request.setTitle(Main.this.getString(R.string.app_name));

    //set destination
    request.setDestinationUri(uri);

    // get download service and enqueue file
    final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    final long downloadId = manager.enqueue(request);

    //set BroadcastReceiver to install app when .apk is downloaded
    BroadcastReceiver onComplete = new BroadcastReceiver() {
        public void onReceive(Context ctxt, Intent intent) {
            Intent install = new Intent(Intent.ACTION_VIEW);
            install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            install.setDataAndType(uri,
                    manager.getMimeTypeForDownloadedFile(downloadId));
            startActivity(install);

            unregisterReceiver(this);
            finish();
        }
    };
    //register receiver for when .apk download is compete
    registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));