回答:
ここでの別の回答におけるScott Helmeのポイントに同意します。ただし、アプリの使用を継続するにはユーザーに更新を絶対に必要とする極端な状況(セキュリティの問題、APIの重大な変更など)では、単純なバージョン管理APIを提供できます。APIは次のようになります。
versionCheck API:
リクエストパラメータ:
int appVersion応答
boolean forceUpgradeboolean recommendUpgradeアプリの起動時に、現在のアプリのバージョンを渡すこのAPIを呼び出して、バージョン管理API呼び出しの応答を確認できます。
の場合forceUpgradeはtrue、ユーザーにアプリの終了を許可するか、Google Playストアにアクセスしてアプリをアップグレードするかのオプションを含むポップアップダイアログを表示します。
そうでない場合recommendUpgradeはtrue、更新するか、アプリの使用を継続するかを選択するポップアップダイアログを表示します。
この強制アップグレード機能が導入されている場合でも、絶対に必要でない限り、引き続き古いバージョンをサポートする必要があります。
これを試してください:まず、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.getElementsByClass("htlgb").get(6).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();
}
新しいバージョンが出たらすぐに古いバージョンのサポートを停止しないでください。これはひどいユーザー体験をもたらします。正当な理由により、これを行うソフトウェアベンダーは存在しません。
ユーザーがその時点で更新できない、または更新したくない場合はどうなりますか?彼らは単にあなたのアプリを使用することができません、それは悪いことです。
Googleはそのようなバージョントラッキングのオプションを提供していないため、独自にロールする必要があります。アプリがチェックできる現在のライブバージョンを返す単純なWebサービスで十分です。その後、バージョンを更新すると、アプリはそれが古いことを認識します。これを使用して、Google Playに依存するよりも早くアップデートがあることをユーザーに知らせることをお勧めします。アプリの動作を妨げるために実際に使用するのではなく、ユーザーに更新を促すだけです。
Googleチームのソリューション
Android 5.0以降、これは新しいGoogle Play In Appアップデートメカニズムを通じて簡単に実現できます。要件は、バージョン1.5.0以降のPlay Coreライブラリがあり、apksの代わりにApp Bundles idstributionを使用することです。
ライブラリは、ユーザーに更新について通知する2つの異なる方法を提供します。
アプリがバックグラウンドで更新されている間、ユーザーがアプリを使い続けることができる場合の柔軟性。
即時-ユーザーがアプリを更新するまでアプリを入力できないブロック画面。
それを実装する次のステップがあります:
これらの手順の実装はすべて公式サイトで詳細に説明されています:https : //developer.android.com/guide/app-bundle/in-app-updates
スコットとマイケルの答えは正しいです。サポートする最小バージョン番号を提供するサービスをホストし、インストールされているバージョンと比較します。あなたはうまくいけばこれを使う必要はないはずですが、あるバージョンがそこにある場合、深刻な欠陥のために絶対に殺さなければならないので、それは命の恩人です。
次に何をするかというコードを追加したかっただけです。次に、Google Playインテントを起動し、アップグレードする必要があることをユーザーに尋ねた後、ストアで新しいバージョンに移行する方法を示します。
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)));
}
});
}
}
各リリースでアップグレードを強制する必要がある場合は、設計を再検討する必要があります。
Googleはアプリ内アップデートライブラリ(https://developer.android.com/guide/app-bundle/in-app-updates)を導入しました。これはLollipop +で動作し、ユーザーに素晴らしいアップデートを要求する機能を提供しますダイアログ(FLEXIBLE)または必須の全画面メッセージ(IMMEDIATE)。
私はこの回答のすべてのコードをカバーしました:https://stackoverflow.com/a/56808529/5502121
これについては、FirebaseのRemote Config機能を確認することを強くお勧めします。
パラメータ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バージョンの正規表現では、|{version name}括弧内に別のバージョンを追加するだけで、無効なバージョンをさらに追加できます。
次に、構成でバージョンが有効になっているかどうかを確認します-ユーザーにアップグレードを強制するアクティビティを起動します。アプリを外部から起動できるのは2か所だけです(私のデフォルトのランチャーアクティビティとインテント処理アクティビティ)。Remote Configはキャッシュベースで機能するため、キャッシュを無効にするために必要な時間が経過していない場合、アプリの「無効な」バージョンはすぐにはキャプチャされませんが、次の場合は最大12時間です推奨されるキャッシュ有効期限値。
公式にこれのためにAndroid APIを提供しています。
APIは現在、少数のパートナーでテストされており、間もなくすべての開発者が利用できるようになります。
Update APIが利用可能になりました-https://developer.android.com/guide/app-bundle/in-app-updates
ローカルのバージョンコードを確認し、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>
アップグレードのために独自のプロセスを定義することをお勧めします。
AndroidおよびiOS: 最新のアプリバージョンが利用可能な場合、「最新バージョンが利用可能です。機能を追加するには、アップグレードボタンをクリックしてください」というアラートが表示されます(「アップガード」と「いいえありがとうございます」ボタンでアラートが表示されます)。 playstore / Appstoreと最新バージョンを開きます。
--- we can do upgrade compulsory or optionally.
アップグレードプロセスの前に、dbスキーマの変更がある場合は、適切なdb移行プロセスを処理したことを確認してください。
マーケットでアップデートが入手可能な場合にアプリユーザーにアップデートを強制するには、まずマーケットでアプリのバージョンを確認し、デバイス上のアプリのバージョンと比較する必要があります。それらが異なる場合、利用可能なアップデートである可能性があります。この投稿では、市場の現在のバージョンとデバイスの現在のバージョンを取得するコードを書き留め、それらを比較しました。また、更新ダイアログを表示し、ユーザーを更新ページにリダイレクトする方法も示しました。次のリンクにアクセスしてください:https : //stackoverflow.com/a/33925032/5475941ダイアログでユーザー更新ボタンのみを表示し、キャンセルボタンは表示しないようにしてください。この場合、アプリを使用する前に、更新を強制されます。
ここで間違いなく言及すべきことは、間もなくリリースされるアプリ内アップデートAPIです。
このAPIには2つのオプションがあります。1つ目は、ユーザーが更新がすぐに適用されるのを待つことを期待する場合の重要な更新の全画面表示です。2番目のオプションは柔軟な更新です。つまり、ユーザーは更新のダウンロード中もアプリを使い続けることができます。更新フローを完全にカスタマイズして、アプリの一部のように感じることができます。
アプリバージョンにリモート構成を使用し、起動アクティビティを常にチェックインすることをお勧めします。現在のアプリバージョンはリモートバージョンと同じか、アプリストアからの更新を強制しない場合はそうではありません。
シンプルなロジックハッピーコーディング
Play Core Libraryアプリ内アップデートを使用してこれに取り組むことができます。アップデートが利用可能かどうかを確認し、シームレスに利用できる場合はインストールできます。
アプリ内アップデートは、APK拡張ファイル(.obbファイル)を使用するアプリと互換性がありません。柔軟なダウンロードか、Google Playが更新のダウンロードとインストールを処理する即時更新のどちらかを選択できます。
dependencies {
implementation 'com.google.android.play:core:1.5.0'
...
}
この回答を参照してくださいhttps://stackoverflow.com/a/58212818/7579041
これは、アプリで変数に保持されているバージョン番号と同様に現在のアプリのバージョンがサーバー側で保持され、ユーザーがアプリを開くたびに最初のリクエストを送信して、アプリが見つかったかどうかを確認することによって行うことができます。一致しても何もしないで、単にユーザーがアプリを使用できるようにします。それ以外の場合は、Google Playstoreにインテントを起動するか、アプリのウェブビューウィンドウを開きます(window.open( " https://play.google.com/store/apps/details?id= package_name "、 '_system'、 'location = yes');)そして、自動更新が有効になっていない場合、Google Playstoreが実行する更新を要求するボタンが自動的に表示されます。
更新可能な現在のアプリの新しいバージョンがあることをユーザーに通知できます。また、この条件に該当する場合は、アプリへのログインをブロックできます。
これがあなたに解決策を提供するかどうか確認してください。
ええと、アプリページ(Google Playアプリページ)からバージョンコードをこするなど、この問題には多くの解決策がある可能性があります。
しかし、私はあなたにペニーの費用がかからず、魔法のように機能する究極のソリューションを紹介します。
次のコードで取得できるアプリの現在のバージョンコードと比較します。
private int getCurrentVersionCode() {
try {
return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return -1;
}
取得したバージョンコードが現在のバージョンより大きい場合は、アプリの更新を要求するAlertDialogを表示します。それ以外の場合、アプリはすでに更新されています。
そのため、新しいバージョンを公開するときはいつでも、その新しいバージョンのコードをFirebase Remote構成パネルに配置する必要があります
Firebase Remote Configを使用してユーザーにアプリを強制的に更新する方法に関するチュートリアル全体を読むことができます
GoogleはPlay Coreライブラリのアプリ内アップデートをリリースしました。
アプリ内アップデートを簡単に実装するために、軽量ライブラリを実装しました。次のリンクに、ユーザーに強制的に更新を実行させる方法の例を示します。
https://github.com/dnKaratzas/android-inapp-update#forced-updates