Android如何實作強制App版本更新

App上架了一段時間,透過Google Play Console常常會發現有不少的使用者仍然一直停留在舊版本不更新,雖然Android預設會自動更新用戶安裝的App版本,但也是會有使用者把自動更新的功能關閉,如此便會造成App加了新功能用戶無法體驗到或是當初沒考慮到的漏洞沒辦法補起來,基於此,強烈建議App在規劃的初期就要把「強制使用者更新App」的功能實作之後才上架。

實作的方式不難,大致上依照以下幾個流程即可達成:
  1. App開啟時檢查版本與Google Play上的版本是否一致
  2. 如果不一致就彈出對話框讓使用者執行前往該App的Google Play連結
  3. 限制使用者企圖操作不進行版本更新的行為

本例以Volley實作,所以在Callback的部份加上判斷版本是否相符的程式碼:
StringRequest appVersion = BaseApi.appVersion(new ResponseListener() {
    @Override
    public void onError(VolleyError error) {
        super.onError(error);
        intoNextPage(); //有可能網路出錯但仍需讓使用者可以進入下一個頁面
    }

    @Override
    public void onResponse(String str) {
        super.onResponse(str);
        
        Pattern pattern = Pattern.compile("\"softwareVersion\"\\W*([\\d\\.]+)");
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()) {

            if (!ValueUtility.getCurrentVersionName().equals(matcher.group(1))) {
                newVersionDialog.show();
            } else {
                intoNextPage();
            }

        } else { //有可能Google Play的網頁內容變動,但仍需讓使用者可以進到下一頁面
            intoNextPage();
        }

    }
});

幾個實用的function:

/**
 * 產生「新版本更新」對話框
 *
 * @param title
 * @param message
 * @return
 */
private AlertDialog alertDialog(String title, String message) {

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);

    builder.setPositiveButton("更新", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            go2GooglePlay();
            finish();
        }
    });

    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            finish();
        }
    });

    return builder.create();

}

/**
 * 前往Google play
 */
private void go2GooglePlay() {
    final String appPackageName = this.getPackageName(); // getPackageName() from Context or Activity object
        try {
            startActivity(new Intent(Intent.ACTION_VIEW,
                    Uri.parse("market://details?id=" + appPackageName)));
        } catch (android.content.ActivityNotFoundException e) {
            startActivity(new Intent(Intent.ACTION_VIEW,
                    Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
        }
}

產生對話框實體
private AlertDialog newVersionDialog; //新版本對話框

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    newVersionDialog = alertDialog("有新版本", "是否更新");
}

限制使用者企圖繞過版本更新的方法:將對話框限制只能按下「更新」或「取消」,關掉使用者在對話框出現時可以按下Back鍵或觸及對話框之外的地方關掉對話框
@Override
protected void onResume() {
    super.onResume();

    //對話框按下back不能取消的監聽
    newVersionDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {

            if ((keyCode == KeyEvent.KEYCODE_BACK)) {
                return true;
            } else {
                return false;
            }
        }
    });

    //對話框碰到外邊不會被取消
    newVersionDialog.setCanceledOnTouchOutside(false);

}

可以達成的效果:
  • 當使用者一打開App的時候如果有彈出版本更新的對話框時,Back鍵失效、碰觸對話框外面區域對話框也不會關閉。
  • 當使用者按下對話框的「取消」時,整個App會關閉。
  • 當使用者按下對話框的「更新」時,進入Google Play的連結但沒有執行更新時,下次再進入App一樣會再出現該對話框。
  • 直到使用者已更新版本與Google Play上的版本一致才不會出現對話框。

留言

張貼留言

這個網誌中的熱門文章

Mac安裝JDK後仍出現沒有runtime的錯誤 No Java runtime present, requesting install

Android使用Callback做為傳遞資料/通知的方法

如何實作從API抓取資料顯示在列表頁(ListView)上