diff --git a/app/build.gradle b/app/build.gradle
index 793a76f1..19896c91 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -132,5 +132,6 @@ dependencies {
compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar'
//noinspection GradleDynamicVersion
compile 'com.anjlab.android.iab.v3:library:1.0.+'
- compile('de.psdev.licensesdialog:licensesdialog:1.8.0')
+ compile 'de.psdev.licensesdialog:licensesdialog:1.8.0'
+ compile 'com.github.kabouzeid:AppIntro:3.3.0k'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 972cc9d9..def6e912 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -139,6 +139,10 @@
+
+
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/IntroActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/IntroActivity.java
new file mode 100644
index 00000000..b78643a8
--- /dev/null
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/IntroActivity.java
@@ -0,0 +1,37 @@
+package com.kabouzeid.gramophone.ui.activities;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.content.ContextCompat;
+
+import com.github.paolorotolo.appintro.AppIntro;
+import com.github.paolorotolo.appintro.AppIntroFragment;
+import com.kabouzeid.gramophone.R;
+import com.kabouzeid.gramophone.util.ColorUtil;
+
+/**
+ * @author Karim Abou Zeid (kabouzeid)
+ */
+public class IntroActivity extends AppIntro {
+ @Override
+ public void init(Bundle savedInstanceState) {
+ int color = ContextCompat.getColor(this, R.color.blue_grey_700);
+ setStatusBarColor(ColorUtil.shiftColorDown(color));
+
+ addSlide(AppIntroFragment.newInstance(getString(R.string.app_name), "Welcome to Phonograph, a beautiful and lightweight music player for Android. ", R.drawable.icon_web, color));
+ if (!hasExternalStoragePermission()) {
+ addSlide(AppIntroFragment.newInstance("Storage", "The storage permission is required for Phonograph to read your music library.", R.drawable.ic_folder_web, color));
+ askForPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
+ }
+ addSlide(AppIntroFragment.newInstance(getString(R.string.label_current_playing_queue), "You can swipe the card in the now playing screen up to reveal to full playing queue.", R.drawable.intro_swipe_up, color));
+ }
+
+ private boolean hasExternalStoragePermission() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
+ }
+ return true;
+ }
+}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java
index 30bc464d..f8eeafb7 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/MainActivity.java
@@ -114,6 +114,17 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
setStatusBarThemeColor();
checkChangelog();
+
+ PreferenceUtil.getInstance(this).incrementAppOpenCount();
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (PreferenceUtil.getInstance(MainActivity.this).getAppOpenCount() == 1) {
+ startActivity(new Intent(MainActivity.this, IntroActivity.class));
+ }
+ }
+ }).start();
}
@Override
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsBaseActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsBaseActivity.java
index 313fa262..450ccb1f 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsBaseActivity.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsBaseActivity.java
@@ -8,9 +8,11 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
+import android.support.design.widget.Snackbar;
import android.view.KeyEvent;
-import android.widget.Toast;
+import android.view.View;
+import com.afollestad.materialdialogs.internal.ThemeSingleton;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
@@ -28,7 +30,7 @@ public abstract class AbsBaseActivity extends AbsThemeActivity implements KabVie
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
- checkExternalStoragePermissions();
+ hasExternalStoragePermission = hasExternalStoragePermission();
}
@Override
@@ -36,13 +38,17 @@ public abstract class AbsBaseActivity extends AbsThemeActivity implements KabVie
super.onResume();
enableViews();
- // the handler is necessary to avoid "java.lang.RuntimeException: Performing pause of activity that is not resumed"
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- recreateIfPermissionsChanged();
- }
- }, 200);
+ if (!hasExternalStoragePermission()) {
+ requestPermissions();
+ } else if (didPermissionsChanged()) {
+ // the handler is necessary to avoid "java.lang.RuntimeException: Performing pause of activity that is not resumed"
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ recreate();
+ }
+ }, 200);
+ }
}
@Override
@@ -83,22 +89,13 @@ public abstract class AbsBaseActivity extends AbsThemeActivity implements KabVie
return areViewsEnabled;
}
- protected void recreateIfPermissionsChanged() {
- if (didPermissionsChanged()) {
- recreate();
- }
- }
-
private boolean didPermissionsChanged() {
return hasExternalStoragePermission != hasExternalStoragePermission();
}
- private void checkExternalStoragePermissions() {
- hasExternalStoragePermission = hasExternalStoragePermission();
- if (!hasExternalStoragePermission) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_EXTERNAL_STORAGE_PERMISSION);
- }
+ private void requestPermissions() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_EXTERNAL_STORAGE_PERMISSION);
}
}
@@ -117,7 +114,17 @@ public abstract class AbsBaseActivity extends AbsThemeActivity implements KabVie
return;
}
}
- Toast.makeText(this, getResources().getString(R.string.permission_to_access_external_storage_denied), Toast.LENGTH_SHORT).show();
+ Snackbar.make(getWindow().getDecorView(), R.string.permission_to_access_external_storage_denied, Snackbar.LENGTH_INDEFINITE)
+ .setAction(getString(R.string.action_settings), onGoToPermissionSettingsClickListener)
+ .setActionTextColor(ThemeSingleton.get().positiveColor)
+ .show();
}
}
+
+ private View.OnClickListener onGoToPermissionSettingsClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //TODO
+ }
+ };
}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java
index d6e9bd03..9f302d27 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java
@@ -62,6 +62,8 @@ public final class PreferenceUtil {
public static final String LAST_CHANGELOG_VERSION = "last_changelog_version";
+ public static final String APP_OPEN_COUNT = "app_open_count";
+
private static PreferenceUtil sInstance;
private final SharedPreferences mPreferences;
@@ -361,4 +363,12 @@ public final class PreferenceUtil {
public final int getLastChangelogVersion() {
return mPreferences.getInt(LAST_CHANGELOG_VERSION, -1);
}
+
+ public void incrementAppOpenCount() {
+ mPreferences.edit().putInt(APP_OPEN_COUNT, getAppOpenCount() + 1).apply();
+ }
+
+ public final int getAppOpenCount() {
+ return mPreferences.getInt(APP_OPEN_COUNT, 0);
+ }
}
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_folder_web.png b/app/src/main/res/drawable-xxxhdpi/ic_folder_web.png
new file mode 100644
index 00000000..ba79cecc
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_folder_web.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_web.png b/app/src/main/res/drawable-xxxhdpi/icon_web.png
new file mode 100644
index 00000000..5f9e782e
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_web.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/intro_swipe_up.png b/app/src/main/res/drawable-xxxhdpi/intro_swipe_up.png
new file mode 100644
index 00000000..d9e2c11c
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/intro_swipe_up.png differ
diff --git a/app/src/main/res/raw/notices.xml b/app/src/main/res/raw/notices.xml
index 696ac003..0fd0a273 100644
--- a/app/src/main/res/raw/notices.xml
+++ b/app/src/main/res/raw/notices.xml
@@ -88,6 +88,12 @@
Copyright 2014 AnjLab
Apache Software License 2.0
+
+ AppIntro
+ https://github.com/PaoloRotolo/AppIntro
+ Copyright {2015} {Paolo Rotolo}
+ Apache Software License 2.0
+
Material Dialogs
https://github.com/afollestad/material-dialogs
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 5be53518..6178831a 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -8,6 +8,8 @@
#424242
#E0E0E0
+ #455A64
+
#FFFFFF
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 32452ff3..9ef9cf3a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -9,6 +9,7 @@
Share
"Settings"
About
+ Show intro
Clear playlist
Playing queue
Add to favorites
@@ -212,4 +213,5 @@
Loading products…
Up next
Now playing layout
+ Intro
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 382b3953..dd509116 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip