diff --git a/README.md b/README.md index f75455f..cc9f881 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # ckChangeLog - An Android Library to display a Change Log - - + This library provides an easy way to display a change log in your app. diff --git a/ckChangeLog/.gitignore b/ckChangeLog/.gitignore new file mode 100644 index 0000000..a5e492a --- /dev/null +++ b/ckChangeLog/.gitignore @@ -0,0 +1,50 @@ +#Android generated +bin +gen +build + +#built application files +*.apk +*.ap_ + +# files for the dex VM +*.dex + +# Java class files +*.class + +#Eclipse +.project +.classpath +.settings + +# Intellij IDEA (see https://intellij-support.jetbrains.com/entries/23393067) +.idea +*.iml + +#Maven +target +release.properties +pom.xml.* + +#Command line +local.properties +build.xml +proguard-project.txt + +# Windows thumbnail db +Thumbs.db + +# OSX files +.DS_Store + +# Crashlytics +com_crashlytics_export_strings.xml +crashlytics-build.properties +crashlytics.properties + +# Android Studio +.gradle +gradle +gradlew +gradlew.bat \ No newline at end of file diff --git a/ckChangeLog/build.gradle b/ckChangeLog/build.gradle index d15f833..4e93ba0 100644 --- a/ckChangeLog/build.gradle +++ b/ckChangeLog/build.gradle @@ -4,10 +4,15 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:1.0.0' + classpath 'com.android.tools.build:gradle:1.2.2' } } +repositories { + jcenter() + mavenCentral() +} + apply plugin: 'com.android.library' android { @@ -15,12 +20,16 @@ android { buildToolsVersion "21.1.2" defaultConfig { - versionName "1.2.2" - - minSdkVersion 4 + versionName "2.0.0" + minSdkVersion 9 } } +dependencies { + compile 'com.afollestad:material-dialogs:0.7.2.8' + compile 'se.emilsjolander:stickylistheaders:2.5.2' +} + project.ext { pom = [ group: "de.cketti.library.changelog", @@ -42,5 +51,5 @@ project.ext { ] } -apply from: '../android-mvn-push.gradle' +//apply from: '../android-mvn-push.gradle' diff --git a/ckChangeLog/src/main/java/de/cketti/library/changelog/ChangeLog.java b/ckChangeLog/src/main/java/de/cketti/library/changelog/ChangeLog.java index b87b3f0..6a59c08 100644 --- a/ckChangeLog/src/main/java/de/cketti/library/changelog/ChangeLog.java +++ b/ckChangeLog/src/main/java/de/cketti/library/changelog/ChangeLog.java @@ -33,18 +33,7 @@ */ package de.cketti.library.changelog; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import android.app.AlertDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; @@ -52,7 +41,19 @@ import android.preference.PreferenceManager; import android.util.Log; import android.util.SparseArray; -import android.webkit.WebView; + +import com.afollestad.materialdialogs.MaterialDialog; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** @@ -60,6 +61,7 @@ */ @SuppressWarnings("UnusedDeclaration") public class ChangeLog { + /** * Tag that is used when sending error/debug messages to the log. */ @@ -75,25 +77,11 @@ public class ChangeLog { */ protected static final int NO_VERSION = -1; - /** - * Default CSS styles used to format the change log. - */ - public static final String DEFAULT_CSS = - "h1 { margin-left: 0px; font-size: 1.2em; }" + "\n" + - "li { margin-left: 0px; }" + "\n" + - "ul { padding-left: 2em; }"; - - /** * Context that is used to access the resources and to create the ChangeLog dialogs. */ protected final Context mContext; - /** - * Contains the CSS rules used to format the change log. - */ - protected final String mCss; - /** * Last version code read from {@code SharedPreferences} or {@link #NO_VERSION}. */ @@ -114,70 +102,53 @@ public class ChangeLog { * Contains constants for the root element of {@code changelog.xml}. */ protected interface ChangeLogTag { - static final String NAME = "changelog"; + + String NAME = "changelog"; } /** * Contains constants for the release element of {@code changelog.xml}. */ protected interface ReleaseTag { - static final String NAME = "release"; - static final String ATTRIBUTE_VERSION = "version"; - static final String ATTRIBUTE_VERSION_CODE = "versioncode"; + + String NAME = "release"; + String ATTRIBUTE_VERSION = "version"; + String ATTRIBUTE_VERSION_CODE = "versioncode"; } /** * Contains constants for the change element of {@code changelog.xml}. */ protected interface ChangeTag { - static final String NAME = "change"; - } - /** - * Create a {@code ChangeLog} instance using the default {@link SharedPreferences} file. - * - * @param context - * Context that is used to access the resources and to create the ChangeLog dialogs. - */ - public ChangeLog(Context context) { - this(context, PreferenceManager.getDefaultSharedPreferences(context), DEFAULT_CSS); + String NAME = "change"; } /** * Create a {@code ChangeLog} instance using the default {@link SharedPreferences} file. * - * @param context - * Context that is used to access the resources and to create the ChangeLog dialogs. - * @param css - * CSS styles that will be used to format the change log. + * @param context Context that is used to access the resources and to create the ChangeLog dialogs. */ - public ChangeLog(Context context, String css) { - this(context, PreferenceManager.getDefaultSharedPreferences(context), css); + public ChangeLog(Context context) { + this(context, PreferenceManager.getDefaultSharedPreferences(context)); } /** * Create a {@code ChangeLog} instance using the supplied {@code SharedPreferences} instance. * - * @param context - * Context that is used to access the resources and to create the ChangeLog dialogs. - * @param preferences - * {@code SharedPreferences} instance that is used to persist the last version code. - * @param css - * CSS styles used to format the change log (excluding {@code }). - * + * @param context Context that is used to access the resources and to create the ChangeLog dialogs. + * @param preferences {@code SharedPreferences} instance that is used to persist the last version code. */ - public ChangeLog(Context context, SharedPreferences preferences, String css) { + public ChangeLog(Context context, SharedPreferences preferences) { mContext = context; - mCss = css; // Get last version code mLastVersionCode = preferences.getInt(VERSION_KEY, NO_VERSION); // Get current version code and version name try { - PackageInfo packageInfo = context.getPackageManager().getPackageInfo( - context.getPackageName(), 0); + PackageInfo packageInfo = context.getPackageManager() + .getPackageInfo(context.getPackageName(), 0); mCurrentVersionCode = packageInfo.versionCode; mCurrentVersionName = packageInfo.versionName; @@ -191,10 +162,9 @@ public ChangeLog(Context context, SharedPreferences preferences, String css) { * Get version code of last installation. * * @return The version code of the last installation of this app (as described in the former - * manifest). This will be the same as returned by {@link #getCurrentVersionCode()} the - * second time this version of the app is launched (more precisely: the second time - * {@code ChangeLog} is instantiated). - * + * manifest). This will be the same as returned by {@link #getCurrentVersionCode()} the + * second time this version of the app is launched (more precisely: the second time + * {@code ChangeLog} is instantiated). * @see android:versionCode */ public int getLastVersionCode() { @@ -205,7 +175,6 @@ public int getLastVersionCode() { * Get version code of current installation. * * @return The version code of this app as described in the manifest. - * * @see android:versionCode */ public int getCurrentVersionCode() { @@ -216,7 +185,6 @@ public int getCurrentVersionCode() { * Get version name of current installation. * * @return The version name of this app as described in the manifest. - * * @see android:versionName */ public String getCurrentVersionName() { @@ -236,7 +204,7 @@ public boolean isFirstRun() { * Check if this is a new installation. * * @return {@code true} if your app including {@code ChangeLog} is started the first time ever. - * Also {@code true} if your app was uninstalled and installed again. + * Also {@code true} if your app was uninstalled and installed again. */ public boolean isFirstRunEver() { return mLastVersionCode == NO_VERSION; @@ -244,7 +212,7 @@ public boolean isFirstRunEver() { /** * Skip the "What's new" dialog for this app version. - * + *
** Future calls to {@link #isFirstRun()} and {@link #isFirstRunEver()} will return {@code false} * for the current app version. @@ -258,10 +226,10 @@ public void skipLogDialog() { * Get the "What's New" dialog. * * @return An AlertDialog displaying the changes since the previous installed version of your - * app (What's New). But when this is the first run of your app including - * {@code ChangeLog} then the full log dialog is show. + * app (What's New). But when this is the first run of your app including + * {@code ChangeLog} then the full log dialog is show. */ - public AlertDialog getLogDialog() { + public MaterialDialog getLogDialog() { return getDialog(isFirstRunEver()); } @@ -270,142 +238,78 @@ public AlertDialog getLogDialog() { * * @return An AlertDialog with a full change log displayed. */ - public AlertDialog getFullLogDialog() { + public MaterialDialog getFullLogDialog() { return getDialog(true); } /** * Create a dialog containing (parts of the) change log. * - * @param full - * If this is {@code true} the full change log is displayed. Otherwise only changes for - * versions newer than the last version are displayed. - * + * @param full If this is {@code true} the full change log is displayed. Otherwise only changes for + * versions newer than the last version are displayed. * @return A dialog containing the (partial) change log. */ - protected AlertDialog getDialog(boolean full) { - WebView wv = new WebView(mContext); - //wv.setBackgroundColor(0); // transparent - wv.loadDataWithBaseURL(null, getLog(full), "text/html", "UTF-8", null); - - AlertDialog.Builder builder = new AlertDialog.Builder(mContext); - builder.setTitle( - mContext.getResources().getString( - full ? R.string.changelog_full_title : R.string.changelog_title)) - .setView(wv) - .setCancelable(false) - // OK button - .setPositiveButton( - mContext.getResources().getString(R.string.changelog_ok_button), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // The user clicked "OK" so save the current version code as - // "last version code". - updateVersionInPreferences(); - } - }); + protected MaterialDialog getDialog(boolean full) { + MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext); + builder.title(mContext.getResources().getString(full ? R.string.changelog_full_title : R.string.changelog_title)); + builder.cancelable(false); + builder.positiveText(mContext.getResources().getString(R.string.changelog_ok_button)); + builder.callback(new ChangelogButtonCallback()); + builder.customView(R.layout.dialog_layout, false); if (!full) { // Show "Moreā¦" button if we're only displaying a partial change log. - builder.setNegativeButton(R.string.changelog_show_full, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - getFullLogDialog().show(); - } - }); + builder.neutralText(R.string.changelog_show_full); } - return builder.create(); - } + MaterialDialog dialog = builder.build(); - /** - * Write current version code to the preferences. - */ - protected void updateVersionInPreferences() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(VERSION_KEY, mCurrentVersionCode); + ChangelogListAdapter adapter = new ChangelogListAdapter(mContext, getChangeLog(full)); + ((StickyListHeadersListView) dialog.getCustomView()).setAdapter(adapter); - // TODO: Update preferences from a background thread - editor.commit(); + return dialog; } - /** - * Get changes since last version as HTML string. - * - * @return HTML string containing the changes since the previous installed version of your app - * (What's New). - */ - public String getLog() { - return getLog(false); - } + private class ChangelogButtonCallback extends MaterialDialog.ButtonCallback { - /** - * Get full change log as HTML string. - * - * @return HTML string containing the full change log. - */ - public String getFullLog() { - return getLog(true); + @Override + public void onNeutral(MaterialDialog dialog) { + getFullLogDialog().show(); + } + + @Override + public void onPositive(MaterialDialog dialog) { + // The user clicked "OK" so save the current version code as + // "last version code". + updateVersionInPreferences(); + } } /** - * Get (partial) change log as HTML string. - * - * @param full - * If this is {@code true} the full change log is returned. Otherwise only changes for - * versions newer than the last version are returned. - * - * @return The (partial) change log. + * Write current version code to the preferences. */ - protected String getLog(boolean full) { - StringBuilder sb = new StringBuilder(); - - sb.append("
"); - - String versionFormat = mContext.getResources().getString(R.string.changelog_version_format); - - List* The default implementation returns the items in reverse order (latest version first). *
*/ protected Comparator