Programing

새 버전을 사용할 수있는 경우 Android 앱 강제 업데이트

lottogame 2020. 10. 9. 08:42
반응형

새 버전을 사용할 수있는 경우 Android 앱 강제 업데이트


Google Play 스토어에 앱이 있습니다. 업데이트 버전이 있으면 이전 버전을 사용할 수 없게됩니다. 즉, 사용자가 앱을 업데이트하지 않으면 앱에 들어 가지 않습니다. 새 버전을 사용할 수있게되면 사용자가 앱을 강제로 업데이트하도록하려면 어떻게해야합니까?


위의 Scott Helme의 요점에 동의합니다. 그러나 앱을 계속 사용하기 위해 사용자가 반드시 업데이트해야하는 극단적 인 상황 (보안 문제, API 중단 변경 ...)에서는 간단한 버전 관리 API를 제공 할 수 있습니다. API는 다음과 같습니다.

versionCheck API :

요청 매개 변수 :

  • int appVersion

응답

  1. boolean forceUpgrade
  2. boolean 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은 이와 같은 버전 추적에 대한 옵션을 제공하지 않으므로 직접 실행해야합니다. 앱에서 확인할 수있는 현재 라이브 버전을 반환하는 간단한 웹 서비스이면 충분합니다. 그런 다음 버전을 업데이트하면 앱이 오래된 버전임을 알 수 있습니다. Google Play에 의존하는 것보다 더 빨리 업데이트가 있음을 사용자에게 알리기 위해서만이 기능을 사용하는 것이 좋습니다. 앱이 작동하는 것을 막는 데 사용해서는 안되며 사용자에게 업데이트를 요청하는 것뿐입니다.


Scott과 Michael의 대답이 맞습니다. 지원하는 최소 버전 번호를 제공하는 서비스를 호스팅하고 설치된 버전과 비교합니다. 당신은 이것을 사용할 필요가 없길 바라지 만, 만약 어떤 버전이 거기에 있다면 당신은 심각한 결함으로 인해 절대적으로 죽여야 만하는 생명의 은인입니다.

다음에 수행 할 작업에 대한 코드를 추가하고 싶었습니다. 그런 다음 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 팀의 솔루션

새로운 Google Play In App 업데이트 메커니즘을 통해 쉽게 달성 할 수있는 Android 5.0부터 시작합니다. 요구 사항은 버전 1.5.0 이상의 Play Core 라이브러리를 보유하고 apk 대신 App Bundle ID 배포를 사용하는 것입니다.

라이브러리는 업데이트에 대해 사용자에게 알리는 두 가지 방법을 제공합니다.

  1. 사용자가 백그라운드에서 업데이트되는 동안 앱을 계속 사용할 수있는 유연성.

  2. 즉시-사용자가 앱을 업데이트 할 때까지 앱에 들어가는 것을 허용하지 않는 차단 화면입니다.

이를 구현하기위한 다음 단계가 있습니다.

  1. 업데이트 가용성 확인
  2. 업데이트 시작
  3. 업데이트 상태에 대한 콜백 받기
  4. 업데이트 처리

이러한 모든 단계 구현은 공식 사이트 https://developer.android.com/guide/app-bundle/in-app-updates 에 자세히 설명되어 있습니다.


이를 위해 Firebase의 원격 구성 기능을 확인하는 것이 좋습니다 .

다음과 같은 "Disabled Android Versions"조건으로 app_version_enabled 매개 변수를 사용하여 구현했습니다.

applies if App ID == com.example.myapp and App version regular expression ^(5.6.1|5.4.2) 

매개 변수의 기본값은 "true"이지만 비활성화 된 Android 버전의 값은 false입니다. 비활성화 된 Android 버전에 대한 정규식에서 |{version name}해당 괄호 안에 다른 비활성화 된 버전을 추가 할 수 있습니다 .

그런 다음 구성에서 버전이 활성화되었는지 여부를 확인합니다. 사용자가 업그레이드하도록 강제하는 활동이 있습니다. 외부에서 앱을 실행할 수있는 두 곳 (내 기본 런처 활동과 인 텐트 처리 활동) 만 체크인합니다. 원격 구성은 캐시 기반으로 작동하기 때문에 캐시를 무효화하는 데 필요한 시간이 지나지 않은 경우 앱의 '사용 중지 된'버전을 즉시 캡처하지 않지만, 계속 진행하는 경우 최대 12 시간입니다. 권장 캐시 만료 값입니다.


공식적으로 Google은이를 위해 Android API를 제공합니다.

API는 현재 소수의 파트너와 테스트 중이며 곧 모든 개발자가 사용할 수있게 될 것입니다.


업그레이드를 위해 자체 프로세스를 정의하는 것이 좋습니다.

  1. 서버에서 최신 버전의 앱 (ios, android)을 제공하는 웹 서비스를 만듭니다.
  2. 또는 앱에서 사용한 모든 웹 서비스 (예 : 로그인)는 서버에서 최신 앱 버전을 반환합니다.
  3. 앱이 # 1 또는 2에서 버전을 가져 오면 앱이 로컬 / cuurent 앱 버전과 교차 확인합니다. 차이가 있으면 다음과 같이 경고를 표시 할 수 있습니다.

Android 및 iOS : 최신 앱 버전이있는 경우 "더 많은 기능을 사용할 수있는 최신 버전을 사용할 수 있습니다. 업그레이드하려면 업그레이드 버튼을 클릭하십시오."( "Upgarde"및 "아니요. 감사합니다"버튼으로 알림) 경고가 표시됩니다. 그러면 앱이 다음으로 리디렉션됩니다. playstore / Appstore를 선택하면 최신 버전이 열립니다.

 --- we can do upgrade compulsory or optionally.

업그레이드 프로세스 전에 db 스키마가 변경된 경우 적절한 db 마이그레이션 프로세스를 처리했는지 확인하십시오.


로컬 및 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;
}
}

업데이트 용 다이얼 롭 박스

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>


Google은 인앱 업데이트 lib ( https://developer.android.com/guide/app-bundle/in-app-updates )를 도입 했으며 Lollipop +에서 작동하며 사용자에게 멋진 업데이트를 요청할 수있는 기능을 제공합니다. 대화 상자 (FLEXIBLE) 또는 필수 전체 화면 메시지 (IMMEDIATE).

후자를 구현해야합니다. 다음과 같이 표시됩니다.enter image description here

이 답변의 모든 코드를 다루었습니다 : https://stackoverflow.com/a/56808529/5502121


For forcing the app user to update if an update is available in the market, you should first check the app version on the market and compare it with the version of the app on the device. If they are different, it may be an update available. In this post I wrote down the code for getting the current version of market and current version on the device and compare them together. I also showed how to show the update dialog and redirect the user to the update page. Please visit this link: https://stackoverflow.com/a/33925032/5475941 Just make sure that in the dialog you only show the user update button and don't show him the cancel button. In this case he will be forced to update, before he can use the app.


What should definitely be mentioned here is the soon-to-be released In-app Updates API.

You'll have two options with this API; the first is a full-screen experience for critical updates when you expect the user to wait for the update to be applied immediately. The second option is a flexible update, which means the user can keep using the app while the update is downloaded. You can completely customize the update flow so it feels like part of your app.


you can do this by doing a match between a version number that is kept on app in a variable and similarly the current app version is kept on server side and each time user opens the app the first request should be send to check that if it founds matching do nothing simply let the user use your app otherwise fire an intent to the google playstore or open a webview window to your app(window.open("https://play.google.com/store/apps/details?id=package_name", '_system', 'location=yes');) and there they will automatically have the button asking for update that's what google playstore does for you if you dont have automatic updates on.


You can notify your users that there is a new version of the current app available to update. Also, if this condition is true, you can block login in the app.

Please see if this provides you the solution.


Well, there could be many solutions to this problem like scraping the version code from App Page (Google Play App page), etc.

But I am going to show you the ultimate solution that won't cost a penny and will work like magic.

  1. Just save the latest Version code of your app on Firebase Remote
    Config panel
  2. Fetch that version code value whenever the app is opened
  3. Compare it with the current version code of the app, which you can get by the following code

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

    }

If the fetched version code is greater than the current version, show an AlertDialog asking to update the app. Otherwise, the app is already updated.

So, whenever you roll out the new version, you need to put that new version code in Firebase Remote config panel

You can read the whole tutorial on how to force users to update the app using Firebase Remote Config


It is good idea to use remote config for app version and always check in launch activity is current app version is same as remote version or not if not force for update from app store..

Simple logic happy coding..

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


You can use the Play Core Library In-app updates to tackle this. You can check for update availability and install them if available seamlessly.

In-app updates are not compatible with apps that use APK expansion files (.obb files). You can either go for flexible downloads or immediate updates which Google Play takes care of downloading and installing the update for you.

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

Refer this answer https://stackoverflow.com/a/58212818/7579041


Google released In-App Updates for the Play Core library.

I implemented a lightweight library to easily implement in-app updates. You can find to the following link an example about how to force the user to perform the update.

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

참고URL : https://stackoverflow.com/questions/19244305/force-update-of-an-android-app-when-a-new-version-is-available

반응형