最近我要开展一个项目,其中的要求很奇怪。我被要求开发一个应用程序,不会上传到任何市场,如Playstore或任何其他Android应用程序商店。它将简单地上传到云端,以便在用户之间分发APK。
在用户设备上安装应用程序后,当发布新版本时,将通知用户(通知不下载新版本并重新安装,但授予权限和更新)。在用户授予权限后,应用程序将会更新。没有市场帮助,最好的方法是什么?
我的想法:
有没有更聪明的方法来实现我想要实现的目标?
答案 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);
答案 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问题中。