web-dev-qa-db-ja.com

検出AndroidアプリのアップグレードとEULAの表示/非表示のアプリケーションクラスブール値の設定

BroadcastReceiverを使用してアプリケーションがアップグレードされたことを検出し、アプリケーションクラスにブール値を設定しようとしています。このブール値を他のいくつかのブール値と組み合わせて使用​​して、EULAダイアログボックスをユーザーに表示するかどうかを決定します。

正しくセットアップされていると思いますが、EULAはまだ表示されないはずのときに表示されます。具体的には、ユーザーが以前のバージョンでEULAに既に同意している場合、アップグレード後のバージョン(私が手動で設定)でEULAは変更されておらず、アプリはアップグレードされています。

これが機能しない理由は、アプリケーションが実行されていないため、isAppUpgrade()メソッドが呼び出されておらず、正しいブールフラグが設定されているためです。誰かがこれが事実であることを確認できますか、または私のコードに何か問題がありますか?

FYI-EULA.show(Activity、boolean、boolean)静的メソッドがメインアクティビティで最初に呼び出されています。

ここにいくつかのコードがあります

アプリケーションクラス

public class MFCApplication extends Application {

    private boolean isUpgrade = false;

    /**
     * Returns a manually set value of whether the EULA has changed in this version of the App
     * @return true/false
     */
    public boolean hasEULAChanged() {
        return false;
    }

    /**
     * Returns whether or not the application has been upgraded.  Set by the UpgradeBroadcastReceiver
     * @return true/false
     */
    public boolean isAppUpgrade() {
        return isUpgrade;
    }

    /**
     * Method called by UpgradeBroadcastReceiver if the App has been upgraded
     */
    public void setAppIsUpgrade() {
        this.isUpgrade = true;
    }
}

BroadcastReceiver

public class UpgradeBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null)
            return;
        if (context == null)
            return;

        String action = intent.getAction();
        if (action == null)
            return;

        if (action.equals(Intent.ACTION_PACKAGE_REPLACED)) {
            MFCApplication myApp = ((MFCApplication)((Activity)context).getApplication());

            myApp.setAppIsUpgrade();
        }
    }
}

EULAクラス

public class EULA {

    private static final String EULA_ASSET = "EULA";
    private static final String EULA_PREFERENCES = "eula";
    private static Activity mActivity;

    private static PackageInfo getPackageInfo() {
        PackageInfo pi = null;
        try {
            pi = mActivity.getPackageManager().getPackageInfo(mActivity.getPackageName(), PackageManager.GET_ACTIVITIES);
        } catch (PackageManager.NameNotFoundException ex) {
            ex.printStackTrace();
        }
        return pi;
    }

    public static boolean show(Activity activity, boolean hasEULAChanged, boolean isAppUpgrade) {
        mActivity = activity;
        final SharedPreferences preferences = activity.getSharedPreferences(EULA_PREFERENCES, Activity.MODE_PRIVATE);
        final PackageInfo packageInfo = getPackageInfo();
        String eulaPref = preferences.getString(EULA_PREFERENCES, "0");
        boolean eulaVersionAccepted = packageInfo.versionName.equals(eulaPref);
        if (!eulaVersionAccepted && (hasEULAChanged || !isAppUpgrade)) {
            //The EULA should be shown here, but it isn't
            return false;
        }
        return true;
    }
}

アプリケーションマニフェスト

<receiver Android:name=".helpers.UpgradeBroadcastReceiver">
    <intent-filter>
        <action Android:name="Android.intent.action.PACKAGE_REPLACED" />
        <data Android:scheme="package" Android:path="com.hookedroid.fishingcompanion" />
    </intent-filter>
</receiver>
35
hooked82

現在のアプリのバージョンを確認するだけの方がはるかに簡単です。

PackageInfo packageInfo = activity.getPackageManager()
    .getPackageInfo(activity.getPackageName(), 0);
int versionCode = packageInfo.versionCode;

アプリが起動したら、SharedPreferencesのバージョンコードで整数値を確認します。ない場合、または一致しない場合は、EULAを表示します。ユーザーがEULAに同意したら、versionCode値をSharedPreferencesに書き込みます。

versionCodeは、マニフェストに保存したバージョン番号と一致します。

63
EboMike

元のアプローチによると、BroadcastReceiverを使用してアプリがアップグレードされているかどうかを検出するために管理しました

public class YourUpgradeReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Uri packageName = intent.getData();
        if(packageName.toString().equals("package:" + context.getPackageName())){
            //Application was upgraded
        }
    } 
}

そしてあなたのマニフェストで

 <receiver Android:name=".YourUpgradeReceiver">
            <intent-filter>
                <action Android:name="Android.intent.action.PACKAGE_REPLACED"/>
                <data Android:scheme="package"/>
            </intent-filter>
 </receiver>
25

アプリが更新されたかどうかを検出

SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
int versionCode = sharedPreferences.getInt("VERSION_CODE", BuildConfig.VERSION_CODE);

if(versionCode != BuildConfig.VERSION_CODE) {
    onAppUpdated();
}

sharedPreferences.edit().putInt("VERSION_CODE", BuildConfig.VERSION_CODE).apply();
9
shahrukhamd

EULAを変更せずにアプリを更新できるため、アプリのバージョン自体は使用しないでください。 EULA自体に特定のバージョンを持つリソースを提供します。文字列リソース「eula_version」の可能性があります。 EULAが変更されるたびに、アプリの更新のためにその文字列を更新します。アクティビティのonCreateでは、リソースの文字列をSharedPreferencesの文字列と照合します。単純なアプローチは、nullまたは等しくないことをチェックすることだけです。 (アプリのダウングレードまたはアンインストール/再インストール後にEULAが再び表示される唯一の欠点)。

public static boolean show(Activity activity, boolean hasEULAChanged, boolean isAppUpgrade) {
    mActivity = activity;
    final SharedPreferences preferences = activity.getSharedPreferences(EULA_PREFERENCES, Activity.MODE_PRIVATE);
    final PackageInfo packageInfo = getPackageInfo();
    String eulaPref = preferences.getString(EULA_PREFERENCES, "0"); //save on accept EULA Dialog click
    String eulaActive = getString(R.string.eula_version)
    return eulaPref==null || !eulaPref.equals(eulaActive);
}
0
FrankKrumnow

ここにあなたの問題を解決できる簡単な方法があります。コードでは、アプリのversionCodeとversionNameを簡単に取得できます。 GCMの登録後の最初のインストールで、versionNameをsharedPreferencesに保存します。ホームアクティビティでisAppUpdated()を確認します。現在のAPP VERSION_NAMEが保存されているVERSION_NAMEと一致しない場合は、GCM IDを再登録します。

これがサンプルコードです:

設定にVersionNameを保存:

public static void saveVersionNameAndCode(Context context){
        try{
            PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            int versionCode = packageInfo.versionCode;
            String versionName=packageInfo.versionName;

            CommonTasks.showLog("Saving APP VersionCode and Version Name");

            // SAVE YOUR DATA

        }catch(Exception e){
        }
    }

アプリがアップグレードされていることを確認:

public static boolean isAppUpdated(Context context){
        boolean result=false;
        try{
            PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            int versionCode = packageInfo.versionCode;
            String versionName=packageInfo.versionName;

            String prevVersionName= GET STORED VERSION_NAME;
            if(prevVersionName!=null && !prevVersionName.equals("") &&
                    !prevVersionName.equals(versionName)){
                showLog("App Updated");
                result=true;
            }else{
                showLog("App Not updated");
            }

        }catch(Exception e){
        }
        return result;
    }

ここで、isAppUpdated()がtrueを返す場合、GCM IDを再登録する必要があることを意味します。

0

11を超えるAPIをターゲットにしている場合、@ MarianKlühspiesの回答からのソリューションは簡略化される可能性があります。レシーバーの登録:

<receiver
    Android:name=".your.receivers.package.AppUpdateReceiver">
    <intent-filter>
        <action Android:name="Android.intent.action.MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>

そして受信機自体:

class AppUpdateReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_MY_PACKAGE_REPLACED) {
            onAppUpdated()
        }
    }
}
0
a.ch.