Примусове оновлення програми Android, коли доступна нова версія


100

У мене є програма в Google Play Store. Коли доступна версія оновлення, старіша версія стане непридатною для використання, тобто якщо користувачі не оновлять програму, вони не ввійдуть у програму. Як я можу змусити користувачів оновлювати програму, коли з’являється нова версія?


1
Цей проект з відкритим кодом GitHub (MAHAndroidUpdater) повністю забезпечує цю функціональність. Спробуйте, дуже просто. github.com/hummatli/MAHAndroidUpdater
Саттар Гумматлі

Відповіді:


99

Я погоджуюся з думкою Скотта Гельме в іншій відповіді тут. Але в деяких екстремальних ситуаціях (проблеми з безпекою, зміни, що порушують API ...), коли вам абсолютно необхідні оновлення користувачів, щоб продовжувати користуватися програмою, ви можете надати простий API версій. API буде виглядати так:

API API versionCheck:

Параметри запиту:

  • int appVersion

Відповідь

  1. boolean forceUpgrade
  2. boolean recommendUpgrade

Коли ваш додаток запускається, ви можете зателефонувати цьому API, який передає поточну версію програми, і перевірити відповідь виклику API версії.

Якщо forceUpgradeє true, показати спливаюче діалогове вікно з параметрами або дозволити користувачеві вийти з програми, або перейти в Google Play Store , щоб оновити додаток.

Інакше, якщо recommendUpgradeє true, покажіть спливаюче діалогове вікно з опціями оновлення або продовження використання програми.

Навіть із наявною можливістю примусового оновлення, ви повинні продовжувати підтримувати старіші версії, якщо це абсолютно не потрібно.


Чи могли б ви показувати спливаюче вікно кожного разу, коли програма запускається, і рекомендувати, щоб оновлення відповідало дійсності? (з точки зору UX) Або просто покажіть спливаюче вікно один раз і більше не показуйте, якщо користувач відмовляється від оновлення.
Aneesh

8
Для рекомендованого оновлення, я думаю, вам не слід показувати знову, якщо користувач відхилив. Ви також можете показати це "раз на n раз, коли користувач відкривав програму". Ви можете самі визначити значення n і реалізувати це.
Майкл

3
кращим рішенням imo є систематичне передавання версії програми в заголовок усіх викликів API, а потім повернення API певного коду стану, якщо виявить, що версія застаріла. а потім обробити це всередині програми. це краще, ніж викликати ще один спеціальний API для цієї перевірки, і потрібно точно з’ясувати, коли / де цей виклик API повинен бути зроблений всередині програми / служби.
Рафаель С

@RaphaelC Це насправді залежить від реалізації на стороні вашого сервера. Також не ідеально додати фільтр, який перевіряє версію всіх API в деяких ситуаціях.
вересень GH

4
З того часу ситуація в @SepGH змінилася, і Android тепер пропонує API, який ви можете використовувати, щоб змусити користувача оновити і заблокувати його від подальшого використання програми, якщо він не перейде на мінімальну версію: developer.android.com/guide/ app-bundle / in-app-updates
Raphael C

55

спробуйте це: Спочатку вам потрібно зробити дзвінок із запитом на посилання магазину, отримати звідти поточну версію, а потім порівняти її з поточною версією.

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();
    }

1
Я думаю, для цього потрібно буде додати зовнішню бібліотеку JSoup?
Авраам Філіп

1
Так, але це було б для отримання сторінки html div. Я хотів сказати, що для досягнення цієї функціональності вам може не знадобитися будь-яка стороння бібліотека, якщо ви можете зішкребти цей елемент html без JSoup, все одно це буде працювати
AshuKingSharma

1
що якщо вони змінять значення itemprop ??
asok Buzz,

1
Якщо вони змінять значення itemprop, то це вплине і на мої додатки, я відразу ж відредагую свою відповідь, щоб підтримати це, тому не хвилюйтеся до цього часу :)
AshuKingSharma

Nice setCancelable (false)
Kai Wang

46

Не слід припиняти підтримку старої версії, як тільки з’явиться нова. Це призведе до жахливого користувацького досвіду. Я не знаю жодного постачальника програмного забезпечення, який би це робив, з поважної причини.

Що станеться, якщо користувач не може оновити або не бажає цього в той час? Вони просто не можуть користуватися вашим додатком, що погано.

Google не надає жодних можливостей для відстеження версій, подібних цим, тому вам доведеться прокручувати власні. Простий веб-сервіс для повернення поточної актуальної версії, яку може перевірити ваш додаток, був би достатнім. Потім ви можете оновити версію, і програма дізнається, що вона застаріла. Я б рекомендував використовувати це лише для того, щоб ваші користувачі повідомили, що оновлення відбувається швидше, ніж залежно від Google Play. Насправді його не слід використовувати для запобігання роботі програми, а лише для спонукання користувача до оновлення.


2
@ashraful, якщо ця чи будь-яка відповідь вирішила ваше запитання, подумайте про його прийняття , натиснувши галочку. Це вказує на широке співтовариство, що ви знайшли рішення, і надає певну репутацію відповідачеві та вам самим. Цього не потрібно робити.
Суфіян

Відповідь суб’єктивна щодо того, скільки постачальників програмного забезпечення Ви ВІДОМО існуєте. Чи можете ви це кількісно визначити?
Lou Morda

1
Чи можна отримати поточну версію програми з магазину додатків чи магазину ігор? чи мені потрібно зберігати останню версію програми на своєму сервері? Оскільки зараз на моєму сервері є сервісний дзвінок для повернення останньої версії програми, але труднощі виникають щоразу, коли потрібно оновлювати сервер під час публікації програми. Отже, чи можна отримати номер поточної версії у відповідних магазинах?
субха

2
Supercell підтримує лише останню версію своїх ігор. Після того, як вони надіслали нову версію до Google Play, будь-який старший клієнт, який намагається підключитися, отримає відповідь "потрібно оновити" від сервера і побачить, що зв’язок закрито. Вони роблять це кілька разів на рік. Тож якщо ви не хочете вважати "ігрову компанію" "продавцем програмного забезпечення", тепер ви це знаєте :) Враховуючи, що вони все ще заробляють пару мільйонів доларів щодня, мабуть, цей жахливий досвід користувачів не є пробкою шоу. .
Arjan

@Subha Так, це можливо. Але для цього не існує офіційного API, тому вам потрібно буде скребти веб-сторінки. Це також означає, що він може зламатися, якщо веб-сторінка зміниться. Я зробив це в сторонньому додатку, який написав і розмістив тут досить простий код як відповідь . В даний час код працюватиме як на сторінках Play, так і на iTunes. Однак у виробничому середовищі може бути краще шукати рішення, яке автоматично оновило б останню версію програми на сервері, замість того, щоб покладатися на формат сторінок у Google або Apple?
Arjan

27

Рішення від команди Google

Починаючи з Android 5.0, чого легко досягти за допомогою нового механізму оновлення Google Play In App. Вимоги полягають у тому, щоб мати бібліотеку Play Core версії 1.5.0+ та використовувати ідентифікацію пакетів App Bundles замість apk.

Бібліотека пропонує два різні способи повідомити користувачів про оновлення:

  1. Гнучка, коли користувачі можуть продовжувати користуватися програмою, поки вона оновлюється у фоновому режимі.

  2. Негайне - екран блокування, який не дозволяє користувачеві увійти до програми, доки він не оновить її.

Є наступні кроки для його реалізації:

  1. Перевірте наявність оновлень
  2. Почніть оновлення
  3. Отримайте зворотний дзвінок для оновлення стану
  4. Обробляйте оновлення

Всі ці кроки реалізації детально описані на офіційному сайті: https://developer.android.com/guide/app-bundle/in-app-updates


16

Відповіді Скотта і Майкла правильні. Розмістіть службу, яка надає мінімальний номер версії, який ви підтримуєте, та порівняйте її із встановленою версією. Сподіваємось, вам ніколи не доведеться використовувати це, але це порятунок життя, якщо є якась версія, яку ви обов’язково повинні вбити через якийсь серйозний недолік.

Я просто хотів додати код, що робити далі. Ось як ви потім запускаєте 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)));

            }
        });
    }
}

Вам слід переглянути свій дизайн, якщо вам доведеться примусово оновлювати кожен випуск.


11

Google представив додаток lib для оновлень у програмі ( https://developer.android.com/guide/app-bundle/in-app-updates ), він працює на Lollipop + і дає вам можливість запитати оновлення у користувача приємно діалогове вікно (Гнучке) або з обов’язковим повноекранним повідомленням (НЕЗАБАЧНО).

Потрібно реалізувати останнє. Ось як це буде виглядати: введіть тут опис зображення

Я охопив увесь код у цій відповіді: https://stackoverflow.com/a/56808529/5502121


1
Це найкраща відповідь!
fvaldivia

Ця функція насправді покладається на те, що кеш відтворення оновлюється, коли користувач запускає вашу програму, тобто якщо номер версії вашого додатка в кеші не збігається з номером версії вашого останнього розгортання на Playstore, тоді користувач не запитує ..
kiran01bm

6

Я настійно рекомендую перевірити для цього функцію віддаленої конфігурації Firebase .

Я реалізував його за допомогою параметра - 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}всередині цих дужок.

Потім я просто перевіряю, чи конфігурація говорить, що версія ввімкнена чи ні - у мене є запуск, який запускає користувача, що змушує користувача оновити. Я перевіряю лише два місця, з яких додаток можна запустити зовні (моя активність запуску за замовчуванням та діяльність з обробки намірів). Оскільки Remote Config працює на основі кеш-пам'яті, він не відразу захоплюватиме "відключені" версії програми, якщо не минув необхідний час, щоб кеш був анульований, але це не більше 12 годин, якщо ви проходите рекомендоване значення терміну дії кешу.


Це дуже хороший варіант. Вказавши підмножину "вимкнених" версій, ви можете швидко захистити себе, якщо програма має проблеми із безпекою або великі проблеми з продуктивністю. Це дозволяє продовжувати підтримувати кожну версію, але забороняти певну версію, коли виникає необхідність.
Террі

6

Офіційно Google надає для цього API Android.

Наразі API тестується з декількома партнерами і незабаром стане доступним для всіх розробників.

API оновлення вже доступний - https://developer.android.com/guide/app-bundle/in-app-updates



1
Чи доступний цей api зараз?
Яяяя

Я Google це і знайшов , що це developer.android.com/guide/app-bundle/in-app-updates
чуло

Ця функція насправді покладається на те, що кеш відтворення оновлюється, коли користувач запускає вашу програму, тобто якщо номер версії вашого додатка в кеші не збігається з номером версії вашого останнього розгортання на Playstore, тоді користувач не запитує ..
kiran01bm

3

перевірити код версії локального та ігрового магазину 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>


2

Краще визначити наш власний процес для оновлення.

  1. Створіть веб-сервіс, який надає останню версію програми (ios, android) з нашого сервера.
  2. Або будь-яка веб-служба, яку ви використовували в додатку (наприклад, Вхід), поверне найновішу версію програми з сервера.
  3. Як тільки програма отримає версію з №1 або 2. Додаток буде перехресно перевіряти її за допомогою локальної / cuurent appversion. якщо є різниця, тоді ми можемо показати попередження наступним чином,

Android і iOS: якщо доступна остання версія програми, то вона відображатиметься як „Остання версія доступна з додатковими функціями. Для оновлення натисніть кнопку оновлення” (Оповіщення за допомогою кнопки „Upgarde” та „Ні. Дякую”.) Тоді програма перенаправить на playstore / Appstore, і він відкриє останню версію.

 --- we can do upgrade compulsory or optionally.

Перед процесом оновлення переконайтеся, що ви обробили належний процес міграції баз даних, якщо змінилася схема баз даних.


1

Щоб змусити користувача додатка оновлюватись, якщо оновлення доступне на ринку, спочатку слід перевірити версію програми на ринку та порівняти її з версією програми на пристрої. Якщо вони різні, можливо, доступне оновлення. У цій публікації я записав код отримання поточної версії ринку та поточної версії на пристрої та порівняв їх разом. Я також показав, як показати діалогове вікно оновлення та перенаправити користувача на сторінку оновлення. Будь ласка, відвідайте це посилання: https://stackoverflow.com/a/33925032/5475941 Просто переконайтеся, що у діалоговому вікні ви показуєте лише кнопку оновлення користувача, а не кнопку скасування. У цьому випадку він буде змушений оновити, перш ніж він зможе користуватися програмою.


1

Тут слід неодмінно згадати про незабаром випущений API оновлення в додатку .

У вас буде два варіанти використання цього API; перший - це повноекранна робота для критичних оновлень, коли ви очікуєте, що користувач чекатиме негайного застосування оновлення. Другий варіант - гнучке оновлення, що означає, що користувач може продовжувати користуватися програмою під час завантаження оновлення. Ви можете повністю налаштувати потік оновлення, щоб він здавався частиною вашого додатка.


1

Хороша ідея використовувати віддалену конфігурацію для версії програми та завжди перевіряти активність запуску, чи поточна версія програми така ж, як віддалена версія, чи ні, якщо не примусово оновлювати з магазину додатків ..

Просте логічне щасливе кодування ..

https://firebase.google.com/docs/remote-config/android


1

Для вирішення цього питання можна використовувати оновлення в програмі Play Core Library. Ви можете перевірити наявність оновлень та встановити їх, якщо вони доступні без проблем.

Оновлення в додатку несумісні з програмами, які використовують файли розширення APK (файли .obb). Ви можете скористатися гнучкими завантаженнями або негайними оновленнями, які Google Play подбає про завантаження та встановлення оновлення для вас.

dependencies {
    implementation 'com.google.android.play:core:1.5.0'
    ...
}

Зверніться до цієї відповіді https://stackoverflow.com/a/58212818/7579041


0

Ви можете зробити це, виконавши збіг між номером версії, який зберігається в додатку в змінній, і аналогічно поточна версія додатка зберігається на стороні сервера, і кожного разу, коли користувач відкриває програму, перший запит повинен бути надісланий, щоб перевірити, якщо він знаходить збіг нічого не робить, просто дозвольте користувачеві використовувати вашу програму, інакше активуйте намір у магазині Google Play або відкрийте вікно веб-перегляду для вашого додатка (window.open (" https://play.google.com/store/apps/details?id= package_name ", '_system', 'location = yes');) і там у них автоматично з'явиться кнопка з проханням оновити це те, що Google Playstore робить для вас, якщо у вас немає автоматичних оновлень.


0

Ви можете повідомити своїх користувачів, що для оновлення доступна нова версія поточної програми. Крім того, якщо ця умова виконується, ви можете заблокувати вхід у програму.

Будь ласка, перевірте, чи це надає вам рішення.


0

Ну, може бути багато рішень цієї проблеми, таких як скасування коду версії зі сторінки додатка (сторінка додатка Google Play) тощо.

Але я збираюся показати вам остаточне рішення, яке не коштуватиме ні копійки, а буде працювати як магія.

  1. Просто збережіть найновіший код версії програми на
    панелі віддаленої конфігурації Firebase
  2. Отримати це значення коду версії кожного разу, коли програму відкрито
  3. Порівняйте його з поточним кодом версії програми, який ви можете отримати за таким кодом

    private int getCurrentVersionCode() {
    try {
        return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }
    return -1;

    }

Якщо отриманий код версії перевищує поточну версію, покажіть AlertDialog із проханням оновити програму. В іншому випадку програма вже оновлена.

Отже, кожного разу, коли ви випускаєте нову версію, вам потрібно помістити цей новий код версії на панель налаштування Firebase Remote

Ви можете прочитати весь підручник про те, як змусити користувачів оновлювати програму за допомогою віддаленої конфігурації Firebase


0

Google випустив оновлення в програмі для бібліотеки Play Core.

Я запровадив полегшену бібліотеку, щоб легко впроваджувати оновлення в програмі. За наступним посиланням ви знайдете приклад того, як змусити користувача виконати оновлення.

https://github.com/dnKaratzas/android-inapp-update#forced-updates

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.