web-dev-qa-db-ja.com

Phonegap Androidプログラムによるアプリトリガーの更新

GooglePlayの外部のサーバーでホストされているAndroidアプリを作成しています。アプリが新しいバージョンを確認し、アプリの起動時にユーザーに更新を促す必要があります。

うまく機能している新しいバージョンをチェックするメカニズムを構築しました(アプリはサーバー上のファイルをチェックし、バージョンを比較します)。次に、ユーザーに更新を促しますが、ユーザーが更新を続行することを選択した場合、apkのダウンロードとインストールをトリガーできません。

私は単にapkのURLを開いてみました:

window.open(apkURL);

ここで、apkURLは、サーバーでホストされている.apkファイルへの完全なhttpリンクです。

しかし、それは何もしていないようです。

私は調査してきましたが、これを行う方法についての答えが見つかりません。この投稿のように、ネイティブコードを使用していくつかの提案を見つけました Androidにプログラムでアプリケーションをインストールします しかし、Phonegapアプリ内からそれを行う方法がわかりません。

Intent promptInstall = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("file:///path/to/your.apk"))
.setType("application/vnd.Android.package-archive");
startActivity(promptInstall); 

これは更新をトリガーする正しい方法ですか? Phonegapアプリ内からこのようなことをどのように行うことができますか?

ありがとう!

14
Vero

File apiと WebIntent プラグインを使用して、ようやくこれを実装できました。それが誰かを助ける場合に備えて、私はここに解決策を投稿します。

このコードは、apkをリモートサーバーからsdcardのダウンロードフォルダーにダウンロードしてから、インストールをトリガーします。

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem){
fileSystem.root.getFile('download/filename.apk', {
    create: true, 
    exclusive: false
  }, function(fileEntry) {
    var localPath = fileEntry.fullPath,
    fileTransfer = new FileTransfer();        
    fileTransfer.download(apkURL, localPath, function(entry) {
        window.plugins.webintent.startActivity({
            action: window.plugins.webintent.ACTION_VIEW,
            url: 'file://' + entry.fullPath,
            type: 'application/vnd.Android.package-archive'
            },
            function(){},
            function(e){
                alert('Error launching app update');
            }
        );                              

    }, function (error) {
        alert("Error downloading APK: " + error.code);
  });
  }, function(evt){
      alert("Error downloading apk: " + evt.target.error.code);                                               
  });
}, function(evt){
alert("Error preparing to download apk: " + evt.target.error.code);
});
16
Vero

Cordova 3+を使用している皆さんは、Veroと同様のソリューションが可能です。

そこで、最初に.apkファイルをダウンロードします。このためにファイル転送プラグインが必要です。次のコマンドでインストールできます。

phonegap local plugin add org.Apache.cordova.file-transfer

次に、Webインテントを開始するために別のプラグインが必要です。このWebインテントは、更新がある場合にユーザーにプロンプ​​トを表示します。次のコマンドでインストールできます。

phonegap local plugin add https://github.com/Initsogar/cordova-webintent.git

次に、コードでこの2つの関数を使用して、.apkをダウンロードし、アプリケーションの更新がある場合にユーザーにプロンプ​​トを表示できます。

/*
 * Uses the filetransfer plugin
 */
function downloadApkAndroid(data) {
    var fileURL = "cdvfile://localhost/persistent/CegekaMon.apk";

    var fileTransfer = new FileTransfer();
    var uri = encodeURI(data.Android);

    fileTransfer.download(
        uri,
        fileURL,
        function (entry) {

            console.log("download complete: " + entry.fullPath);

            promptForUpdateAndroid(entry);
        },
        function (error) {
            console.log("download error source " + error.source);
            console.log("download error target " + error.target);
            console.log("upload error code" + error.code);
        },
        false,
        {

        }
    );
}
/*
 * Uses the borismus webintent plugin
 */
function promptForUpdateAndroid(entry) {
    window.plugins.webintent.startActivity({
            action: window.plugins.webintent.ACTION_VIEW,
            url: entry.toURL(),
            type: 'application/vnd.Android.package-archive'
        },
        function () {
        },
        function () {
            alert('Failed to open URL via Android Intent.');
            console.log("Failed to open URL via Android Intent. URL: " + entry.fullPath);
        }
    );
}
12
RobinCominotto

残念ながら、プラグインを使用せずにPhonegap Webコンテナー内でその種のネイティブ機能にアクセスすることはできません。できることは、ユーザーをapkにリンクして(たとえばネイティブブラウザーを開いて)インストールさせることだけです。

0
zakinster

答えてくれてありがとうVero ...それは私をとても助けてくれます... cordovaファイルプラグインの最後のバージョンのコードに問題があります。 ファイルプラグインバージョン1.0.0以降を使用している場合は、entry.fullPathをentry.toURL()に置き換えます。 entry.fullPathを使用すると、「パッケージの解析に問題があります」というエラーがスローされます。

githubのファイル転送プラグインから

これらのパスは、以前はFileプラグインによって返されるFileEntryおよびDirectoryEntryオブジェクトのfullPathプロパティで公開されていました。ただし、ファイルプラグインの新しいバージョンでは、これらのパスがJavaScriptに公開されなくなりました。

Fileの新しい(1.0.0以降)バージョンにアップグレードしていて、以前にdownload()またはupload()の引数としてentry.fullPathを使用していた場合は、ファイルシステムのURLを使用するようにコードを変更する必要があります。代わりに。

FileEntry.toURL()およびDirectoryEntry.toURL()は、次の形式のファイルシステムURLを返します。

download()メソッドとupload()メソッドの両方で絶対ファイルパスの代わりに使用できるcdvfile:// localhost/persistent/path/to/file。

0
Siroos Asadi

2018年の実例

以前のコメントに基づいて、私はこのソリューションを実装します

必要なもの:

constructor(public navCtrl: NavController, private transfer: FileTransfer, private file: File, private webIntent: WebIntent) {
    const fileTransfer: FileTransferObject = this.transfer.create();
    const url = 'urlApkFile';//Modified this
    fileTransfer.download(url, this.file.externalDataDirectory + 'file.apk').then((entry) => 
    {
        webIntent.startActivity({
            action: (window).plugins.intentShim.ACTION_INSTALL_PACKAGE,
            url: entry.toURL(),
            type: 'application/vnd.Android.package-archive'
        }).then(function () {
            //OK
        }, function (e) {
            alert('Error launching app update' + JSON.stringify(e));
        });
    }, (error) => {
        alert("downdload finish" + JSON.stringify(error));
    });
}
    
0
DanielGatti