【问题标题】:Download apk and start install prompt inside android application下载apk并在android应用程序中开始安装提示
【发布时间】:2012-12-09 17:56:21
【问题描述】:

我正在构建一个私有企业 Android 应用程序。我的目标是检测何时有可用更新并为用户提供下载。如果用户选择下载更新文件,则下载并显示安卓应用安装提示。

我成功检查更新,问题是没有下载apk文件(创建了空文件)因此“解析包时出现问题。” android 应用安装提示中显示错误。

代码:

public void downloadfileto(String fileurl, String filename) { 
    String myString; 
    try { 
            FileOutputStream f = new FileOutputStream(filename); 
            try { 
                    URL url = new URL(fileurl); 
                    URLConnection urlConn = url.openConnection(); 
                    InputStream is = urlConn.getInputStream(); 
                    BufferedInputStream bis = new BufferedInputStream(is, 8000); 
                    int current = 0; 
                    while ((current = bis.read()) != -1) { 
                            f.write((byte) current); 
                    } 
            } catch (Exception e) { 
                    myString = e.getMessage(); 
            } 
            f.flush(); 
            f.close(); 
            install(filename);
    } catch (FileNotFoundException e) { 
            e.printStackTrace(); 
    } catch (IOException e) { 
            e.printStackTrace(); 
    } 
} 

protected void install(String fileName) {
    Intent install = new Intent(Intent.ACTION_VIEW);
    install.setDataAndType(Uri.fromFile(new File(fileName)),
            "application/vnd.android.package-archive");
    startActivity(install);
}

函数 downloadfileto 被调用:

downloadfileto("http://some-url/ind.apk", "data/data/my.package.name/app.apk");

【问题讨论】:

  • 您在目录中缺少前导“/”,但是您应该在运行时发现私有存储的位置,而不是假设给定设备将分配给您的目录。此外,您可能需要验证是否可以从私人存储安装,而不是像 sdcard 这样的公共存储。由于您没有使用安全链接,因此您可能只需交出 URL,而无需自己下载。
  • 感谢您指出这一点,问题仍然存在。
  • 验证您是否可以在此位置创建和写入文件,并使用 getFilesDir() 或其他任何方法,而不是对路径进行硬编码。您需要在模拟器上进行测试或在 adb shell 中使用 run-as 来查看私有目录中的文件。
  • 我正在根手机上测试应用程序。在 DDMS 中,我可以看到文件已在给定目录中成功创建,但它是空的(0 字节大)。
  • @erum-hannan 我在 MySQL 数据库中保存了应用程序的版本和 apk 的物理位置。然后,Android 应用程序向一个简单的 PHP 脚本发送请求,该脚本以最新版本和 URL 响应最新的 apk。然后,Android 应用程序会比较是否有较新版本,如果 true 下载它并向用户提供更新(在接受的答案中检查我的代码)

标签: android


【解决方案1】:

即使您下载成功,您也无法安装 APK 文件,因为安装程序进程将无法读取该文件。此外,正如 Chris Stratton 所指出的,您的硬编码路径是草率的(在 Android 4.1 及更早版本上)并且是灾难性的(在 Android 4.2 及更高版本上)。

就下载逻辑而言,一次下载一个字节的性能不太可能很好。尝试这样的事情(对于名为 outputFile 和名为 urlURL):

  HttpURLConnection c=(HttpURLConnection)url.openConnection();

  c.setRequestMethod("GET");
  c.setReadTimeout(15000);
  c.connect();

  FileOutputStream fos=new FileOutputStream(output.getPath());
  BufferedOutputStream out=new BufferedOutputStream(fos);

  try {
    InputStream in=c.getInputStream();
    byte[] buffer=new byte[8192];
    int len=0;

    while ((len=in.read(buffer)) > 0) {
      out.write(buffer, 0, len);
    }

    out.flush();
  }
  finally {
    fos.getFD().sync();
    out.close();
  }

【讨论】:

    【解决方案2】:

    我要感谢大家在这里的帮助。我通过在服务器上打开 php 脚本解决了这个问题,该脚本使用 Web 视图计算下载量、检测下载、下载路径和启动活动以安装应用程序。

    文件名始终采用“ind-version.apk”形式(例如:ind-1-0.apk),因为当我检查更新时我会得到新更新的版本号,所以我决定将它放在附加文件中用它来确定文件名。

    代码:

        WebView myWebView = (WebView) findViewById(R.id.helpview);
        showDialog();
        myWebView.setWebViewClient(new WebViewClient());
    
        myWebView.loadUrl(url);
        myWebView.getSettings().setJavaScriptEnabled(false);
    
        myWebView.setWebViewClient(new WebViewClient() {
             @Override  
             public void onPageFinished(WebView view, String url) {
                 super.onPageFinished(view, url);
                 dismissDialog();
             }  
        });
    
        myWebView.setDownloadListener(new DownloadListener() {
            public void onDownloadStart(String url, String userAgent,
                    String contentDisposition, String mimetype,
                    long contentLength) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse(url));
                startActivity(intent);
    
                Bundle extras = getIntent().getExtras();
                String v = extras.getString("v");
                v = v.replace(".", "-");
                Log.i("File", v);
    
                File loc = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
                Log.i("File", loc.toString() + "/ind-" + v + ".apk");
    
                install(loc.toString() + "/ind-" + v + ".apk");
            }
        });
    

    然后安装:

    protected void install(String fileName) {
        Intent install = new Intent(Intent.ACTION_VIEW);
        install.setDataAndType(Uri.fromFile(new File(fileName)),
                "application/vnd.android.package-archive");
        startActivity(install);
    }
    

    【讨论】:

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