diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
new file mode 100644
index 000000000..df6cb062c
--- /dev/null
+++ b/.github/workflows/android.yml
@@ -0,0 +1,18 @@
+name: Android CI
+
+on: [push, pull_request]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'adopt'
+ java-version: '11'
+ - name: Build with Gradle
+ run: ./gradlew assembleDebug
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b94e59548..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: android
-
-branches:
- only:
- - master
-
-script: "./gradlew clean assembleDebug"
-
-android:
- components:
- - platform-tools
- - tools
- - build-tools-24.0.3
- - android-24
- - extra-android-m2repository
\ No newline at end of file
diff --git a/README.md b/README.md
index 53605457b..c3bc1fbfe 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,41 @@
# Timber
-[![Build Status](https://travis-ci.org/naman14/Timber.svg?branch=master)](https://travis-ci.org/naman14/Timber)
-[WIP][BETA]-Material Design Music Player
+Material Design Music Player
-
-[![Get it on F-Droid](https://guardianproject.info/wp-content/uploads/2014/07/logo-fdroid.png)](https://f-droid.org/repository/browse/?fdid=naman14.timber)
+This project is no longer in active development. Please refer to [TimberX](https://github.com/naman14/TimberX) instead
-## Screenshots
-![](https://raw.githubusercontent.com/naman14/Timber/master/graphics/Screenshot_2015-09-18-12-33-27.png)
-![](https://raw.githubusercontent.com/naman14/Timber/master/graphics/Screenshot_2015-08-05-14-23-03.png)
-![](https://raw.githubusercontent.com/naman14/Timber/master/graphics/Screenshot_2015-08-29-22-44-26.png)
-![](https://raw.githubusercontent.com/naman14/Timber/master/graphics/Screenshot_2015-08-31-11-50-50.png)
-![](https://raw.githubusercontent.com/naman14/Timber/master/graphics/Screenshot_2015-08-31-11-52-50.png)
-## Contribute
-### Translations
+
-If there isn't any translations in your language go to the [res folder](https://github.com/naman14/Timber/blob/master/app/src/main/res/) and create a file named "values-XX/strings.xml" where XX is the target language's code. Copy and paste the content of the [English base file](https://github.com/naman14/Timber/blob/master/app/src/main/res/values/strings.xml) and remove all strings with "translatable=false" attribute. Translate all the keys and make a pull request.
+## Screenshots
-If there is a translation in your language go to its folder in [res folder](https://github.com/naman14/Timber/blob/master/app/src/main/res/) and edit the strings.xml file. You'd like to update the translation with new keys by copying them from the [English base file](https://github.com/naman14/Timber/blob/master/app/src/main/res/values/strings.xml). Edit the file and make a pull request.
+
+
+
+
+
+
+
+
+
+
+
+
+## Features
+- Material design
+- Browse Songs, Albums, Artists
+- Create and edit playlists
+- 6 different now playing styles
+- Homescreen widgets
+- Browse device folders
+- Dark theme and UI customisability
+- Gestures for track switching
+- LastFM scrobble
+- Android Wear and Android Auto support
+- Playing queue in notification (Xposed)
+- Lyrics support
+- Chromecast support
## Changelog
@@ -34,10 +50,6 @@ Changelog is available [here](https://github.com/naman14/Timber/blob/master/Chan
* [CircularSeekBar](https://github.com/devadvance/circularseekbar)
* [Nammu](https://github.com/tajchert/Nammu)
-#Donate
-Paypal donation email-
-namandwivedi14@gmail.com
-
## License
diff --git a/app/build.gradle b/app/build.gradle
index 20602bd86..2963874c7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,30 +1,37 @@
apply plugin: 'com.android.application'
+
android {
- compileSdkVersion 24
- buildToolsVersion '24.0.3'
+ compileSdkVersion rootProject.compileSdkVersion
defaultConfig {
- applicationId "naman14.timber"
- minSdkVersion 16
- targetSdkVersion 24
- versionCode 16
- versionName "0.3b"
+ applicationId "it.fossoft.timberfoss"
+ minSdkVersion rootProject.minSdkVersion
+ targetSdkVersion rootProject.targetSdkVersion
+ versionCode 22
+ versionName "1.8"
//renderscript support mode is not supported for 21+ with gradle version 2.0
- renderscriptTargetApi 20
- renderscriptSupportModeEnabled true
+ renderscriptTargetApi 16
+ renderscriptSupportModeEnabled false
+ multiDexEnabled true
}
+
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+
}
debug {
versionNameSuffix "-debug"
minifyEnabled false
+ applicationIdSuffix '.dev'
+ manifestPlaceholders = [ appNameSuffix:" Dev"]
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+
lintOptions {
disable 'MissingTranslation'
disable 'ExtraTranslation'
@@ -37,29 +44,35 @@ repositories {
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile 'com.android.support:appcompat-v7:24.2.1'
- compile 'com.android.support:recyclerview-v7:24.2.1'
- compile 'com.android.support:cardview-v7:24.2.1'
- compile 'com.android.support:palette-v7:24.2.1'
- compile 'com.android.support:design:24.2.1'
- compile 'com.android.support:percent:24.2.1'
-
- compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
- compile 'net.steamcrafted:materialiconlib:1.0.3'
- compile 'com.squareup.retrofit:retrofit:1.9.0'
- compile 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
- compile 'com.squareup.okhttp:okhttp:2.3.0'
- compile 'com.google.code.gson:gson:2.3'
- compile 'de.Maxr1998:track-selector-lib:1.1'
-
- compile 'com.afollestad.material-dialogs:core:0.9.0.2'
- compile 'com.afollestad.material-dialogs:commons:0.9.0.2'
-
- compile('com.github.naman14:app-theme-engine:0.5.2@aar') {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "androidx.appcompat:appcompat:1.4.1"
+ implementation "com.google.android.material:material:1.6.0"
+ implementation "androidx.cardview:cardview:1.0.0"
+ implementation "androidx.recyclerview:recyclerview:1.2.1"
+ implementation "androidx.palette:palette:1.0.0"
+ implementation "androidx.percentlayout:percentlayout:1.0.0"
+ implementation 'androidx.multidex:multidex:2.0.1'
+
+ implementation "androidx.mediarouter:mediarouter:1.3.0"
+
+
+ implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
+ implementation 'net.steamcrafted:materialiconlib:1.1.4'
+ implementation 'com.squareup.retrofit:retrofit:1.9.0'
+ implementation 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
+ implementation 'com.squareup.okhttp:okhttp:2.3.0'
+ implementation 'com.google.code.gson:gson:2.8.6'
+ implementation 'de.Maxr1998:track-selector-lib:1.2'
+
+ implementation 'com.afollestad.material-dialogs:core:0.9.0.2'
+ implementation 'com.afollestad.material-dialogs:commons:0.9.0.2'
+
+ implementation('com.github.naman14:app-theme-engine:0.5.2@aar') {
transitive = true
}
- compile 'com.anjlab.android.iab.v3:library:1.0.+'
-
+ implementation 'com.anjlab.android.iab.v3:library:1.0.+'
+ implementation 'org.nanohttpd:nanohttpd:2.3.1'
}
+
+apply from: '../mock.gradle'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0e114bdd5..8379bbb2c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,14 +18,14 @@
android:name=".TimberApp"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
+ android:label="Timber"
android:theme="@style/AppTheme.FullScreen.Light"
- tools:replace="android:allowBackup">
+ tools:replace="android:allowBackup, android:label">
+ android:screenOrientation="portrait"
+ android:exported="true">
@@ -84,9 +84,11 @@
android:name=".activities.NowPlayingActivity"
android:theme="@style/AppTheme.FullScreen.Light" />
-
+
+
-
+
@@ -98,20 +100,18 @@
android:label="@string/app_name"
android:process=":main" />
-
-
+ -->
+
-
-
-
+
@@ -121,7 +121,8 @@
android:resource="@xml/widget_standard" />
-
+
@@ -131,7 +132,8 @@
android:resource="@xml/widget_white" />
-
+
diff --git a/app/src/main/aidl/com/naman14/timber/ITimberService.aidl b/app/src/main/aidl/com/naman14/timber/ITimberService.aidl
index d545adcbe..10236c828 100644
--- a/app/src/main/aidl/com/naman14/timber/ITimberService.aidl
+++ b/app/src/main/aidl/com/naman14/timber/ITimberService.aidl
@@ -48,6 +48,5 @@ interface ITimberService
int getRepeatMode();
int getMediaMountedCount();
int getAudioSessionId();
- void setLockscreenAlbumArt(boolean enabled);
}
diff --git a/app/src/main/assets/materialdesignicons-webfont.ttf b/app/src/main/assets/materialdesignicons-webfont.ttf
index 8bb426d3b..69404e3d9 100644
Binary files a/app/src/main/assets/materialdesignicons-webfont.ttf and b/app/src/main/assets/materialdesignicons-webfont.ttf differ
diff --git a/app/src/main/java/com/naman14/timber/MusicPlayer.java b/app/src/main/java/com/naman14/timber/MusicPlayer.java
index 9c8eea716..feb0ce270 100644
--- a/app/src/main/java/com/naman14/timber/MusicPlayer.java
+++ b/app/src/main/java/com/naman14/timber/MusicPlayer.java
@@ -99,16 +99,7 @@ public static void next() {
}
public static void initPlaybackServiceWithSettings(final Context context) {
- setShowAlbumArtOnLockscreen(true);
- }
- public static void setShowAlbumArtOnLockscreen(final boolean enabled) {
- try {
- if (mService != null) {
- mService.setLockscreenAlbumArt(enabled);
- }
- } catch (final RemoteException ignored) {
- }
}
public static void asyncNext(final Context context) {
@@ -515,27 +506,19 @@ public static void playNext(Context context, final long[] list, final long sourc
public static void shuffleAll(final Context context) {
Cursor cursor = SongLoader.makeSongCursor(context, null, null);
- final long[] mTrackList = SongLoader.getSongListForCursor(cursor);
- final int position = 0;
- if (mTrackList.length == 0 || mService == null) {
+ final long[] trackList = SongLoader.getSongListForCursor(cursor);
+ if (trackList.length == 0 || mService == null) {
return;
}
try {
mService.setShuffleMode(MusicService.SHUFFLE_NORMAL);
- final long mCurrentId = mService.getAudioId();
- final int mCurrentQueuePosition = getQueuePosition();
- if (position != -1 && mCurrentQueuePosition == position
- && mCurrentId == mTrackList[position]) {
- final long[] mPlaylist = getQueue();
- if (Arrays.equals(mTrackList, mPlaylist)) {
+ if (getQueuePosition() == 0 && mService.getAudioId() == trackList[0] && Arrays.equals(trackList, getQueue())) {
mService.play();
return;
- }
}
- mService.open(mTrackList, -1, -1, IdType.NA.mId);
+ mService.open(trackList, -1, -1, IdType.NA.mId);
mService.play();
cursor.close();
- cursor = null;
} catch (final RemoteException ignored) {
}
}
@@ -624,6 +607,8 @@ public static void seek(final long position) {
try {
mService.seek(position);
} catch (final RemoteException ignored) {
+ } catch (IllegalStateException ignored) {
+
}
}
}
diff --git a/app/src/main/java/com/naman14/timber/MusicService.java b/app/src/main/java/com/naman14/timber/MusicService.java
index 48426eac3..398c9670f 100644
--- a/app/src/main/java/com/naman14/timber/MusicService.java
+++ b/app/src/main/java/com/naman14/timber/MusicService.java
@@ -17,8 +17,11 @@
import android.Manifest;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
@@ -35,7 +38,10 @@
import android.graphics.Color;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.media.MediaMetadataEditor;
+import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
+import android.media.RemoteControlClient;
import android.media.audiofx.AudioEffect;
import android.net.Uri;
import android.os.Build;
@@ -52,12 +58,13 @@
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AlbumColumns;
import android.provider.MediaStore.Audio.AudioColumns;
-import android.support.v4.app.NotificationManagerCompat;
+import androidx.core.app.NotificationManagerCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
-import android.support.v7.app.NotificationCompat;
-import android.support.v7.graphics.Palette;
+
+import androidx.media.app.NotificationCompat;
+import androidx.palette.graphics.Palette;
import android.text.TextUtils;
import android.util.Log;
@@ -120,6 +127,8 @@ public class MusicService extends Service {
public static final String CMDPREVIOUS = "previous";
public static final String CMDNEXT = "next";
public static final String CMDNOTIF = "buttonId";
+ public static final String UPDATE_PREFERENCES = "updatepreferences";
+ public static final String CHANNEL_ID = "timber_channel_01";
public static final int NEXT = 2;
public static final int LAST = 3;
public static final int SHUFFLE_NONE = 0;
@@ -188,6 +197,8 @@ public class MusicService extends Service {
private boolean mPausedByTransientLossOfFocus = false;
private MediaSessionCompat mSession;
+ @SuppressWarnings("deprecation")
+ private RemoteControlClient mRemoteControlClient;
private ComponentName mMediaButtonReceiverComponent;
@@ -223,6 +234,7 @@ public void onAudioFocusChange(final int focusChange) {
private BroadcastReceiver mUnmountReceiver = null;
private MusicPlaybackState mPlaybackStateStore;
private boolean mShowAlbumArtOnLockscreen;
+ private boolean mActivateXTrackSelector;
private SongPlayCount mSongPlayCount;
private RecentStore mRecentStore;
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -277,6 +289,7 @@ public void onCreate() {
super.onCreate();
mNotificationManager = NotificationManagerCompat.from(this);
+ createNotificationChannel();
// gets a pointer to the playback state store
mPlaybackStateStore = MusicPlaybackState.getInstance(this);
@@ -299,6 +312,8 @@ public void onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
setUpMediaSession();
+ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ setUpRemoteControlClient();
mPreferences = getSharedPreferences("Service", 0);
mCardId = getCardId();
@@ -319,6 +334,8 @@ public void onCreate() {
filter.addAction(PREVIOUS_FORCE_ACTION);
filter.addAction(REPEAT_ACTION);
filter.addAction(SHUFFLE_ACTION);
+ filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
// Attach the broadcast listener
registerReceiver(mIntentReceiver, filter);
@@ -345,6 +362,35 @@ public void onCreate() {
reloadQueueAfterPermissionCheck();
notifyChange(QUEUE_CHANGED);
notifyChange(META_CHANGED);
+ //Try to push LastFMCache
+ if (LastfmUserSession.getSession(this) != null) {
+ LastFmClient.getInstance(this).Scrobble(null);
+ }
+ PreferencesUtility pref = PreferencesUtility.getInstance(this);
+ mShowAlbumArtOnLockscreen = pref.getSetAlbumartLockscreen();
+ mActivateXTrackSelector = pref.getXPosedTrackselectorEnabled();
+ }
+
+ @SuppressWarnings("deprecation")
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ private void setUpRemoteControlClient() {
+ //Legacy for ICS
+ if (mRemoteControlClient == null) {
+ Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ mediaButtonIntent.setComponent(mMediaButtonReceiverComponent);
+ PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
+
+ // create and register the remote control client
+ mRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
+ mAudioManager.registerRemoteControlClient(mRemoteControlClient);
+ }
+
+ mRemoteControlClient.setTransportControlFlags(
+ RemoteControlClient.FLAG_KEY_MEDIA_PLAY |
+ RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
+ RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS |
+ RemoteControlClient.FLAG_KEY_MEDIA_NEXT |
+ RemoteControlClient.FLAG_KEY_MEDIA_STOP);
}
private void setUpMediaSession() {
@@ -384,13 +430,18 @@ public void onStop() {
releaseServiceUiAndStop();
}
});
- mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
+ mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
+ | MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
}
@Override
public void onDestroy() {
if (D) Log.d(TAG, "Destroying service");
super.onDestroy();
+ //Try to push LastFMCache
+ if (LastfmUserSession.getSession(this).isLogedin()) {
+ LastFmClient.getInstance(this).Scrobble(null);
+ }
// Remove any sound effects
final Intent audioEffectsIntent = new Intent(
AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
@@ -454,9 +505,11 @@ public int onStartCommand(final Intent intent, final int flags, final int startI
}
void scrobble() {
- if (LastfmUserSession.getSession(this) != null) {
+ if (LastfmUserSession.getSession(this).isLogedin()) {
Log.d("Scrobble", "to LastFM");
- LastFmClient.getInstance(this).Scrobble(new ScrobbleQuery(getArtistName(), getTrackName(), (System.currentTimeMillis() - duration()) / 1000));
+ String trackname = getTrackName();
+ if (trackname != null)
+ LastFmClient.getInstance(this).Scrobble(new ScrobbleQuery(getArtistName(), trackname, System.currentTimeMillis() / 1000));
}
}
@@ -516,9 +569,30 @@ private void handleCommandIntent(Intent intent) {
cycleRepeat();
} else if (SHUFFLE_ACTION.equals(action)) {
cycleShuffle();
+ } else if (UPDATE_PREFERENCES.equals(action)) {
+ onPreferencesUpdate(intent.getExtras());
+ }
+ else if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) {
+ if (PreferencesUtility.getInstance(getApplicationContext()).pauseEnabledOnDetach()) {
+ pause();
+ }
}
}
+ private void onPreferencesUpdate(Bundle extras) {
+ mShowAlbumArtOnLockscreen = extras.getBoolean("lockscreen", mShowAlbumArtOnLockscreen);
+ mActivateXTrackSelector = extras.getBoolean("xtrack",mActivateXTrackSelector);
+ LastfmUserSession session = LastfmUserSession.getSession(this);
+ session.mToken = extras.getString("lf_token", session.mToken);
+ session.mUsername = extras.getString("lf_user", session.mUsername);
+ if ("logout".equals(session.mToken)) {
+ session.mToken = null;
+ session.mUsername = null;
+ }
+ notifyChange(META_CHANGED);
+
+ }
+
private void updateNotification() {
final int newNotifyMode;
if (isPlaying()) {
@@ -634,6 +708,12 @@ private void cancelShutdown() {
private void stop(final boolean goToIdle) {
if (D) Log.d(TAG, "Stopping playback, goToIdle = " + goToIdle);
+ long duration = this.duration();
+ long position = this.position();
+ if (duration > 30000 && (position >= duration / 2) || position > 240000) {
+ scrobble();
+ }
+
if (mPlayer.isInitialized()) {
mPlayer.stop();
}
@@ -1028,6 +1108,8 @@ private void notifyChange(final String what) {
// Update the lockscreen controls
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
updateMediaSession(what);
+ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ updateRemoteControlClient(what);
if (what.equals(POSITION_CHANGED)) {
return;
@@ -1037,6 +1119,7 @@ private void notifyChange(final String what) {
intent.putExtra("id", getAudioId());
intent.putExtra("artist", getArtistName());
intent.putExtra("album", getAlbumName());
+ intent.putExtra("albumid", getAlbumId());
intent.putExtra("track", getTrackName());
intent.putExtra("playing", isPlaying());
@@ -1072,6 +1155,42 @@ && getShuffleMode() != SHUFFLE_NONE) {
}
+ @SuppressWarnings("deprecation")
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ private void updateRemoteControlClient(final String what) {
+ //Legacy for ICS
+ if (mRemoteControlClient != null) {
+ int playState = mIsSupposedToBePlaying
+ ? RemoteControlClient.PLAYSTATE_PLAYING
+ : RemoteControlClient.PLAYSTATE_PAUSED;
+ if (what.equals(META_CHANGED) || what.equals(QUEUE_CHANGED)) {
+ Bitmap albumArt = null;
+ if (mShowAlbumArtOnLockscreen) {
+ albumArt = ImageLoader.getInstance().loadImageSync(TimberUtils.getAlbumArtUri(getAlbumId()).toString());
+ if (albumArt != null) {
+
+ Bitmap.Config config = albumArt.getConfig();
+ if (config == null) {
+ config = Bitmap.Config.ARGB_8888;
+ }
+ albumArt = albumArt.copy(config, false);
+ }
+ }
+
+ RemoteControlClient.MetadataEditor editor = mRemoteControlClient.editMetadata(true);
+ editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, getAlbumName());
+ editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, getArtistName());
+ editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, getTrackName());
+ editor.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, duration());
+ editor.putBitmap(MediaMetadataEditor.BITMAP_KEY_ARTWORK, albumArt);
+ editor.apply();
+
+ }
+ mRemoteControlClient.setPlaybackState(playState);
+ }
+ }
+
+
private void updateMediaSession(final String what) {
int playState = mIsSupposedToBePlaying
? PlaybackStateCompat.STATE_PLAYING
@@ -1086,14 +1205,17 @@ private void updateMediaSession(final String what) {
.build());
}
} else if (what.equals(META_CHANGED) || what.equals(QUEUE_CHANGED)) {
- Bitmap albumArt = ImageLoader.getInstance().loadImageSync(TimberUtils.getAlbumArtUri(getAlbumId()).toString());
- if (albumArt != null) {
-
- Bitmap.Config config = albumArt.getConfig();
- if (config == null) {
- config = Bitmap.Config.ARGB_8888;
+ Bitmap albumArt = null;
+ if (mShowAlbumArtOnLockscreen) {
+ albumArt = ImageLoader.getInstance().loadImageSync(TimberUtils.getAlbumArtUri(getAlbumId()).toString());
+ if (albumArt != null) {
+
+ Bitmap.Config config = albumArt.getConfig();
+ if (config == null) {
+ config = Bitmap.Config.ARGB_8888;
+ }
+ albumArt = albumArt.copy(config, false);
}
- albumArt = albumArt.copy(config, false);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mSession.setMetadata(new MediaMetadataCompat.Builder()
@@ -1105,8 +1227,7 @@ private void updateMediaSession(final String what) {
.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, getQueuePosition() + 1)
.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, getQueue().length)
.putString(MediaMetadataCompat.METADATA_KEY_GENRE, getGenreName())
- .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART,
- mShowAlbumArtOnLockscreen ? albumArt : null)
+ .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt)
.build());
mSession.setPlaybackState(new PlaybackStateCompat.Builder()
@@ -1118,6 +1239,16 @@ private void updateMediaSession(final String what) {
}
}
+ private void createNotificationChannel() {
+ if (TimberUtils.isOreo()) {
+ CharSequence name = "Timber";
+ int importance = NotificationManager.IMPORTANCE_LOW;
+ NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
+ manager.createNotificationChannel(mChannel);
+ }
+ }
+
private Notification buildNotification() {
final String albumName = getAlbumName();
final String artistName = getArtistName();
@@ -1141,7 +1272,7 @@ private Notification buildNotification() {
mNotificationPostTime = System.currentTimeMillis();
}
- android.support.v4.app.NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
+ androidx.core.app.NotificationCompat.Builder builder = new androidx.core.app.NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(artwork)
.setContentIntent(clickIntent)
@@ -1160,6 +1291,7 @@ private Notification buildNotification() {
if (TimberUtils.isJellyBeanMR1()) {
builder.setShowWhen(false);
}
+
if (TimberUtils.isLollipop()) {
builder.setVisibility(Notification.VISIBILITY_PUBLIC);
NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle()
@@ -1167,11 +1299,17 @@ private Notification buildNotification() {
.setShowActionsInCompactView(0, 1, 2, 3);
builder.setStyle(style);
}
- if (artwork != null && TimberUtils.isLollipop())
+ if (artwork != null && TimberUtils.isLollipop()) {
builder.setColor(Palette.from(artwork).generate().getVibrantColor(Color.parseColor("#403f4d")));
+ }
+
+ if (TimberUtils.isOreo()) {
+ builder.setColorized(true);
+ }
+
Notification n = builder.build();
- if (PreferencesUtility.getInstance(this).getXPosedTrackselectorEnabled()) {
+ if (mActivateXTrackSelector) {
addXTrackSelector(n);
}
@@ -1193,8 +1331,7 @@ private void addXTrackSelector(Notification n) {
ArrayList list = new ArrayList<>();
do {
TrackItem t = new TrackItem()
- .setArt(ImageLoader.getInstance()
- .loadImageSync(TimberUtils.getAlbumArtUri(c.getLong(c.getColumnIndexOrThrow(AudioColumns.ALBUM_ID))).toString()))
+ .setArt(TimberUtils.getAlbumArtUri(c.getLong(c.getColumnIndexOrThrow(AudioColumns.ALBUM_ID))))
.setTitle(c.getString(c.getColumnIndexOrThrow(AudioColumns.TITLE)))
.setArtist(c.getString(c.getColumnIndexOrThrow(AudioColumns.ARTIST)))
.setDuration(TimberUtils.makeShortTimeString(this, c.getInt(c.getColumnIndexOrThrow(AudioColumns.DURATION)) / 1000));
@@ -1964,8 +2101,6 @@ public void setAndRecordPlayPos(int nextPos) {
public void prev(boolean forcePrevious) {
synchronized (this) {
-
-
boolean goPrevious = getRepeatMode() != REPEAT_CURRENT &&
(position() < REWIND_INSTEAD_PREVIOUS_THRESHOLD || forcePrevious);
@@ -2100,11 +2235,6 @@ public void playlistChanged() {
notifyChange(PLAYLIST_CHANGED);
}
- public void setLockscreenAlbumArt(boolean enabled) {
- mShowAlbumArtOnLockscreen = enabled;
- notifyChange(META_CHANGED);
- }
-
public interface TrackErrorExtra {
String TRACK_NAME = "trackname";
@@ -2172,7 +2302,6 @@ public void handleMessage(final Message msg) {
service.updateNotification();
break;
case TRACK_ENDED:
- mService.get().scrobble();
if (service.mRepeatMode == REPEAT_CURRENT) {
service.seek(0);
service.play();
@@ -2704,12 +2833,6 @@ public int getAudioSessionId() throws RemoteException {
return mService.get().getAudioSessionId();
}
-
- @Override
- public void setLockscreenAlbumArt(boolean enabled) {
- mService.get().setLockscreenAlbumArt(enabled);
- }
-
}
private class MediaStoreObserver extends ContentObserver implements Runnable {
@@ -2737,5 +2860,4 @@ public void run() {
refresh();
}
}
-
}
diff --git a/app/src/main/java/com/naman14/timber/TimberApp.java b/app/src/main/java/com/naman14/timber/TimberApp.java
index 5016e9c9f..a0151c241 100644
--- a/app/src/main/java/com/naman14/timber/TimberApp.java
+++ b/app/src/main/java/com/naman14/timber/TimberApp.java
@@ -14,17 +14,22 @@
package com.naman14.timber;
-import android.app.Application;
+import androidx.multidex.MultiDexApplication;
import com.afollestad.appthemeengine.ATE;
import com.naman14.timber.permissions.Nammu;
+import com.naman14.timber.utils.PreferencesUtility;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
+import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.utils.L;
-public class TimberApp extends Application {
+import java.io.IOException;
+import java.io.InputStream;
+public class TimberApp extends MultiDexApplication {
+
private static TimberApp mInstance;
public static synchronized TimberApp getInstance() {
@@ -36,7 +41,17 @@ public void onCreate() {
super.onCreate();
mInstance = this;
- ImageLoaderConfiguration localImageLoaderConfiguration = new ImageLoaderConfiguration.Builder(this).build();
+ ImageLoaderConfiguration localImageLoaderConfiguration = new ImageLoaderConfiguration.Builder(this).imageDownloader(new BaseImageDownloader(this) {
+ PreferencesUtility prefs = PreferencesUtility.getInstance(TimberApp.this);
+
+ @Override
+ protected InputStream getStreamFromNetwork(String imageUri, Object extra) throws IOException {
+ if (prefs.loadArtistAndAlbumImages())
+ return super.getStreamFromNetwork(imageUri, extra);
+ throw new IOException();
+ }
+ }).build();
+
ImageLoader.getInstance().init(localImageLoaderConfiguration);
L.writeLogs(false);
L.disableLogging();
diff --git a/app/src/main/java/com/naman14/timber/WearBrowserService.java b/app/src/main/java/com/naman14/timber/WearBrowserService.java
index db31e1523..949d703a9 100644
--- a/app/src/main/java/com/naman14/timber/WearBrowserService.java
+++ b/app/src/main/java/com/naman14/timber/WearBrowserService.java
@@ -24,7 +24,7 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.service.media.MediaBrowserService;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import com.naman14.timber.dataloaders.AlbumLoader;
import com.naman14.timber.dataloaders.AlbumSongLoader;
diff --git a/app/src/main/java/com/naman14/timber/activities/BaseActivity.java b/app/src/main/java/com/naman14/timber/activities/BaseActivity.java
index c113c164e..d74727e70 100644
--- a/app/src/main/java/com/naman14/timber/activities/BaseActivity.java
+++ b/app/src/main/java/com/naman14/timber/activities/BaseActivity.java
@@ -22,13 +22,12 @@
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.media.AudioManager;
-import android.media.session.MediaSessionManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
-import android.support.annotation.Nullable;
-import android.support.v4.app.FragmentManager;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -36,10 +35,12 @@
import com.afollestad.appthemeengine.ATE;
import com.afollestad.appthemeengine.ATEActivity;
+
import com.naman14.timber.ITimberService;
import com.naman14.timber.MusicPlayer;
import com.naman14.timber.MusicService;
import com.naman14.timber.R;
+import com.naman14.timber.cast.WebServer;
import com.naman14.timber.listeners.MusicStateListener;
import com.naman14.timber.slidinguppanel.SlidingUpPanelLayout;
import com.naman14.timber.subfragments.QuickControlsFragment;
@@ -47,6 +48,7 @@
import com.naman14.timber.utils.NavigationUtils;
import com.naman14.timber.utils.TimberUtils;
+import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -58,6 +60,10 @@ public class BaseActivity extends ATEActivity implements ServiceConnection, Musi
private MusicPlayer.ServiceToken mToken;
private PlaybackStatus mPlaybackStatus;
+ private WebServer castServer;
+
+
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -92,24 +98,31 @@ protected void onStart() {
@Override
protected void onStop() {
super.onStop();
-
-
}
@Override
public void onResume() {
- super.onResume();
+ //For Android 8.0+: service may get destroyed if in background too long
+ if(mService == null){
+ mToken = MusicPlayer.bindToService(this, this);
+ }
onMetaChanged();
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
}
@Override
public void onServiceConnected(final ComponentName name, final IBinder service) {
mService = ITimberService.Stub.asInterface(service);
-
onMetaChanged();
}
+
@Override
public void onServiceDisconnected(final ComponentName name) {
mService = null;
@@ -180,6 +193,10 @@ public void removeMusicStateListenerListener(final MusicStateListener status) {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
+
+ getMenuInflater().inflate(R.menu.menu_cast, menu);
+
+
if (!TimberUtils.hasEffectsPanel(BaseActivity.this)) {
menu.removeItem(R.id.action_equalizer);
}
@@ -229,19 +246,22 @@ public void setPanelSlideListeners(SlidingUpPanelLayout panelLayout) {
@Override
public void onPanelSlide(View panel, float slideOffset) {
View nowPlayingCard = QuickControlsFragment.topContainer;
- nowPlayingCard.setAlpha(1 - slideOffset);
+ if (nowPlayingCard != null)
+ nowPlayingCard.setAlpha(1 - slideOffset);
}
@Override
public void onPanelCollapsed(View panel) {
View nowPlayingCard = QuickControlsFragment.topContainer;
- nowPlayingCard.setAlpha(1);
+ if (nowPlayingCard != null)
+ nowPlayingCard.setAlpha(1);
}
@Override
public void onPanelExpanded(View panel) {
View nowPlayingCard = QuickControlsFragment.topContainer;
- nowPlayingCard.setAlpha(0);
+ if (nowPlayingCard != null)
+ nowPlayingCard.setAlpha(0);
}
@Override
@@ -300,12 +320,6 @@ protected String doInBackground(String... params) {
@Override
protected void onPostExecute(String result) {
-// QuickControlsFragment.topContainer.setOnClickListener(new View.OnClickListener() {
-// @Override
-// public void onClick(View v) {
-// NavigationUtils.navigateToNowplaying(BaseActivity.this, false);
-// }
-// });
}
@Override
@@ -313,4 +327,26 @@ protected void onPreExecute() {
}
}
+ public void showCastMiniController() {
+ //implement by overriding in activities
+ }
+
+ public void hideCastMiniController() {
+ //implement by overriding in activities
+ }
+
+ private void startCastServer() {
+ castServer = new WebServer(this);
+ try {
+ castServer.start();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void stopCastServer() {
+ if (castServer != null) {
+ castServer.stop();
+ }
+ }
}
diff --git a/app/src/main/java/com/naman14/timber/activities/BaseThemedActivity.java b/app/src/main/java/com/naman14/timber/activities/BaseThemedActivity.java
index f46d09c9f..9454bd11f 100644
--- a/app/src/main/java/com/naman14/timber/activities/BaseThemedActivity.java
+++ b/app/src/main/java/com/naman14/timber/activities/BaseThemedActivity.java
@@ -2,7 +2,7 @@
import android.media.AudioManager;
import android.os.Bundle;
-import android.support.annotation.Nullable;
+import androidx.annotation.Nullable;
import com.afollestad.appthemeengine.ATEActivity;
import com.naman14.timber.utils.Helpers;
diff --git a/app/src/main/java/com/naman14/timber/activities/DonateActivity.java b/app/src/main/java/com/naman14/timber/activities/DonateActivity.java
index 737c0f411..997ab6d3b 100644
--- a/app/src/main/java/com/naman14/timber/activities/DonateActivity.java
+++ b/app/src/main/java/com/naman14/timber/activities/DonateActivity.java
@@ -3,7 +3,7 @@
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@@ -16,6 +16,7 @@
import com.anjlab.android.iab.v3.SkuDetails;
import com.anjlab.android.iab.v3.TransactionDetails;
import com.naman14.timber.R;
+import com.naman14.timber.utils.PreferencesUtility;
import java.util.ArrayList;
import java.util.Collections;
@@ -42,6 +43,8 @@ public class DonateActivity extends BaseThemedActivity implements BillingProcess
private ProgressBar progressBar;
private TextView status;
+ private String action = "support";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -51,11 +54,12 @@ protected void onCreate(Bundle savedInstanceState) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setTitle("Donate");
+ getSupportActionBar().setTitle("Support development");
+ action = getIntent().getAction();
+
productListView = (LinearLayout) findViewById(R.id.product_list);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
status = (TextView) findViewById(R.id.donation_status);
-
bp = new BillingProcessor(this, "PLAY_LICENSE_KEY", this);
}
@@ -64,7 +68,8 @@ protected void onCreate(Bundle savedInstanceState) {
public void onBillingInitialized() {
readyToPurchase = true;
checkStatus();
- getProducts();
+ if (!(action != null && action.equals("restore")))
+ getProducts();
}
@Override
@@ -73,7 +78,7 @@ public void onProductPurchased(String productId, TransactionDetails details) {
runOnUiThread(new Runnable() {
@Override
public void run() {
- Toast.makeText(DonateActivity.this, "Thanks for your donation!", Toast.LENGTH_SHORT).show();
+ Toast.makeText(DonateActivity.this, "Thanks for your support!", Toast.LENGTH_SHORT).show();
}
});
}
@@ -119,7 +124,19 @@ protected Boolean doInBackground(Void... voids) {
protected void onPostExecute(Boolean b) {
super.onPostExecute(b);
if (b) {
- status.setText("Thanks for your donation!");
+ PreferencesUtility.getInstance(DonateActivity.this).setFullUnlocked(true);
+ status.setText("Thanks for your support!");
+ if (action!=null && action.equals("restore")) {
+ status.setText("Your purchases has been restored. Thanks for your support");
+ progressBar.setVisibility(View.GONE);
+ }
+ if (getSupportActionBar() != null)
+ getSupportActionBar().setTitle("Support development");
+ } else {
+ if (action!=null && action.equals("restore")) {
+ status.setText("No previous purchase found");
+ getProducts();
+ }
}
}
}.execute();
diff --git a/app/src/main/java/com/naman14/timber/activities/MainActivity.java b/app/src/main/java/com/naman14/timber/activities/MainActivity.java
index 94ee213d0..463f5deb1 100644
--- a/app/src/main/java/com/naman14/timber/activities/MainActivity.java
+++ b/app/src/main/java/com/naman14/timber/activities/MainActivity.java
@@ -16,25 +16,28 @@
import android.Manifest;
import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
-import android.support.design.widget.NavigationView;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
+import com.google.android.material.navigation.NavigationView;
+import com.google.android.material.snackbar.Snackbar;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.core.view.GravityCompat;
+import androidx.drawerlayout.widget.DrawerLayout;
+import android.view.Gravity;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.afollestad.appthemeengine.customizers.ATEActivityThemeCustomizer;
import com.anjlab.android.iab.v3.BillingProcessor;
+
import com.naman14.timber.MusicPlayer;
import com.naman14.timber.R;
import com.naman14.timber.fragments.AlbumDetailFragment;
@@ -46,6 +49,7 @@
import com.naman14.timber.permissions.Nammu;
import com.naman14.timber.permissions.PermissionCallback;
import com.naman14.timber.slidinguppanel.SlidingUpPanelLayout;
+import com.naman14.timber.subfragments.LyricsFragment;
import com.naman14.timber.utils.Constants;
import com.naman14.timber.utils.Helpers;
import com.naman14.timber.utils.NavigationUtils;
@@ -58,17 +62,18 @@
public class MainActivity extends BaseActivity implements ATEActivityThemeCustomizer {
+ private SlidingUpPanelLayout panelLayout;
+ private NavigationView navigationView;
+ private TextView songtitle, songartist;
+ private ImageView albumart;
+ private String action;
+ private Map navigationMap = new HashMap();
+ private Handler navDrawerRunnable = new Handler();
+ private Runnable runnable;
+ private DrawerLayout mDrawerLayout;
+ private boolean isDarkTheme;
- private static MainActivity sMainActivity;
- SlidingUpPanelLayout panelLayout;
- NavigationView navigationView;
- TextView songtitle, songartist;
- ImageView albumart;
- String action;
- Map navigationMap = new HashMap();
- Handler navDrawerRunnable = new Handler();
- Runnable runnable;
- Runnable navigateLibrary = new Runnable() {
+ private Runnable navigateLibrary = new Runnable() {
public void run() {
navigationView.getMenu().findItem(R.id.nav_library).setChecked(true);
Fragment fragment = new MainFragment();
@@ -77,24 +82,8 @@ public void run() {
}
};
- Runnable navigateNowplaying = new Runnable() {
- public void run() {
- navigateLibrary.run();
- startActivity(new Intent(MainActivity.this, NowPlayingActivity.class));
- }
- };
- final PermissionCallback permissionReadstorageCallback = new PermissionCallback() {
- @Override
- public void permissionGranted() {
- loadEverything();
- }
- @Override
- public void permissionRefused() {
- finish();
- }
- };
- Runnable navigatePlaylist = new Runnable() {
+ private Runnable navigatePlaylist = new Runnable() {
public void run() {
navigationView.getMenu().findItem(R.id.nav_playlists).setChecked(true);
Fragment fragment = new PlaylistFragment();
@@ -104,7 +93,8 @@ public void run() {
}
};
- Runnable navigateFolder = new Runnable() {
+
+ private Runnable navigateFolder = new Runnable() {
public void run() {
navigationView.getMenu().findItem(R.id.nav_folders).setChecked(true);
Fragment fragment = new FoldersFragment();
@@ -114,7 +104,8 @@ public void run() {
}
};
- Runnable navigateQueue = new Runnable() {
+
+ private Runnable navigateQueue = new Runnable() {
public void run() {
navigationView.getMenu().findItem(R.id.nav_queue).setChecked(true);
Fragment fragment = new QueueFragment();
@@ -124,7 +115,8 @@ public void run() {
}
};
- Runnable navigateAlbum = new Runnable() {
+
+ private Runnable navigateAlbum = new Runnable() {
public void run() {
long albumID = getIntent().getExtras().getLong(Constants.ALBUM_ID);
Fragment fragment = AlbumDetailFragment.newInstance(albumID, false, null);
@@ -133,7 +125,8 @@ public void run() {
.replace(R.id.fragment_container, fragment).commit();
}
};
- Runnable navigateArtist = new Runnable() {
+
+ private Runnable navigateArtist = new Runnable() {
public void run() {
long artistID = getIntent().getExtras().getLong(Constants.ARTIST_ID);
Fragment fragment = ArtistDetailFragment.newInstance(artistID, false, null);
@@ -142,17 +135,39 @@ public void run() {
.replace(R.id.fragment_container, fragment).commit();
}
};
- private DrawerLayout mDrawerLayout;
- private boolean isDarkTheme;
- public static MainActivity getInstance() {
- return sMainActivity;
- }
+ private Runnable navigateLyrics = new Runnable() {
+ public void run() {
+ Fragment fragment = new LyricsFragment();
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ fragmentManager.beginTransaction()
+ .replace(R.id.fragment_container, fragment).commit();
+ }
+ };
+
+ private Runnable navigateNowplaying = new Runnable() {
+ public void run() {
+ navigateLibrary.run();
+ startActivity(new Intent(MainActivity.this, NowPlayingActivity.class));
+ }
+ };
+
+ private final PermissionCallback permissionReadstorageCallback = new PermissionCallback() {
+ @Override
+ public void permissionGranted() {
+ loadEverything();
+ }
+
+ @Override
+ public void permissionRefused() {
+ finish();
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
- sMainActivity = this;
action = getIntent().getAction();
isDarkTheme = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("dark_theme", false);
@@ -166,6 +181,7 @@ public void onCreate(Bundle savedInstanceState) {
navigationMap.put(Constants.NAVIGATE_NOWPLAYING, navigateNowplaying);
navigationMap.put(Constants.NAVIGATE_ALBUM, navigateAlbum);
navigationMap.put(Constants.NAVIGATE_ARTIST, navigateArtist);
+ navigationMap.put(Constants.NAVIGATE_LYRICS, navigateLyrics);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
panelLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
@@ -190,6 +206,7 @@ public void run() {
if (TimberUtils.isMarshmallow()) {
checkPermissionAndThenLoad();
+ //checkWritePermissions();
} else {
loadEverything();
}
@@ -209,6 +226,11 @@ public void run() {
}, 350);
}
+ if (!panelLayout.isPanelHidden() && MusicPlayer.getTrackName() == null ) {
+ panelLayout.hidePanel();
+ }
+
+
}
private void loadEverything() {
@@ -224,7 +246,7 @@ private void loadEverything() {
private void checkPermissionAndThenLoad() {
//check for permission
- if (Nammu.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
+ if (Nammu.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) && Nammu.checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
loadEverything();
} else {
if (Nammu.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
@@ -233,18 +255,20 @@ private void checkPermissionAndThenLoad() {
.setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View view) {
- Nammu.askForPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE, permissionReadstorageCallback);
+ Nammu.askForPermission(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, permissionReadstorageCallback);
}
}).show();
} else {
- Nammu.askForPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE, permissionReadstorageCallback);
+ Nammu.askForPermission(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, permissionReadstorageCallback);
}
}
}
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
+
return true;
}
@@ -297,7 +321,6 @@ private void setupNavigationIcons(NavigationView navigationView) {
navigationView.getMenu().findItem(R.id.nav_folders).setIcon(R.drawable.ic_folder_open_black_24dp);
navigationView.getMenu().findItem(R.id.nav_nowplaying).setIcon(R.drawable.bookmark_music);
navigationView.getMenu().findItem(R.id.nav_settings).setIcon(R.drawable.settings);
- navigationView.getMenu().findItem(R.id.nav_help).setIcon(R.drawable.help_circle);
navigationView.getMenu().findItem(R.id.nav_about).setIcon(R.drawable.information);
navigationView.getMenu().findItem(R.id.nav_donate).setIcon(R.drawable.payment_black);
} else {
@@ -307,7 +330,6 @@ private void setupNavigationIcons(NavigationView navigationView) {
navigationView.getMenu().findItem(R.id.nav_folders).setIcon(R.drawable.ic_folder_open_white_24dp);
navigationView.getMenu().findItem(R.id.nav_nowplaying).setIcon(R.drawable.bookmark_music_white);
navigationView.getMenu().findItem(R.id.nav_settings).setIcon(R.drawable.settings_white);
- navigationView.getMenu().findItem(R.id.nav_help).setIcon(R.drawable.help_circle_white);
navigationView.getMenu().findItem(R.id.nav_about).setIcon(R.drawable.information_white);
navigationView.getMenu().findItem(R.id.nav_donate).setIcon(R.drawable.payment_white);
}
@@ -348,12 +370,6 @@ private void updatePosition(final MenuItem menuItem) {
case R.id.nav_settings:
NavigationUtils.navigateToSettings(MainActivity.this);
break;
- case R.id.nav_help:
- Intent intent = new Intent(Intent.ACTION_VIEW);
- Uri data = Uri.parse("mailto:namandwivedi14@gmail.com");
- intent.setData(data);
- startActivity(intent);
- break;
case R.id.nav_about:
mDrawerLayout.closeDrawers();
Handler handler = new Handler();
@@ -402,12 +418,10 @@ public void setDetailsToHeader() {
public void onMetaChanged() {
super.onMetaChanged();
setDetailsToHeader();
- }
- @Override
- public void onResume() {
- super.onResume();
- sMainActivity = this;
+ if (panelLayout.isPanelHidden() && MusicPlayer.getTrackName() != null) {
+ panelLayout.showPanel();
+ }
}
@Override
@@ -442,6 +456,23 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
getSupportFragmentManager().findFragmentById(R.id.fragment_container).onActivityResult(requestCode, resultCode, data);
}
+
+
+ @Override
+ public void showCastMiniController() {
+ findViewById(R.id.castMiniController).setVisibility(View.VISIBLE);
+ findViewById(R.id.quickcontrols_container).setVisibility(View.GONE);
+ panelLayout.hidePanel();
+ }
+
+ @Override
+ public void hideCastMiniController() {
+
+ findViewById(R.id.castMiniController).setVisibility(View.GONE);
+ findViewById(R.id.quickcontrols_container).setVisibility(View.VISIBLE);
+
+ panelLayout.showPanel();
+ }
}
diff --git a/app/src/main/java/com/naman14/timber/activities/NowPlayingActivity.java b/app/src/main/java/com/naman14/timber/activities/NowPlayingActivity.java
index 89a6abb32..46cd4bf2c 100644
--- a/app/src/main/java/com/naman14/timber/activities/NowPlayingActivity.java
+++ b/app/src/main/java/com/naman14/timber/activities/NowPlayingActivity.java
@@ -5,12 +5,13 @@
import android.graphics.Color;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.annotation.StyleRes;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
+import androidx.annotation.StyleRes;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
import com.afollestad.appthemeengine.Config;
import com.afollestad.appthemeengine.customizers.ATEActivityThemeCustomizer;
+import com.afollestad.appthemeengine.customizers.ATEStatusBarCustomizer;
import com.afollestad.appthemeengine.customizers.ATEToolbarCustomizer;
import com.naman14.timber.R;
import com.naman14.timber.utils.Constants;
@@ -20,7 +21,7 @@
/**
* Created by naman on 01/01/16.
*/
-public class NowPlayingActivity extends BaseActivity implements ATEActivityThemeCustomizer, ATEToolbarCustomizer {
+public class NowPlayingActivity extends BaseActivity implements ATEActivityThemeCustomizer, ATEToolbarCustomizer, ATEStatusBarCustomizer {
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -48,11 +49,21 @@ public int getLightToolbarMode() {
return Config.LIGHT_TOOLBAR_AUTO;
}
+ @Override
+ public int getLightStatusBarMode() {
+ return Config.LIGHT_STATUS_BAR_OFF;
+ }
+
@Override
public int getToolbarColor() {
return Color.TRANSPARENT;
}
+ @Override
+ public int getStatusBarColor() {
+ return Color.TRANSPARENT;
+ }
+
@Override
public void onResume() {
super.onResume();
diff --git a/app/src/main/java/com/naman14/timber/activities/PlaylistDetailActivity.java b/app/src/main/java/com/naman14/timber/activities/PlaylistDetailActivity.java
index d94c822d0..a02ea6f02 100644
--- a/app/src/main/java/com/naman14/timber/activities/PlaylistDetailActivity.java
+++ b/app/src/main/java/com/naman14/timber/activities/PlaylistDetailActivity.java
@@ -23,12 +23,12 @@
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
-import android.support.annotation.NonNull;
-import android.support.annotation.StyleRes;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.NonNull;
+import androidx.annotation.StyleRes;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.Toolbar;
import android.transition.Transition;
import android.util.Log;
import android.view.Menu;
@@ -52,7 +52,6 @@
import com.naman14.timber.listeners.SimplelTransitionListener;
import com.naman14.timber.models.Song;
import com.naman14.timber.utils.Constants;
-import com.naman14.timber.utils.PreferencesUtility;
import com.naman14.timber.utils.TimberUtils;
import com.naman14.timber.widgets.DividerItemDecoration;
import com.naman14.timber.widgets.DragSortRecycler;
@@ -64,41 +63,43 @@
public class PlaylistDetailActivity extends BaseActivity implements ATEActivityThemeCustomizer, ATEToolbarCustomizer {
- String action;
- long playlistID;
- HashMap playlistsMap = new HashMap<>();
- Runnable playlistLastAdded = new Runnable() {
+ private String action;
+ private long playlistID;
+ private HashMap playlistsMap = new HashMap<>();
+
+ private AppCompatActivity mContext = PlaylistDetailActivity.this;
+ private SongsListAdapter mAdapter;
+ private RecyclerView recyclerView;
+ private ImageView blurFrame;
+ private TextView playlistname;
+ private View foreground;
+ private boolean animate;
+
+ private Runnable playlistLastAdded = new Runnable() {
public void run() {
new loadLastAdded().execute("");
}
};
- Runnable playlistRecents = new Runnable() {
+ private Runnable playlistRecents = new Runnable() {
@Override
public void run() {
new loadRecentlyPlayed().execute("");
}
};
- Runnable playlistToptracks = new Runnable() {
+ private Runnable playlistToptracks = new Runnable() {
@Override
public void run() {
new loadTopTracks().execute("");
}
};
- Runnable playlistUsercreated = new Runnable() {
+ private Runnable playlistUsercreated = new Runnable() {
@Override
public void run() {
new loadUserCreatedPlaylist().execute("");
}
};
- private AppCompatActivity mContext = PlaylistDetailActivity.this;
- private SongsListAdapter mAdapter;
- private RecyclerView recyclerView;
- private ImageView blurFrame;
- private TextView playlistname;
- private View foreground;
- private boolean animate;
@TargetApi(21)
@Override
@@ -130,12 +131,22 @@ public void onCreate(Bundle savedInstanceState) {
setAlbumart();
animate = getIntent().getBooleanExtra(Constants.ACTIVITY_TRANSITION, false);
- if (animate && TimberUtils.isLollipop() && PreferencesUtility.getInstance(this).getAnimations()) {
- getWindow().getEnterTransition().addListener(new EnterTransitionListener());
+ if (animate && TimberUtils.isLollipop()) {
+ if(savedInstanceState != null && savedInstanceState.containsKey("ROTATION_RECREATION")){
+ setUpSongs();
+ }
+ else{
+ getWindow().getEnterTransition().addListener(new EnterTransitionListener());
+ }
} else {
setUpSongs();
}
+ }
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString("ROTATION_RECREATION", "Rotacion");
}
private void setAlbumart() {
@@ -184,7 +195,7 @@ private void loadBitmap(String uri) {
private void setRecyclerViewAapter() {
recyclerView.setAdapter(mAdapter);
- if (animate && TimberUtils.isLollipop() && PreferencesUtility.getInstance(mContext).getAnimations()) {
+ if (animate && TimberUtils.isLollipop()) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
@@ -378,6 +389,13 @@ private void clearAutoPlaylists() {
finish();
}
+ @Override
+ public void onMetaChanged() {
+ super.onMetaChanged();
+ if (mAdapter != null)
+ mAdapter.notifyDataSetChanged();
+ }
+
@Override
public int getToolbarColor() {
return Color.TRANSPARENT;
diff --git a/app/src/main/java/com/naman14/timber/activities/SearchActivity.java b/app/src/main/java/com/naman14/timber/activities/SearchActivity.java
index d5c3652f4..2c114bc6e 100644
--- a/app/src/main/java/com/naman14/timber/activities/SearchActivity.java
+++ b/app/src/main/java/com/naman14/timber/activities/SearchActivity.java
@@ -17,12 +17,13 @@
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.view.MenuItemCompat;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.SearchView;
-import android.support.v7.widget.Toolbar;
+import androidx.annotation.Nullable;
+import androidx.core.view.MenuItemCompat;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.SearchView;
+import androidx.appcompat.widget.Toolbar;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
@@ -45,7 +46,7 @@
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
-public class SearchActivity extends BaseThemedActivity implements SearchView.OnQueryTextListener, View.OnTouchListener {
+public class SearchActivity extends BaseActivity implements SearchView.OnQueryTextListener, View.OnTouchListener {
private final Executor mSearchExecutor = Executors.newSingleThreadExecutor();
@Nullable
@@ -60,6 +61,8 @@ public class SearchActivity extends BaseThemedActivity implements SearchView.OnQ
private List