强制更新Android应用程序,当新版本可用
我有一个在谷歌Play商店的应用程序。 当更新版本可用时,旧版本将变得不可行,即如果用户不更新应用程序,他们不进入应用程序。请帮我解决这个问题..
我同意Scott Helme的观点。 但是,在一些极端的情况下(安全问题,API中断的变化…),你绝对需要用户更新以继续使用应用程序,你可以提供一个简单的版本控制API。 API看起来像这样:
versionCheck API:
请求参数:
int appVersion
响应
-
boolean forceUpgrade
-
boolean recommendUpgrade
当您的应用程序启动时,您可以调用在当前应用程序版本中传递的此API,并检查版本控制API调用的响应。
如果forceUpgrade
为true
,则显示一个popup对话框,其中包含允许用户退出应用程序的选项,或者转到Google Play商店升级应用程序。
否则,如果recommendUpgrade
为true
,显示popup对话框的选项来更新或继续使用该应用程序。
即使有这种强制升级能力,除非绝对需要,否则应该继续支持旧版本。
一旦有新版本发布,您不应该停止支持旧版本。 这将导致糟糕的用户体验。 我不知道有这样的软件供应商,这是有原因的。
如果用户当时不能更新或不想要,会发生什么情况? 他们根本无法使用你的应用程序,这是不好的。
谷歌不提供这样的版本跟踪任何选项,所以你将不得不推出自己的。 一个简单的Web服务来返回您的应用程序可以检查的当前实时版本就足够了。 然后你可以更新版本,应用程序会知道它已经过时了。 我只会build议使用这个function,让用户知道有一个更新比依赖于Google Play更快。 它不应该真的被用来阻止应用程序工作,只是为了提示用户更新。
试试这个:首先,你需要调用playstore链接,从那里获取当前版本,然后将它与当前版本进行比较。
String currentVersion, latestVersion; Dialog dialog; private void getCurrentVersion(){ PackageManager pm = this.getPackageManager(); PackageInfo pInfo = null; try { pInfo = pm.getPackageInfo(this.getPackageName(),0); } catch (PackageManager.NameNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } currentVersion = pInfo.versionName; new GetLatestVersion().execute(); } private class GetLatestVersion extends AsyncTask<String, String, JSONObject> { private ProgressDialog progressDialog; @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected JSONObject doInBackground(String... params) { try { //It retrieves the latest version by scraping the content of current version from play store at runtime Document doc = Jsoup.connect(urlOfAppFromPlayStore).get(); latestVersion = doc.getElementsByAttributeValue ("itemprop","softwareVersion").first().text(); }catch (Exception e){ e.printStackTrace(); } return new JSONObject(); } @Override protected void onPostExecute(JSONObject jsonObject) { if(latestVersion!=null) { if (!currentVersion.equalsIgnoreCase(latestVersion)){ if(!isFinishing()){ //This would help to prevent Error : BinderProxy@45d459c0 is not valid; is your activity running? error showUpdateDialog(); } } } else background.start(); super.onPostExecute(jsonObject); } } private void showUpdateDialog(){ final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("A New Update is Available"); builder.setPositiveButton("Update", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse ("market://details?id=yourAppPackageName"))); dialog.dismiss(); } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { background.start(); } }); builder.setCancelable(false); dialog = builder.show(); }
斯科特和迈克尔的答案是正确的。 托pipe一个提供您支持的最小版本号的服务,并将其与安装的版本进行比较。 你应该希望永远不需要使用这个,但是如果某个版本在外面,那么这是一个救命的人,因为一些严重的缺陷,你绝对必须杀死它。
我只是想添加下一步做什么的代码。 以下是您如何启动Google Play Intent并在提示用户必须升级之后将其带到商店中的新版本。
public class UpgradeActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_upgrade); final String appName = "com.appname"; Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+appName))); } }); } }
如果必须在每个版本上强制升级,则应重新考虑devise。
定义我们自己的升级过程更好。
- 创build一个web服务,从我们的服务器提供最新版本的应用程序(ios,android)。
- 或者您在应用程序中使用的任何Web服务(例如,login)将从服务器返回最新的应用程序版本。
- 一旦应用程序将获得#1或2的版本。应用程序将与本地/ cuurent appversion进行交叉检查。 如果有差异,那么我们可以显示如下警报,
Android和iOS:如果最新的应用版本可用,那么它会显示警报为“最新版本提供更多的function,升级点击升级button”(Alert With“Upgarde”和“No. Thanks”button)。然后,应用程序将redirect到playstore / Appstore,它会打开最新版本。
--- we can do upgrade compulsory or optionally.
在升级过程之前,请确保您处理了适当的数据库迁移过程,如果有任何数据库模式更改。
我强烈build议检查Firebase的远程configurationfunction。
我使用参数“app_version_enabled”实现了它,条件为“禁用Android版本”,如下所示:
applies if App ID == com.example.myapp and App version regular expression ^(5.6.1|5.4.2)
参数的默认值为“true”,但“禁用Android版本”的值为false。 在我的禁用Android版本的正则expression式中,您可以在这些括号内添加更多的禁用版本,只需添加另一个|{version name}
。
然后我只是检查configuration是否显示版本是否启用 – 我有一个活动,我启动,强制用户升级。 我检查了应用程序只能从外部启动的两个地方(我的默认启动器活动和意向处理活动)。 由于远程configuration在caching的基础上工作,它不会立即捕获应用程序的“禁用”的版本,如果没有超过必要的时间使caching失效,但是如果您要通过最多12小时他们build议的caching过期值。
如果市场上有更新,迫使应用用户更新,则应首先检查市场上的应用版本,并将其与设备上的应用版本进行比较。 如果它们不同,则可能是可用的更新。 在这篇文章中,我写下了获取设备上当前版本的市场和当前版本的代码,并将它们进行比较。 我还展示了如何显示更新对话框并将用户redirect到更新页面。 请访问此链接: https : //stackoverflow.com/a/33925032/5475941只要确保在对话框中,您只显示用户更新button,不要显示取消button。 在这种情况下,他将被迫更新,然后才能使用该应用程序。
您可以通过在variables中保存在应用程序中的版本号之间进行匹配来执行此操作,并且类似地将当前应用程序版本保存在服务器端,并且每次用户打开应用程序时,第一个请求应该被发送以检查是否发现匹配不做任何事情,只是让用户使用你的应用程序,否则火意图的谷歌Playstore或打开一个Web视窗到您的应用程序(window.open(“ https://play.google.com/store/apps/details?id= package_name “,”_system“,”location = yes“);在那里,他们将自动有button要求更新,这是谷歌playstore为你做的,如果你没有自动更新。
您可以通知您的用户可以更新当前应用程序的新版本。 此外,如果这种情况是真的,你可以阻止login的应用程序。
请看看这是否为您提供解决scheme。
检查本地和Play商店apk版本的代码
try { versionChecker VersionChecker = new versionChecker(); String versionUpdated = VersionChecker.execute().get().toString(); Log.i("version code is", versionUpdated); PackageInfo packageInfo = null; try { packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } int version_code = packageInfo.versionCode; String version_name = packageInfo.versionName; Log.i("updated version code", String.valueOf(version_code) + " " + version_name); if (version_name != versionUpdated) { String packageName = getApplicationContext().getPackageName();// UpdateMeeDialog updateMeeDialog = new UpdateMeeDialog(); updateMeeDialog.showDialogAddRoute(MainActivity.this, packageName); Toast.makeText(getApplicationContext(), "please updated", Toast.LENGTH_LONG).show(); } } catch (Exception e) { e.getStackTrace(); }
实现版本检查的类
class versionChecker extends AsyncTask<String, String, String> { String newVersion; @Override protected String doInBackground(String... params) { try { newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=+YOR_PACKAGE_NAME+&hl=en") .timeout(30000) .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6") .referrer("http://www.google.com") .get() .select("div[itemprop=softwareVersion]") .first() .ownText(); } catch (IOException e) { e.printStackTrace(); } return newVersion; } }
dialob盒更新
public class UpdateMeeDialog { ActivityManager am; TextView rootName; Context context; Dialog dialog; String key1,schoolId; public void showDialogAddRoute(Activity activity, final String packageName){ context=activity; dialog = new Dialog(context); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setCancelable(false); dialog.setContentView(R.layout.dialog_update); am = (ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE); Button cancelDialogue=(Button)dialog.findViewById(R.id.buttonUpdate); Log.i("package name",packageName); cancelDialogue.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("https://play.google.com/store/apps/details? id="+packageName+"&hl=en")); context.startActivity(intent); } }); dialog.show(); } }
对话框布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#d4e9f2"> <TextView android:layout_width="match_parent" android:layout_height="40dp" android:text="Please Update First..!!" android:textSize="20dp" android:textColor="#46a5df" android:textAlignment="center" android:layout_marginTop="50dp" android:id="@+id/textMessage" /> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:weightSum="1" android:layout_marginTop="50dp" android:layout_below="@+id/textMessage" android:layout_height="50dp"> <Button android:id="@+id/buttonUpdate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Update" android:background="#67C6F1" android:textAlignment="center" /> </LinearLayout>