diff --git a/library/wversionmanager/build.gradle b/library/wversionmanager/build.gradle index f142a7b..1b682ef 100644 --- a/library/wversionmanager/build.gradle +++ b/library/wversionmanager/build.gradle @@ -3,7 +3,6 @@ apply plugin: 'com.jfrog.bintray' apply plugin: 'com.github.dcendents.android-maven' ext { - bintrayRepo = "Android-WVersionManager" bintrayName = "com.winsontan520.wversionmanager" libraryDescription = '' @@ -15,7 +14,7 @@ ext { siteUrl = 'https://github.com/revanmj/Android-WVersionManager' gitUrl = 'https://github.com/revanmj/Android-WVersionManager.git' - libraryVersion = '1.5' + libraryVersion = "1.6" developerId = 'revanmj' developerName = 'Michal Jakubowski' @@ -33,8 +32,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 27 - versionCode 5 - versionName "1.5" + versionCode 6 + versionName "$libraryVersion" } buildTypes { @@ -43,10 +42,15 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { - implementation 'com.android.support:support-v4:27.1.0' + implementation 'com.android.support:support-v4:27.1.1' } task deleteJar(type: Delete) { diff --git a/library/wversionmanager/src/main/AndroidManifest.xml b/library/wversionmanager/src/main/AndroidManifest.xml index 1c74ccd..ad21c7d 100644 --- a/library/wversionmanager/src/main/AndroidManifest.xml +++ b/library/wversionmanager/src/main/AndroidManifest.xml @@ -5,6 +5,14 @@ android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > + + + - \ No newline at end of file diff --git a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/CustomTagHandler.java b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/CustomTagHandler.java similarity index 91% rename from library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/CustomTagHandler.java rename to library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/CustomTagHandler.java index 3d42d04..f948079 100644 --- a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/CustomTagHandler.java +++ b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/CustomTagHandler.java @@ -1,4 +1,4 @@ -package com.winsontan520.wversionmanager.library; +package com.winsontan520.wversionmanager; import org.xml.sax.XMLReader; diff --git a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/IWVersionManager.java b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/IWVersionManager.java similarity index 57% rename from library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/IWVersionManager.java rename to library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/IWVersionManager.java index 98f9232..09018b1 100644 --- a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/IWVersionManager.java +++ b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/IWVersionManager.java @@ -1,60 +1,53 @@ -package com.winsontan520.wversionmanager.library; +package com.winsontan520.wversionmanager; +import android.Manifest; import android.graphics.drawable.Drawable; +import android.support.annotation.RequiresPermission; public interface IWVersionManager { - - /** - * @return Label of update now button - */ - public String getUpdateNowLabel(); - - - /** - * @param updateNowLabel Set the label for update now button - */ - public void setUpdateNowLabel(String updateNowLabel); - - /** - * @return label of remind me later button - */ - public String getRemindMeLaterLabel(); - /** - * @param remindMeLaterLabel Set label of remind me later button + * Displays a dialog asking user to rate your app */ - public void setRemindMeLaterLabel(String remindMeLaterLabel); - - /** - * @return label of ignore this version button - */ - public String getIgnoreThisVersionLabel(); - + public void askForRate(); /** - * @param ignoreThisVersionLabel Set label of ignore this version button + * Initiates check for updates that may result in displaying a dialog with release notes + * and options to update now, remind user about it later or ignore that version */ - public void setIgnoreThisVersionLabel(String ignoreThisVersionLabel); - + public void checkVersion(); /** - * @param icon Set drawable of icon in dialog + * @param icon Drawable of icon in dialog */ public void setIcon(Drawable icon); /** - * @param title Set title of dialog + * @param title Title of dialog */ public void setTitle(String title); /** - * @param message Set message of dialog + * @param message Message of dialog */ public void setMessage(String message); /** - * @param value Set if Android's Download Manager should be used (off by default) instead of opening a link in a browser + * Used to choose if Android's Download Manager should be used to download file at URL + * from JSON file to Downloads folder (off by default) instead of opening a link in a browser + * @param value true to use Download Manager, false otherwise */ + @RequiresPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) public void useDownloadManager(boolean value); + /** + * Setting this to true when {@link #useDownloadManager(boolean)} + * is also true will automatically fire APK installation dialog after download completes. + * This requires Unknown Sources to be enabled (globally on Nougat and lower, + * for your app specifically in Oreo or higher). If permission is not granted, + * system's Download app will be launched. + * @param value true to enable auto install, false otherwise + */ + @RequiresPermission(anyOf = {Manifest.permission.REQUEST_INSTALL_PACKAGES, Manifest.permission.INSTALL_PACKAGES}) + public void installAfterDownload(boolean value); + /** * @return message of dialog */ @@ -124,5 +117,4 @@ public interface IWVersionManager { * @param listener Set your own callback listener when receiving response from server */ public void setOnReceiveListener(OnReceiveListener listener); - } \ No newline at end of file diff --git a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/OnReceiveListener.java b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/OnReceiveListener.java similarity index 84% rename from library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/OnReceiveListener.java rename to library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/OnReceiveListener.java index b26be56..d1935c8 100644 --- a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/OnReceiveListener.java +++ b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/OnReceiveListener.java @@ -1,4 +1,4 @@ -package com.winsontan520.wversionmanager.library; +package com.winsontan520.wversionmanager; public interface OnReceiveListener { diff --git a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/UpdateFileProvider.java b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/UpdateFileProvider.java new file mode 100644 index 0000000..a1e2e5e --- /dev/null +++ b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/UpdateFileProvider.java @@ -0,0 +1,5 @@ +package com.winsontan520.wversionmanager; + +import android.support.v4.content.FileProvider; + +public class UpdateFileProvider extends FileProvider { } diff --git a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/WVersionManager.java b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/WVersionManager.java similarity index 52% rename from library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/WVersionManager.java rename to library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/WVersionManager.java index 9f73fd1..7cb4801 100644 --- a/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/library/WVersionManager.java +++ b/library/wversionmanager/src/main/java/com/winsontan520/wversionmanager/WVersionManager.java @@ -1,7 +1,8 @@ -package com.winsontan520.wversionmanager.library; +package com.winsontan520.wversionmanager; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; @@ -15,63 +16,67 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.DownloadManager; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.pm.ApplicationInfo; +import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Environment; import android.preference.PreferenceManager; +import android.provider.Settings; +import android.support.v4.content.FileProvider; import android.text.Html; import android.util.Log; +import android.widget.Toast; + +import com.winsontan520.wversionmanager.library.BuildConfig; +import com.winsontan520.wversionmanager.library.R; public class WVersionManager implements IWVersionManager { - private static final String TAG = "WVersionManager"; + private static final String TAG = WVersionManager.class.getSimpleName(); private static final int MODE_CHECK_VERSION = 100; private static final int MODE_ASK_FOR_RATE = 200; - private CustomTagHandler customTagHandler; - - private String PREF_IGNORE_VERSION_CODE = "w.ignore.version.code"; - private String PREF_REMINDER_TIME = "w.reminder.time"; - - private Activity activity; - private Drawable icon; - private String title; - private String message; - private String updateNowLabel; - private String remindMeLaterLabel; - private String ignoreThisVersionLabel; - private String updateUrl; - private String versionContentUrl; - private int reminderTimer; - private int mVersionCode; - private AlertDialogButtonListener listener; + private static final String PREF_IGNORE_VERSION_CODE = "w.ignore.version.code"; + private static final String PREF_REMINDER_TIME = "w.reminder.time"; + private static final String APK_MIME_TYPE = "application/vnd.android.package-archive"; + + private Activity mActivity; + private Drawable mIcon; + private String mTitle; + private String mMessage; + private String mUpdateUrl; + private String mVersionContentUrl; private boolean mDialogCancelable = true; - private boolean mIsAskForRate = false; private boolean mUseDownloadManager = false; - private String mAskForRatePositiveLabel; - private String mAskForRateNegativeLabel; - private int mMode = 100; // default mode + private boolean mAutoInstall = false; + private int mReminderTimer; + private int mVersionCode; + private int mMode = MODE_CHECK_VERSION; // Default mode + private AlertDialogButtonListener mDialogListener; private OnReceiveListener mOnReceiveListener; - private String mResult; + private CustomTagHandler mCustomTagHandler; public WVersionManager(Activity act) { - this.activity = act; - this.listener = new AlertDialogButtonListener(); - this.customTagHandler = new CustomTagHandler(); - } - - private Drawable getDefaultAppIcon() { - Drawable d = activity.getApplicationInfo().loadIcon(activity.getPackageManager()); - return d; + this.mActivity = act; + this.mDialogListener = new AlertDialogButtonListener(); + this.mCustomTagHandler = new CustomTagHandler(); } + /* + * (non-Javadoc) + * + * @see + * com.winsontan520.wversionmanager.IWVersionManager#checkVersion() + */ + @Override public void checkVersion() { mMode = MODE_CHECK_VERSION; String versionContentUrl = getVersionContentUrl(); @@ -93,275 +98,322 @@ public void checkVersion() { if (BuildConfig.DEBUG) { Log.v(TAG, "getting update content..."); } - VersionContentRequest request = new VersionContentRequest(activity); + VersionContentRequest request = new VersionContentRequest(mActivity); request.execute(getVersionContentUrl()); } } - private void showDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - - builder.setIcon(getIcon()); - builder.setTitle(getTitle()); - builder.setMessage(Html.fromHtml(getMessage(), null, getCustomTagHandler())); - - switch (mMode) { - case MODE_CHECK_VERSION: - builder.setPositiveButton(getUpdateNowLabel(), listener); - builder.setNeutralButton(getRemindMeLaterLabel(), listener); - builder.setNegativeButton(getIgnoreThisVersionLabel(), listener); - break; - case MODE_ASK_FOR_RATE: - builder.setPositiveButton(getAskForRatePositiveLabel(), listener); - builder.setNegativeButton(getAskForRateNegativeLabel(), listener); - break; - default: - return; - } - - builder.setCancelable(isDialogCancelable()); - - AlertDialog dialog = builder.create(); - if (activity != null && !activity.isFinishing()) { - dialog.show(); - } + /* + * (non-Javadoc) + * + * @see + * com.winsontan520.wversionmanager.IWVersionManager#askForRate() + */ + @Override + public void askForRate() { + mMode = MODE_ASK_FOR_RATE; + showDialog(); } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#getUpdateNowLabel() + * com.winsontan520.wversionmanager.IWVersionManager#setIcon(android.graphics.drawable.Drawable) */ @Override - public String getUpdateNowLabel() { - return updateNowLabel != null ? updateNowLabel : "Update now"; + public void setIcon(Drawable icon) { + this.mIcon = icon; } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setUpdateNowLabel - * (java.lang.String) + * com.winsontan520.wversionmanager.IWVersionManager#setMessage(java.lang.String) */ @Override - public void setUpdateNowLabel(String updateNowLabel) { - this.updateNowLabel = updateNowLabel; + public void setMessage(String message) { + this.mMessage = message; } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#getRemindMeLaterLabel - * () + * com.winsontan520.wversionmanager.IWVersionManager#setTitle(java.lang.String) */ @Override - public String getRemindMeLaterLabel() { - return remindMeLaterLabel != null ? remindMeLaterLabel : "Remind me later"; + public void setTitle(String mTitle) { + this.mTitle = mTitle; } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setRemindMeLaterLabel - * (java.lang.String) + * com.winsontan520.wversionmanager.IWVersionManager#useDownloadManager(boolean) */ @Override - public void setRemindMeLaterLabel(String remindMeLaterLabel) { - this.remindMeLaterLabel = remindMeLaterLabel; + public void useDownloadManager(boolean value) { + mUseDownloadManager = value; } /* * (non-Javadoc) * - * @see com.winsontan520.wversionmanagertest.IWVersionManager# - * getIgnoreThisVersionLabel() + * @see + * com.winsontan520.wversionmanager.IWVersionManager#installAfterDownload(boolean) */ @Override - public String getIgnoreThisVersionLabel() { - return ignoreThisVersionLabel != null ? ignoreThisVersionLabel : "Ignore this version"; + public void installAfterDownload(boolean value) { + mAutoInstall = value; } /* * (non-Javadoc) * - * @see com.winsontan520.wversionmanagertest.IWVersionManager# - * setIgnoreThisVersionLabel(java.lang.String) + * @see com.winsontan520.wversionmanager.IWVersionManager#getMessage() */ @Override - public void setIgnoreThisVersionLabel(String ignoreThisVersionLabel) { - this.ignoreThisVersionLabel = ignoreThisVersionLabel; + public String getMessage() { + String defaultMessage = null; + switch (mMode) { + case MODE_CHECK_VERSION: + defaultMessage = mActivity.getString(R.string.wvm_dialog_message_update); + break; + case MODE_ASK_FOR_RATE: + defaultMessage = mActivity.getString(R.string.wvm_dialog_message_rate_us); + break; + } + + return mMessage != null ? mMessage : defaultMessage; } /* * (non-Javadoc) * - * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setIcon(android - * .graphics.drawable.Drawable) + * @see com.winsontan520.wversionmanager.IWVersionManager#getTitle() */ @Override - public void setIcon(Drawable icon) { - this.icon = icon; + public String getTitle() { + String defaultTitle = null; + switch (mMode) { + case MODE_CHECK_VERSION: + defaultTitle = mActivity.getString(R.string.wvm_dialog_title_update); + break; + case MODE_ASK_FOR_RATE: + defaultTitle = mActivity.getString(R.string.wvm_dialog_title_rate_us); + break; + } + return mTitle != null ? mTitle : defaultTitle; } /* * (non-Javadoc) * - * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setTitle(java.lang - * .String) + * @see com.winsontan520.wversionmanager.IWVersionManager#getIcon() */ @Override - public void setTitle(String title) { - this.title = title; + public Drawable getIcon() { + return mIcon != null ? mIcon : getDefaultAppIcon(); } /* * (non-Javadoc) * - * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setMessage(java - * .lang.String) + * @see com.winsontan520.wversionmanager.IWVersionManager#getUpdateUrl() */ @Override - public void setMessage(String message) { - this.message = message; + public String getUpdateUrl() { + return mUpdateUrl != null ? mUpdateUrl : getGooglePlayStoreUrl(); } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#useDownloadManager(boolean) + * com.winsontan520.wversionmanager.IWVersionManager#setUpdateUrl(java.lang.String) */ @Override - public void useDownloadManager(boolean value) { - mUseDownloadManager = value; + public void setUpdateUrl(String updateUrl) { + this.mUpdateUrl = updateUrl; } /* * (non-Javadoc) * - * @see com.winsontan520.wversionmanagertest.IWVersionManager#getMessage() + * @see + * com.winsontan520.wversionmanager.IWVersionManager#getVersionContentUrl() */ @Override - public String getMessage() { - String defaultMessage = null; - switch (mMode) { - case MODE_CHECK_VERSION: - defaultMessage = "What's new in this version"; - break; - case MODE_ASK_FOR_RATE: - defaultMessage = "Please rate us!"; - break; - } - - return message != null ? message : defaultMessage; + public String getVersionContentUrl() { + return mVersionContentUrl; } /* * (non-Javadoc) * - * @see com.winsontan520.wversionmanagertest.IWVersionManager#getTitle() + * @see + * com.winsontan520.wversionmanager.IWVersionManager#setVersionContentUrl(java.lang.String) */ @Override - public String getTitle() { - String defaultTitle = null; - switch (mMode) { - case MODE_CHECK_VERSION: - defaultTitle = "New Update Available"; - break; - case MODE_ASK_FOR_RATE: - defaultTitle = "Rate this app"; - break; - } - return title != null ? title : defaultTitle; + public void setVersionContentUrl(String versionContentUrl) { + this.mVersionContentUrl = versionContentUrl; } /* * (non-Javadoc) * - * @see com.winsontan520.wversionmanagertest.IWVersionManager#getIcon() + * @see + * com.winsontan520.wversionmanager.IWVersionManager#setVersionContentUrl(java.lang.String) */ @Override - public Drawable getIcon() { - return icon != null ? icon : getDefaultAppIcon(); + public int getReminderTimer() { + return mReminderTimer > 0 ? mReminderTimer : 60; // default value: 60 minutes } /* * (non-Javadoc) * - * @see com.winsontan520.wversionmanagertest.IWVersionManager#getUpdateUrl() + * @see + * com.winsontan520.wversionmanager.IWVersionManager#setReminderTimer(int) */ @Override - public String getUpdateUrl() { - return updateUrl != null ? updateUrl : getGooglePlayStoreUrl(); + public void setReminderTimer(int minutes) { + if (minutes > 0) { + mReminderTimer = minutes; + } } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setUpdateUrl(java - * .lang.String) + * com.winsontan520.wversionmanager.IWVersionManager#getCurrentVersionCode() */ @Override - public void setUpdateUrl(String updateUrl) { - this.updateUrl = updateUrl; + public int getCurrentVersionCode() { + int currentVersionCode = 0; + PackageInfo pInfo; + try { + pInfo = mActivity.getPackageManager().getPackageInfo(mActivity.getPackageName(), 0); + currentVersionCode = pInfo.versionCode; + } catch (NameNotFoundException e) { + // return 0 + } + return currentVersionCode; } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#getVersionContentUrl - * () + * com.winsontan520.wversionmanager.IWVersionManager#getIgnoreVersionCode() */ @Override - public String getVersionContentUrl() { - return versionContentUrl; + public int getIgnoreVersionCode() { + return PreferenceManager.getDefaultSharedPreferences(mActivity).getInt(PREF_IGNORE_VERSION_CODE, 1); } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setVersionContentUrl - * (java.lang.String) + * com.winsontan520.wversionmanager.IWVersionManager#getCustomTagHandler() */ @Override - public void setVersionContentUrl(String versionContentUrl) { - this.versionContentUrl = versionContentUrl; + public CustomTagHandler getCustomTagHandler() { + return mCustomTagHandler; } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setVersionContentUrl - * (java.lang.String) + * com.winsontan520.wversionmanager.IWVersionManager#setCustomTagHandler + * (com.winsontan520.wversionmanager.WVersionManager.CustomTagHandler) */ @Override - public int getReminderTimer() { - return reminderTimer > 0 ? reminderTimer : (1 * 60); // default value 60 - // minutes + public void setCustomTagHandler(CustomTagHandler customTagHandler) { + this.mCustomTagHandler = customTagHandler; + } + + public boolean isDialogCancelable() { + return mDialogCancelable; + } + + public void setDialogCancelable(boolean dialogCancelable) { + mDialogCancelable = dialogCancelable; } /* * (non-Javadoc) * * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setReminderTimer - * (int) + * com.winsontan520.wversionmanager.IWVersionManager#setOnReceiveListener + * (com.winsontan520.wversionmanager.OnReceiveListener) */ @Override - public void setReminderTimer(int minutes) { - if (minutes > 0) { - reminderTimer = minutes; + public void setOnReceiveListener(OnReceiveListener listener) { + this.mOnReceiveListener = listener; + } + + private void showDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); + + builder.setIcon(getIcon()); + builder.setTitle(getTitle()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + builder.setMessage(Html.fromHtml(getMessage(), Html.FROM_HTML_MODE_LEGACY, null, getCustomTagHandler())); + } else { + builder.setMessage(Html.fromHtml(getMessage(),null, getCustomTagHandler())); + } + + switch (mMode) { + case MODE_CHECK_VERSION: + builder.setPositiveButton(R.string.wvm_button_update, mDialogListener); + builder.setNeutralButton(R.string.wvm_button_remind_later, mDialogListener); + builder.setNegativeButton(R.string.wvm_button_ignore, mDialogListener); + break; + case MODE_ASK_FOR_RATE: + builder.setPositiveButton(R.string.wvm_button_ok, mDialogListener); + builder.setNegativeButton(R.string.wvm_button_not_now, mDialogListener); + break; + default: + return; + } + + builder.setCancelable(isDialogCancelable()); + + AlertDialog dialog = builder.create(); + if (mActivity != null && !mActivity.isFinishing()) { + dialog.show(); + } + } + + private class AlertDialogButtonListener implements DialogInterface.OnClickListener { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case AlertDialog.BUTTON_POSITIVE: + switch (mMode) { + case MODE_CHECK_VERSION: + updateNow(getUpdateUrl()); + break; + case MODE_ASK_FOR_RATE: + mActivity.startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse(getGooglePlayStoreUrl()))); + break; + } + break; + case AlertDialog.BUTTON_NEUTRAL: + remindMeLater(getReminderTimer()); + break; + case AlertDialog.BUTTON_NEGATIVE: + ignoreThisVersion(); + break; + } } } @@ -370,31 +422,73 @@ private void updateNow(String url) { try { Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); - activity.startActivity(intent); + mActivity.startActivity(intent); } catch (Exception e) { Log.e(TAG, "is update url correct?" + e); } } else if (url != null) { Uri downloadUri = Uri.parse(url); - // Use app's name as Download Manager's notification title - ApplicationInfo appInfo = activity.getApplicationInfo(); - int stringId = appInfo.labelRes; - String title = stringId == 0 ? - appInfo.nonLocalizedLabel.toString() : activity.getString(appInfo.labelRes); + String title = downloadUri.getLastPathSegment(); + final String filePath = Environment.getExternalStorageDirectory() + "/" + + Environment.DIRECTORY_DOWNLOADS + "/" + downloadUri.getLastPathSegment(); + final Uri fileUri = Uri.parse("file://" + filePath); // Build Download Manager's request DownloadManager.Request request = new DownloadManager.Request(downloadUri); request.setTitle(title); + request.setMimeType(APK_MIME_TYPE); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, downloadUri.getLastPathSegment()); + request.setDestinationUri(fileUri); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); // Start downloading - DownloadManager manager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE); + final DownloadManager manager = (DownloadManager) mActivity.getSystemService(Context.DOWNLOAD_SERVICE); manager.enqueue(request); + + // Handle initiating downloaded APK install + Toast.makeText(mActivity, R.string.wvm_toast_download_started, Toast.LENGTH_SHORT).show(); + boolean apkPermission = false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + apkPermission = mActivity.getPackageManager().canRequestPackageInstalls(); + } else { + try { + apkPermission = Settings.Secure.getInt( + mActivity.getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS) == 1; + } catch (Settings.SettingNotFoundException e) { + Log.e(TAG, e.getMessage()); + } + } + if (mAutoInstall && apkPermission) { + BroadcastReceiver onComplete = new BroadcastReceiver() { + public void onReceive(Context ctx, Intent intent) { + Intent install = new Intent(Intent.ACTION_VIEW); + install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + install.setDataAndType(FileProvider.getUriForFile(mActivity, + mActivity.getApplicationContext().getPackageName() + ".UpdateFileProvider", + new File(filePath)), APK_MIME_TYPE); + install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + install.setDataAndType(fileUri,APK_MIME_TYPE); + } + Toast.makeText(mActivity, R.string.wvm_toast_download_complete, Toast.LENGTH_SHORT).show(); + mActivity.startActivity(install); + mActivity.unregisterReceiver(this); + mActivity.finish(); + } + }; + mActivity.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); + } else if (mAutoInstall && !apkPermission) { + mActivity.startActivity(new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS)); + } } + } + private void ignoreThisVersion() { + PreferenceManager.getDefaultSharedPreferences(mActivity).edit() + .putInt(PREF_IGNORE_VERSION_CODE, mVersionCode).commit(); } private void remindMeLater(int reminderTimer) { @@ -408,55 +502,33 @@ private void remindMeLater(int reminderTimer) { Log.v(TAG, "currentTimeStamp=" + currentTimeStamp); Log.v(TAG, "reminderTimeStamp=" + reminderTimeStamp); } - setReminderTime(reminderTimeStamp); } private void setReminderTime(long reminderTimeStamp) { - PreferenceManager.getDefaultSharedPreferences(activity).edit().putLong(PREF_REMINDER_TIME, reminderTimeStamp) - .commit(); + PreferenceManager.getDefaultSharedPreferences(mActivity).edit() + .putLong(PREF_REMINDER_TIME + mMode, reminderTimeStamp).commit(); } private long getReminderTime() { - return PreferenceManager.getDefaultSharedPreferences(activity).getLong(PREF_REMINDER_TIME, 0); - } - - private void ignoreThisVersion() { - PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(PREF_IGNORE_VERSION_CODE, mVersionCode) - .commit(); + return PreferenceManager.getDefaultSharedPreferences(mActivity).getLong( + PREF_REMINDER_TIME + mMode, 0); } private String getGooglePlayStoreUrl() { - String id = activity.getApplicationInfo().packageName; // current google - // play is using - // package name - // as id - return "market://details?id=" + id; + // currently google play is using package name as id + return "market://details?id=" + mActivity.getApplicationInfo().packageName; } - private class AlertDialogButtonListener implements DialogInterface.OnClickListener { - - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case AlertDialog.BUTTON_POSITIVE: - updateNow(getUpdateUrl()); - break; - case AlertDialog.BUTTON_NEUTRAL: - remindMeLater(getReminderTimer()); - break; - case AlertDialog.BUTTON_NEGATIVE: - ignoreThisVersion(); - break; - } - } + private Drawable getDefaultAppIcon() { + return mActivity.getApplicationInfo().loadIcon(mActivity.getPackageManager()); } class VersionContentRequest extends AsyncTask { Context context; int statusCode; - public VersionContentRequest(Context context) { + VersionContentRequest(Context context) { this.context = context; } @@ -486,7 +558,6 @@ protected String doInBackground(String... uri) { connection.disconnect(); responseBody = result.toString(); } - } catch (Exception e) { Log.e(TAG, e.toString()); } finally { @@ -512,20 +583,18 @@ protected void onPostExecute(String result) { } } else { try { - if (!result.startsWith("{")) { // for response who append - // with unknown char + if (!result.startsWith("{")) { // for response who append with unknown char result = result.substring(1); } - mResult = result; if (BuildConfig.DEBUG) { Log.d(TAG, "status = " + statusCode); - Log.d(TAG, "result = " + mResult); + Log.d(TAG, "result = " + result); } // show default dialog if no listener is set OR return true if (mOnReceiveListener == null || mOnReceiveListener.onReceive(statusCode, result)) { // json format from server: - JSONObject json = (JSONObject) new JSONTokener(mResult).nextValue(); + JSONObject json = (JSONObject) new JSONTokener(result).nextValue(); mVersionCode = json.optInt("version_code"); content = json.optString("content"); @@ -536,13 +605,11 @@ protected void onPostExecute(String result) { if (mVersionCode != getIgnoreVersionCode()) { // set dialog message setMessage(content); - // show update dialog showDialog(); } } } - } catch (JSONException e) { Log.e(TAG, "is your server response have valid json format?"); } catch (Exception e) { @@ -551,81 +618,4 @@ protected void onPostExecute(String result) { } } } - - /* - * (non-Javadoc) - * - * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#getCurrentVersionCode - * () - */ - @Override - public int getCurrentVersionCode() { - int currentVersionCode = 0; - PackageInfo pInfo; - try { - pInfo = activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0); - currentVersionCode = pInfo.versionCode; - } catch (NameNotFoundException e) { - // return 0 - } - return currentVersionCode; - } - - @Override - public int getIgnoreVersionCode() { - return PreferenceManager.getDefaultSharedPreferences(activity).getInt(PREF_IGNORE_VERSION_CODE, 1); - } - - @Override - public CustomTagHandler getCustomTagHandler() { - return customTagHandler; - } - - /* - * (non-Javadoc) - * - * @see - * com.winsontan520.wversionmanagertest.IWVersionManager#setCustomTagHandler - * (com.winsontan520.wversionmanagertest.WVersionManager.CustomTagHandler) - */ - @Override - public void setCustomTagHandler(CustomTagHandler customTagHandler) { - this.customTagHandler = customTagHandler; - } - - public boolean isDialogCancelable() { - return mDialogCancelable; - } - - public void setDialogCancelable(boolean dialogCancelable) { - mDialogCancelable = dialogCancelable; - } - - public void askForRate() { - mMode = MODE_ASK_FOR_RATE; - showDialog(); - } - - public String getAskForRatePositiveLabel() { - return mAskForRatePositiveLabel == null ? "OK" : mAskForRatePositiveLabel; - } - - public void setAskForRatePositiveLabel(String askForRatePositiveLabel) { - mAskForRatePositiveLabel = askForRatePositiveLabel; - } - - public String getAskForRateNegativeLabel() { - return mAskForRateNegativeLabel == null ? "Not now" : mAskForRateNegativeLabel; - } - - public void setAskForRateNegativeLabel(String askForRateNegativeLabel) { - mAskForRateNegativeLabel = askForRateNegativeLabel; - } - - @Override - public void setOnReceiveListener(OnReceiveListener listener) { - this.mOnReceiveListener = listener; - } - } diff --git a/library/wversionmanager/src/main/res/values/strings.xml b/library/wversionmanager/src/main/res/values/strings.xml index 8bdf0f7..14db516 100644 --- a/library/wversionmanager/src/main/res/values/strings.xml +++ b/library/wversionmanager/src/main/res/values/strings.xml @@ -1,5 +1,14 @@ - WVersionManager - + Download started … + Download completed, installing … + New Update Available! + Rate this app + What\'s new in this version: + Please rate us! + Ignore + Later + Update + OK + Not now \ No newline at end of file diff --git a/library/wversionmanager/src/main/res/xml/provider_paths.xml b/library/wversionmanager/src/main/res/xml/provider_paths.xml new file mode 100644 index 0000000..11ab4b0 --- /dev/null +++ b/library/wversionmanager/src/main/res/xml/provider_paths.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file