diff --git a/README.md b/README.md index e1dc49b..4dc387a 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,12 @@ A modern About Box for an Android App built on the [daniel-stoneuk/material-abou ## About -Android About Box is configured with a set of (mostly) strings for the company name, twitter and Facebook accounts, website, and filenames to html files for help files, privacy policy etc. +Android About Box is configured with a set of (mostly) strings for the company name, twitter and Facebook accounts, website, and filenames to html files for help files, privacy policy etc. When triggered from a menu item, it will display the app name, icon and version, provide links to contact support, leave a review, share the app, go to other apps by the same company in the app store -- as well as links to Facebook etc. +As of version 1.1.0, you can also optionally provide a help file with the `aboutConfig.guideHtmlPath` setting. Leave it unset (null or empty string) and the behaviour is compatible with version 1.0.x. + ## Installation Instructions Add the JitPack.io repository to your root `build.gradle`: @@ -100,6 +102,32 @@ Open AboutBox screen AboutActivity.launch(activity); ``` +## Theme + +Add to your AndroidManifest.xml file + +``` + +``` + +Ensure that `AppTheme.MaterialAboutActivity` theme extends either of these themes, and apply primary & accent colours: +``` +Theme.Mal.Light.DarkActionBar +Theme.Mal.Light.LightActionBar +Theme.Mal.Dark.LightActionBar +Theme.Mal.Dark.DarkActionBar +``` + +``` + +``` ## Screenshot diff --git a/circle.yml b/circle.yml index e6a8356..ed917c0 100644 --- a/circle.yml +++ b/circle.yml @@ -1,7 +1,7 @@ dependencies: pre: - - echo y | android update sdk --no-ui --all --filter tools,platform-tools,android-24 - - echo y | android update sdk --no-ui --all --filter build-tools-24.0.2 + - echo y | android update sdk --no-ui --all --filter tools,platform-tools,android-25 + - echo y | android update sdk --no-ui --all --filter build-tools-25.0.2 test: override: diff --git a/library/build.gradle b/library/build.gradle index 6dacbaf..aeb3fb9 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -6,13 +6,13 @@ group='com.github.eggheadgames' android { compileSdkVersion 24 - buildToolsVersion "24.0.2" + buildToolsVersion "25.0.2" defaultConfig { minSdkVersion 15 targetSdkVersion 24 - versionCode 3 - versionName "1.0.2" + versionCode 4 + versionName "1.1.0" } buildTypes { release { @@ -28,8 +28,8 @@ android { } dependencies { - compile 'com.github.daniel-stoneuk:material-about-library:1.5.0' - compile('io.branch.sdk.android:library:2.5.7') { + compile 'com.github.daniel-stoneuk:material-about-library:1.8.2' + compile('io.branch.sdk.android:library:2.6.1') { exclude module: 'answers.shim' } } diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index 017747f..ef784a0 100644 --- a/library/src/main/AndroidManifest.xml +++ b/library/src/main/AndroidManifest.xml @@ -1,10 +1,10 @@ + package="com.eggheadgames.aboutbox"> + android:theme="@style/AppTheme.MaterialAboutActivity"/> diff --git a/library/src/main/java/com/eggheadgames/aboutbox/AboutConfig.java b/library/src/main/java/com/eggheadgames/aboutbox/AboutConfig.java index 490fc95..64bb21d 100644 --- a/library/src/main/java/com/eggheadgames/aboutbox/AboutConfig.java +++ b/library/src/main/java/com/eggheadgames/aboutbox/AboutConfig.java @@ -13,6 +13,7 @@ public class AboutConfig { public String facebookUserName; public String twitterUserName; public String webHomePage; + public String guideHtmlPath; public String appPublisher; public String companyHtmlPath; public String privacyHtmlPath; diff --git a/library/src/main/java/com/eggheadgames/aboutbox/activity/AboutActivity.java b/library/src/main/java/com/eggheadgames/aboutbox/activity/AboutActivity.java index 14674e5..74ec6fc 100644 --- a/library/src/main/java/com/eggheadgames/aboutbox/activity/AboutActivity.java +++ b/library/src/main/java/com/eggheadgames/aboutbox/activity/AboutActivity.java @@ -5,14 +5,18 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.support.annotation.NonNull; +import android.text.TextUtils; import android.widget.Toast; import com.danielstone.materialaboutlibrary.MaterialAboutActivity; -import com.danielstone.materialaboutlibrary.model.MaterialAboutActionItem; +import com.danielstone.materialaboutlibrary.items.MaterialAboutActionItem; +import com.danielstone.materialaboutlibrary.items.MaterialAboutItemOnClickListener; +import com.danielstone.materialaboutlibrary.items.MaterialAboutTitleItem; import com.danielstone.materialaboutlibrary.model.MaterialAboutCard; import com.danielstone.materialaboutlibrary.model.MaterialAboutList; -import com.danielstone.materialaboutlibrary.model.MaterialAboutTitleItem; import com.eggheadgames.aboutbox.AboutConfig; +import com.eggheadgames.aboutbox.IAnalytic; import com.eggheadgames.aboutbox.R; import com.eggheadgames.aboutbox.share.EmailUtil; import com.eggheadgames.aboutbox.share.ShareUtil; @@ -29,6 +33,18 @@ public class AboutActivity extends MaterialAboutActivity { final AboutConfig config = AboutConfig.getInstance(); + return new MaterialAboutList.Builder() + .addCard(buildGeneralInfoCard(config)) + .addCard(buildSupportCard(config)) + .addCard(buildShareCard(config)) + .addCard(buildAboutCard(config)) + .addCard(buildSocialNetworksCard(config)) + .addCard(buildPrivacyCard(config)) + .build(); + } + + @NonNull + private MaterialAboutCard buildGeneralInfoCard(AboutConfig config) { MaterialAboutCard.Builder generalInfoCardBuilder = new MaterialAboutCard.Builder(); generalInfoCardBuilder.addItem(new MaterialAboutTitleItem.Builder() @@ -40,181 +56,184 @@ public class AboutActivity extends MaterialAboutActivity { .text(R.string.egab_version) .subText(config.version) .build()); - - - MaterialAboutCard.Builder supportCardBuilder = new MaterialAboutCard.Builder(); - supportCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_contact_support) - .icon(R.drawable.ic_email_black) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - EmailUtil.contactUs(AboutActivity.this); - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_contact_log_event)); - } - } - }) - .build()); - - - MaterialAboutCard.Builder shareCardBuilder = new MaterialAboutCard.Builder(); - shareCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_leave_review) - .icon(R.drawable.ic_review) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - openApp(config.buildType, config.packageName); - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_review_log_event)); - } - } - }) - .build()); - shareCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_share) - .icon(R.drawable.ic_share_black) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - ShareUtil.share(AboutActivity.this); - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_share_log_event)); - } - } - }) - .build()); - - - MaterialAboutCard.Builder aboutCardBuilder = new MaterialAboutCard.Builder(); - aboutCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_try_other_apps) - .icon(R.drawable.ic_try_other_apps) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - openPublisher(config.buildType, config.appPublisher, config.packageName); - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_try_other_app_log_event)); - } - } - }) - .build()); - aboutCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(config.aboutLabelTitle) - .icon(R.drawable.ic_about_black) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - if (config.dialog == null) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(config.companyHtmlPath))); - } else { - config.dialog.open(AboutActivity.this, config.companyHtmlPath, config.aboutLabelTitle); - } - - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, config.aboutLabelTitle); - } - } - }) - .build()); - - - MaterialAboutCard.Builder socialNetworksCardBuilder = new MaterialAboutCard.Builder(); - socialNetworksCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_facebook_label) - .subText(config.facebookUserName) - .icon(R.drawable.ic_facebook_24) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - getOpenFacebookIntent(AboutActivity.this, config.facebookUserName); - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_facebook_log_event)); - } - } - }) - .build()); - socialNetworksCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_twitter_label) - .subText(config.twitterUserName) - .icon(R.drawable.ic_twitter_24dp) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - startTwitter(AboutActivity.this, config.twitterUserName); - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_twitter_log_event)); - } - } - }) - .build()); - - socialNetworksCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_web_label) - .subText(config.webHomePage.replace("https://", "").replace("http://", "").replace("/", "")) - .icon(R.drawable.ic_web_black_24dp) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(config.webHomePage))); - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_website_log_event)); - } - } - }) - .build()); - - MaterialAboutCard.Builder privacyCardBuilder = new MaterialAboutCard.Builder(); - privacyCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_privacy_policy) - .icon(R.drawable.ic_privacy) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - if (config.dialog == null) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(config.privacyHtmlPath))); - } else { - config.dialog.open(AboutActivity.this, config.privacyHtmlPath, getString(R.string.egab_privacy_policy)); - } - - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_privacy_log_event)); - } - } - }) - .build()); - privacyCardBuilder.addItem(new MaterialAboutActionItem.Builder() - .text(R.string.egab_acknowledgements) - .icon(R.drawable.ic_acknowledgements) - .setOnClickListener(new MaterialAboutActionItem.OnClickListener() { - @Override - public void onClick() { - if (config.dialog == null) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(config.acknowledgmentHtmlPath))); - } else { - config.dialog.open(AboutActivity.this, config.acknowledgmentHtmlPath, getString(R.string.egab_acknowledgements)); - } - - if (config.analytics != null) { - config.analytics.logUiEvent(config.logUiEventName, getString(R.string.egab_acknowledgements_log_event)); - } - } - }) - .build()); - - - return new MaterialAboutList.Builder() - .addCard(generalInfoCardBuilder.build()) - .addCard(supportCardBuilder.build()) - .addCard(shareCardBuilder.build()) - .addCard(aboutCardBuilder.build()) - .addCard(socialNetworksCardBuilder.build()) - .addCard(privacyCardBuilder.build()) - .build(); + return generalInfoCardBuilder.build(); } + @NonNull + private MaterialAboutCard buildSupportCard(final AboutConfig config) { + MaterialAboutCard.Builder card = new MaterialAboutCard.Builder(); + + if (!TextUtils.isEmpty(config.guideHtmlPath)) { + card.addItem(itemHelper(R.string.egab_guide, R.drawable.ic_help_green, + new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + if (config.dialog == null) { + openHTMLPage(config.guideHtmlPath); + } else { + config.dialog.open(AboutActivity.this, config.guideHtmlPath, getString(R.string.egab_guide)); + } + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_guide)); + } + }) + ); + } + card.addItem(itemHelper(R.string.egab_contact_support, R.drawable.ic_email_black, + new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + EmailUtil.contactUs(AboutActivity.this); + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_contact_log_event)); + } + })); + + return card.build(); + } + + @NonNull + private MaterialAboutCard buildShareCard(final AboutConfig config) { + MaterialAboutCard.Builder card = new MaterialAboutCard.Builder(); + + card.addItem(itemHelper(R.string.egab_leave_review, R.drawable.ic_review, + new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + openApp(config.buildType, config.packageName); + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_review_log_event)); + } + })); + + card.addItem(itemHelper(R.string.egab_share, R.drawable.ic_share_black, + new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + ShareUtil.share(AboutActivity.this); + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_share_log_event)); + } + })); + + return card.build(); + } + + @NonNull + private MaterialAboutCard buildAboutCard(final AboutConfig config) { + MaterialAboutCard.Builder card = new MaterialAboutCard.Builder(); + + card.addItem(itemHelper(R.string.egab_try_other_apps, R.drawable.ic_try_other_apps, + new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + openPublisher(config.buildType, config.appPublisher, config.packageName); + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_try_other_app_log_event)); + } + })); + card.addItem(new MaterialAboutActionItem.Builder() + .text(config.aboutLabelTitle) + .icon(R.drawable.ic_about_black) + .setOnClickListener(new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + if (config.dialog == null) { + openHTMLPage(config.companyHtmlPath); + } else { + config.dialog.open(AboutActivity.this, config.companyHtmlPath, config.aboutLabelTitle); + } + logUIEventName(config.analytics, config.logUiEventName, config.aboutLabelTitle); + } + }) + .build()); + + return card.build(); + } + + @NonNull + private MaterialAboutCard buildSocialNetworksCard(final AboutConfig config) { + MaterialAboutCard.Builder card = new MaterialAboutCard.Builder(); + + card.addItem(new MaterialAboutActionItem.Builder() + .text(R.string.egab_facebook_label) + .subText(config.facebookUserName) + .icon(R.drawable.ic_facebook_24) + .setOnClickListener(new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + getOpenFacebookIntent(AboutActivity.this, config.facebookUserName); + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_facebook_log_event)); + } + }) + .build()); + card.addItem(new MaterialAboutActionItem.Builder() + .text(R.string.egab_twitter_label) + .subText(config.twitterUserName) + .icon(R.drawable.ic_twitter_24dp) + .setOnClickListener(new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + startTwitter(AboutActivity.this, config.twitterUserName); + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_twitter_log_event)); + } + }) + .build()); + + card.addItem(new MaterialAboutActionItem.Builder() + .text(R.string.egab_web_label) + .subText(config.webHomePage.replace("https://", "").replace("http://", "").replace("/", "")) + .icon(R.drawable.ic_web_black_24dp) + .setOnClickListener(new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + openHTMLPage(config.webHomePage); + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_website_log_event)); + } + }) + .build()); + + return card.build(); + } + + @NonNull + private MaterialAboutCard buildPrivacyCard(final AboutConfig config) { + MaterialAboutCard.Builder card = new MaterialAboutCard.Builder(); + + card.addItem(itemHelper(R.string.egab_privacy_policy, R.drawable.ic_privacy, + new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + if (config.dialog == null) { + openHTMLPage(config.privacyHtmlPath); + } else { + config.dialog.open(AboutActivity.this, config.privacyHtmlPath, getString(R.string.egab_privacy_policy)); + } + + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_privacy_log_event)); + } + }) + ); + card.addItem(itemHelper(R.string.egab_acknowledgements, R.drawable.ic_acknowledgements, + new MaterialAboutItemOnClickListener() { + @Override + public void onClick(boolean b) { + if (config.dialog == null) { + openHTMLPage(config.acknowledgmentHtmlPath); + } else { + config.dialog.open(AboutActivity.this, config.acknowledgmentHtmlPath, getString(R.string.egab_acknowledgements)); + } + logUIEventName(config.analytics, config.logUiEventName, getString(R.string.egab_acknowledgements_log_event)); + } + }) + ); + return card.build(); + } + + private MaterialAboutActionItem itemHelper(int name, int icon, MaterialAboutItemOnClickListener listener) { + return new MaterialAboutActionItem.Builder() + .text(name) + .icon(icon) + .setOnClickListener(listener) + .build(); + } + + @Override protected CharSequence getActivityTitle() { return getString(R.string.egab_about_screen_title); @@ -249,7 +268,6 @@ public class AboutActivity extends MaterialAboutActivity { Toast.makeText(context, R.string.egab_can_not_open, Toast.LENGTH_SHORT).show(); } } - } public void openApp(AboutConfig.BuildType buildType, String packageName) { @@ -267,7 +285,7 @@ public class AboutActivity extends MaterialAboutActivity { default: //nothing } - open(appURI, webURI); + openApplication(appURI, webURI); } public void openPublisher(AboutConfig.BuildType buildType, String publisher, String packageName) { @@ -285,18 +303,28 @@ public class AboutActivity extends MaterialAboutActivity { default: //nothing } - open(appURI, webURI); + openApplication(appURI, webURI); } - private void open(String appURI, String webURI) { + private void openApplication(String appURI, String webURI) { try { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(appURI))); } catch (ActivityNotFoundException e1) { try { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(webURI))); + openHTMLPage(webURI); } catch (ActivityNotFoundException e2) { Toast.makeText(this, R.string.egab_can_not_open, Toast.LENGTH_SHORT).show(); } } } + + private void openHTMLPage(String htmlPath) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(htmlPath))); + } + + private void logUIEventName(IAnalytic analytics, String eventType, String eventValue) { + if (analytics != null) { + analytics.logUiEvent(eventType, eventValue); + } + } } diff --git a/library/src/main/res/drawable/ic_help_green.xml b/library/src/main/res/drawable/ic_help_green.xml new file mode 100644 index 0000000..e1e7ce0 --- /dev/null +++ b/library/src/main/res/drawable/ic_help_green.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/library/src/main/res/values-pt/strings.xml b/library/src/main/res/values-pt/strings.xml index 9f31aeb..0e6a643 100644 --- a/library/src/main/res/values-pt/strings.xml +++ b/library/src/main/res/values-pt/strings.xml @@ -21,4 +21,5 @@ Acknowledgements Tu não tens nenhuma aplicação que possa abrir esta ligação Digite sua pergunta aqui: + Guia diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml index cdf08c3..b979e55 100644 --- a/library/src/main/res/values/strings.xml +++ b/library/src/main/res/values/strings.xml @@ -21,5 +21,6 @@ Acknowledgements You don\'t have any app that can open this link Please type your question here: + Guide