Android App版本更新服务,但未将其发布到市场

时间:2014-08-14 19:26:14

标签: android apk

最近我要开展一个项目,其中的要求很奇怪。我被要求开发一个应用程序,不会上传到任何市场,如Playstore或任何其他Android应用程序商店。它将简单地上传到云端,以便在用户之间分发APK。

在用户设备上安装应用程序后,当发布新版本时,将通知用户(通知不下载新版本并重新安装,但授予权限和更新)。在用户授予权限后,应用程序将会更新。没有市场帮助,最好的方法是什么?

我的想法:

  1. 使用GCM(Google云消息传递)通知用户并提供新版本链接。
  2. 用户将点击该链接,将下载新版本并替换上一版本(android默认版本替换)
  3. 有没有更聪明的方法来实现我想要实现的目标?

3 个答案:

答案 0 :(得分:4)

我发现,最好的办法是托管apk和最新版本的文本文件。

打开应用程序,检查当前v#与服务器上托管的那个,如果它们不匹配,请抓住新的。

除非您的应用程序作为后台服务工作,否则无需推送任何内容,并且您需要确保用户是否使用最新版本,无论他们是否使用它。

如果是这种情况,您可以拥有一天一次或类似的服务。

编辑 - 下载后,要安装apk,请使用以下代码。

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

Install Application programmatically on Android

答案 1 :(得分:4)

以下是我为此目的使用的一些代码。你将不得不调整一些,因为我懒得把它剥掉。 (遗憾)。

所以,在onCreate of my Activity中我有:

new FetchLatestVersion().execute(); 

检查并获取最新版本的代码(+启动安装程序)。

    private class FetchLatestVersion extends AsyncTask<Void, Void, Integer> {

    @Override
    protected Integer doInBackground(Void... param) {

        String inputLine = "-1";
        BufferedReader in = null;
        try {
            URL update_url = new URL(UPDATE_VERSIONCHECK_URL);
            in = new BufferedReader(new InputStreamReader(
                    update_url.openStream()));

            while ((inputLine = in.readLine()) != null) {
                return Integer.parseInt(inputLine);
            }

        } catch (IOException e) {
            Log.e(TAG, inputLine, e);
        } catch (NumberFormatException e) {
            Log.e(TAG, inputLine, e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {

            }
        }
        return -1;

    }

    @Override
    protected void onPostExecute(Integer result) {
        if (result > device.getVersionCode()) {
            // Toast.makeText(
            // getApplicationContext(),
            // "current version: " + device.getVersionCode() + "\n"
            // + "new version: " + result, Toast.LENGTH_SHORT)
            // .show();
            // pref.putBoolean(PREF_HAS_UPDATE, true);
            showDownloadOption();
        }
    }

}

private void showDownloadOption() {
    findViewById(R.id.new_update).setVisibility(View.VISIBLE);
}

@OnClick(R.id.button_download)
public void update(Button button) {
    if (mDownloadTask != null
            && mDownloadTask.getStatus() == Status.RUNNING) {
        mDownloadTask.cancel(true);
    }
    mDownloadTask = new DownloadUpdate();
    mDownloadTask.execute();
}

private class DownloadUpdate extends AsyncTask<Void, Void, File> {

    public ProgressDialog working_dialog;

    private String toastMsg = "";

    @Override
    protected void onPreExecute() {
        working_dialog = ProgressDialog.show(context, "",
                context.getString(R.string.working), true);
    }

    @Override
    protected File doInBackground(Void... param) {

        String filename = "YOURAPP.apk";

        HttpURLConnection c = null;
        try {
            URL url = new URL(UPDATE_DOWNLOAD_URL);
            c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();
        } catch (IOException e1) {
            toastMsg = context
                    .getString(R.string.could_not_connect_to_server);
            return null;
        }

        File myFilesDir = new File(Environment
                .getExternalStorageDirectory().getAbsolutePath()
                + "/Download");

        File file = new File(myFilesDir, filename);

        if (file.exists()) {
            file.delete();
        }

        if ((myFilesDir.mkdirs() || myFilesDir.isDirectory())) {
            try {
                InputStream is = c.getInputStream();
                FileOutputStream fos = new FileOutputStream(myFilesDir
                        + "/" + filename);

                byte[] buffer = new byte[1024];
                int len1 = 0;
                while ((len1 = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, len1);
                }
                fos.close();
                is.close();
            } catch (Exception e) {
                toastMsg = context
                        .getString(R.string.missing_internet_connection);
            }
        }

        return file;
    }

    @Override
    protected void onPostExecute(File file) {

        if (!toastMsg.isEmpty()) {
            Toast.makeText(context, toastMsg, Toast.LENGTH_LONG).show();
        } else {
            launchInstaller(file);
        }

        removeWorkingDialog();
    }

    private void removeWorkingDialog() {
        if (working_dialog != null && working_dialog.isShowing()) {
            working_dialog.dismiss();
            working_dialog = null;
        }
    }

}

public void launchInstaller(File apkFile) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(apkFile),
            "application/vnd.android.package-archive");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivityForResult(intent, 0);
}

答案 2 :(得分:1)

我进行了少量的挖掘,并找到了一个完全正确的库。 我没有使用它,但它出现在其他一些相关的SO问题中。

https://github.com/RaghavSood/AppaholicsUpdateChecker