【问题标题】:Phonegap Android app trigger update programmaticallyPhonegap Android应用程序以编程方式触发更新
【发布时间】:2013-04-08 13:50:18
【问题描述】:

我正在构建一个托管在 Google Play 之外的服务器上的 Android 应用。我需要应用程序检查新版本并在应用程序启动时提示用户更新。

我建立了一种机制来检查新版本(应用程序检查服务器上的文件并比较版本),该机制运行良好。然后我提示用户更新,但如果用户选择继续更新,我无法触发下载和安装 apk。

我尝试简单地打开 apk 网址:

window.open(apkURL);

其中 apkURL 是服务器上托管的 .apk 文件的完整 http 链接。

但它似乎没有做任何事情。

我一直在研究,但找不到有关如何执行此操作的答案。我发现了一些使用本机代码的建议,比如这篇文章Install Application programmatically on 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 应用程序中完成这样的事情?

谢谢!

【问题讨论】:

    标签: android cordova auto-update


    【解决方案1】:

    我终于设法实现了这一点,使用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);
    });
    

    【讨论】:

    • 使用phonegap安装apk后如何自动启动该apk? fileapi 或 webintent 插件中是否有任何特定方法,请告诉我
    • 我想从download.com/update/myapp.apk 下载更新。那么代码会是什么呢?请帮忙。
    【解决方案2】:

    对于使用 Cordova 3+ 的你们,类似 Vero 的解决方案是可能的:

    所以我们首先要下载 .apk 文件。为此,我们需要文件传输插件。 您可以使用以下命令安装它:

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

    其次,我们需要另一个插件来启动 webintent。如果有更新,此 webintent 会提示用户。您可以使用以下命令安装它:

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

    【讨论】:

    • 感谢您的回答。 downloadApkAndroid 函数中的“数据”参数是什么?你能分享一个调用它的例子吗?
    • 只是一个字符串数组,'data.android'包含要下载的APK的URL。
    • 如何调用该函数? downloadApkAndroid({ android: "/files/app.apk" })
    • 这几乎对我有用,除了我不断收到“解析错误 - 解析包时出现问题”警报。将 fileURL 更改为此解决了我的问题: var fileURL = cordova.file.externalDataDirectory + '.apk'
    【解决方案3】:

    遗憾的是,如果不使用插件,您无法在 Phonegap Web 容器中访问这种原生功能,您所能做的就是将用户链接到 apk(例如通过打开原生浏览器)并让他安装它。

    【讨论】:

    • 感谢您的回答。我现在正在检查webintent phonegap 插件,看看它是否可以工作。当您说指向 apk 的链接时,它是常规链接吗?为什么链接有效,但我的 window.open 无效?谢谢。
    • 当然使用插件可以绕过Cordova的限制,我不知道这个插件,但我认为它应该可以工作。通过链接,我实际上是在考虑打开本机浏览器以使用类似 navigator.app.loadUrl 的方式打开 apk。
    【解决方案4】:

    谢谢 Vero 的回答......这对我帮助很大...... 上一个版本的cordova文件插件中的代码有问题。 如果您使用文件插件版本 1.0.0 或更高版本,请将 entry.fullPath 替换为 entry.toURL()。 如果你使用 entry.fullPath ,它会抛出错误'解析包有问题'。

    from file-transfer plugin on github

    这些路径以前在 File 插件返回的 FileEntry 和 DirectoryEntry 对象的 fullPath 属性中公开。但是,新版本的 File 插件不再向 JavaScript 公开这些路径。

    如果您要升级到 File 的新版本(1.0.0 或更高版本),并且您之前一直使用 entry.fullPath 作为 download() 或 upload() 的参数,那么您需要将代码更改为改用文件系统 URL。

    FileEntry.toURL() 和 DirectoryEntry.toURL() 返回表单的文件系统 URL

    cdvfile://localhost/persistent/path/to/file 在 download() 和 upload() 方法中都可以使用它来代替绝对文件路径。

    【讨论】:

      【解决方案5】:

      2018 年的工作示例

      基于以前的 cmets 我实现了这个解决方案

      需要:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多