package com.nf2m.service;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.graphics.Palette;
import android.widget.RemoteViews;
import android.widget.Toast;
import com.nf2m.R;
import com.nf2m.RandomSong;
import com.nf2m.activity.TarMediaPlayerActivity;
import com.nf2m.fragment.BaseFragment;
import com.nf2m.fragment.NowPlayingFragment;
import com.nf2m.model.Songs;
import com.nf2m.preferences.Preferences;
import com.nf2m.provider.PlayerWidgetLargeProvider;
import com.nf2m.provider.PlayerWidgetSmallProvider;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
public class MediaPlayerService extends Service implements MediaPlayer.OnCompletionListener,
AudioManager.OnAudioFocusChangeListener {
public static final int MSG_ADD_CLIENT = 0;
public static final int MSG_REMOVE_CLIENT = 1;
public static final int MSG_PLAY = 2;
public static final int MSG_PAUSE = 3;
private static final int MSG_STOP = 4;
public static final int MSG_SEEK_TO = 5;
public static final int MSG_NEXT = 6;
public static final int MSG_CURRENT_DURATION = 7;
public static final int MSG_REPEAT_STATE = 8;
public static final int MSG_PLAY_STATE = 10;
public static final int MSG_PREVIOUS = 11;
private static final int MSG_FINISH = 12;
private static final int DELAY_MILLIS = 1000;
public static final String DATA_KEY_CURRENT_POS = "current_position";
public static final String DATA_KEY_PLAY_STATE = "data_play_state";
private static final int NOTIFY_ID = 1;
public static final String ACTION_PLAY = "action_play";
private static final String ACTION_PAUSE = "action_pause";
public static final String ACTION_NEXT = "action_next";
public static final String ACTION_PREVIOUS = "action_previous";
public static final String ACTION_TIMER = "action_timer";
public static final String ACTION_UPDATE = "action_update";
public static final String ACTION_SONG_PLAY = "action_song_play";
public static final String ACTION_NWP_UPDATE = "action_nwp_play";
public static final String ACTION_REPEAT = "action_repeat";
public static final String ACTION_SHUFFLE = "action_shuffle";
private static final String ACTION_EXIT = "action_exit";
private static final int KEY_NEXT = 0;
private static final int KEY_PREVIOUS = 1;
private static final String DATA_KEY_NUMBER_OF_PLAY = "data_number_of_play";
private static final int DATA_PLAY_NUMBER = 1;
public static boolean newPlay;
private static ArrayList<Messenger> client;
private Messenger messenger;
private MediaPlayer mediaPlayer;
public static String songPath;
private boolean isPause = true;
public static boolean isPlaying;
@NonNull
private final Handler timerHandler = new Handler();
private static AudioManager audioManager;
private RemoteViews rvNotification;
private Notification notificationBuild;
private String oldSongPath;
private ComponentName playerWidgetSmallProvider;
private AppWidgetManager appWidgetSmallManager;
private CountDownTimer countDownTimer;
private NotificationManager notificationManager;
public static boolean isServiceStart;
private boolean isFocusPause;
private Preferences preferences;
private RemoteViews rvSmallWidget;
private RemoteViews rvLargeWidget;
private ComponentName playerWidgetLargeProvider;
private AppWidgetManager appWidgetLargeManager;
private int defaultVolume;
private boolean isTransientDuck;
private RandomSong randomSong;
@Nullable
public static Cursor songsCursor;
private AsyncTask<Void, Void, Exception> playTask;
private int getSongPos() {
return preferences.getPrefSongPosition();
}
@Nullable
private String getPrefShuffle() {
return preferences.getPrefShuffle();
}
@Nullable
private String getPrefRepeat() {
return preferences.getPrefRepeat();
}
private class ServiceHandler extends Handler {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MSG_ADD_CLIENT:
client.add(msg.replyTo);
break;
case MSG_REMOVE_CLIENT:
client.remove(msg.replyTo);
break;
case MSG_PLAY:
play(NowPlayingFragment.songPath);
updateNotification(NowPlayingFragment.songTitle, NowPlayingFragment.album_art_path);
updateWidget();
break;
case MSG_PAUSE:
pause();
break;
case MSG_STOP:
stop();
break;
case MSG_SEEK_TO:
int progress = NowPlayingFragment.progress;
seekTo(progress);
break;
case MSG_REPEAT_STATE:
String state = NowPlayingFragment.repeat_state;
setSongLooping(state);
break;
}
super.handleMessage(msg);
}
}
private void updateNotification(String songTitle, String albumArtPath) {
setRemoteViews(songTitle, albumArtPath);
notificationBuild.contentView = rvNotification;
notificationManager.notify(NOTIFY_ID, notificationBuild);
}
private void setSongLooping(@NonNull String state) {
if (state.equalsIgnoreCase(NowPlayingFragment.REPEAT_ONE)) {
mediaPlayer.setLooping(true);
} else {
mediaPlayer.setLooping(false);
}
}
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
@Override
public void onCreate() {
super.onCreate();
if (checkStoragePermission()) return;
isServiceStart = true;
initPreferences();
initSongsCursor();
initMessenger();
checkCursorIsEmpty();
}
private boolean checkStoragePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED) {
stopSelf();
return true;
}
}
return false;
}
private void checkCursorIsEmpty() {
if (songsCursor == null || songsCursor.getCount() == 0) {
stopSelf();
} else {
init();
}
}
private void initSongsCursor() {
if (songsCursor == null || songsCursor.isClosed()) {
Songs songs = new Songs(getBaseContext());
String where = preferences.getPrefQueryWhere();
ArrayList<String> selectionArgs = preferences.getPrefQuerySelectionArgs();
String prefQueryUri = preferences.getPrefQueryUri();
if (where == null && selectionArgs == null && prefQueryUri == null) {
songsCursor = songs.getCursor();
} else {
String[] selection = null;
if (selectionArgs != null) {
selection = selectionArgs.toArray(new String[selectionArgs.size()]);
}
songsCursor = songs.initCursor(Uri.parse(prefQueryUri), null, where, selection, songs.getSortOrder());
}
}
}
private void init() {
initReceiver();
initAudioManager();
initMediaPlayer();
initListener();
setSongRepeat();
initAudios();
initSongPath();
showNotification();
initPlayerWidget();
initCountDownTimer();
initNotificationManager();
initRandom();
}
private void initRandom() {
randomSong = RandomSong.newInstance(getApplicationContext());
}
private void initPreferences() {
preferences = Preferences.newInstance(getBaseContext());
}
private void initNotificationManager() {
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
private void initCountDownTimer() {
int timer_length = preferences.getPrefTimer();
if (timer_length > 0) {
setCountDownTimer(timer_length);
}
}
private void setCountDownTimer(int length) {
countDownTimer = new CountDownTimer(length, 1000) {
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
sendMessageToActivity(MSG_FINISH, null, 0);
stopSelf();
}
}.start();
}
private void initSongPath() {
songPath = NowPlayingFragment.songPath;
if (songPath == null) {
if (getSongPos() > songsCursor.getCount() || getSongPos() < 0) {
if (songsCursor.moveToFirst()) {
songPath = getSongPath();
preferences.setPrefSongPos(0);
}
} else {
if (songsCursor.moveToPosition(getSongPos())) {
songPath = getSongPath();
}
}
}
}
private void initPlayerWidget() {
rvSmallWidget.setOnClickPendingIntent(R.id.rlPlayer, getMainPendingIntent());
rvLargeWidget.setOnClickPendingIntent(R.id.rlPlayer, getMainPendingIntent());
playerWidgetSmallProvider = new ComponentName(this, PlayerWidgetSmallProvider.class);
appWidgetSmallManager = AppWidgetManager.getInstance(this);
appWidgetSmallManager.updateAppWidget(playerWidgetSmallProvider, rvSmallWidget);
playerWidgetLargeProvider = new ComponentName(this, PlayerWidgetLargeProvider.class);
appWidgetLargeManager = AppWidgetManager.getInstance(this);
rvLargeWidget.setImageViewResource(R.id.ivRepeatWidget, getRepeatRes());
rvLargeWidget.setImageViewResource(R.id.ivShuffle, getShuffleRes());
appWidgetLargeManager.updateAppWidget(playerWidgetLargeProvider, rvLargeWidget);
}
private void initReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_PLAY);
intentFilter.addAction(ACTION_NEXT);
intentFilter.addAction(ACTION_PREVIOUS);
intentFilter.addAction(ACTION_PAUSE);
intentFilter.addAction(ACTION_TIMER);
intentFilter.addAction(ACTION_UPDATE);
intentFilter.addAction(ACTION_SONG_PLAY);
intentFilter.addAction(ACTION_NWP_UPDATE);
intentFilter.addAction(ACTION_REPEAT);
intentFilter.addAction(ACTION_SHUFFLE);
intentFilter.addAction(ACTION_EXIT);
intentFilter.addAction("android.media.AUDIO_BECOMING_NOISY");
registerReceiver(receiver, intentFilter);
}
private void initAudios() {
if (getSongPos() < 0 || getSongPos() >= songsCursor.getCount()) {
preferences.setPrefSongPos(0);
}
}
private void initAudioManager() {
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
private void initListener() {
mediaPlayer.setOnCompletionListener(this);
}
private void initMediaPlayer() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK);
}
private void initMessenger() {
client = new ArrayList<>();
messenger = new Messenger(new ServiceHandler());
}
private void setSongRepeat() {
String repeat_state = preferences.getPrefRepeat();
setSongLooping(repeat_state);
}
@Override
public void onCompletion(@NonNull MediaPlayer mp) {
if (mp.isLooping()) {
play(songPath);
} else {
sendMessageNextOrPreviousSong(KEY_NEXT, DATA_KEY_NUMBER_OF_PLAY, DATA_PLAY_NUMBER);
}
}
private void sendMessageNextOrPreviousSong(int key, String dataKey, int data) {
if (client != null && client.size() == 1) {
choiceSendMessage(key, dataKey, data);
} else {
//choice next or previous or shuffle song position
if (getPrefShuffle().equalsIgnoreCase(NowPlayingFragment.SHUFFLE_ON)) {
choiceRandomSongPos(key);
} else if (getPrefRepeat().equalsIgnoreCase(NowPlayingFragment.REPEAT_ALL)) {
choiceFirstOrLastPos(key);
} else if (getPrefRepeat().equalsIgnoreCase(NowPlayingFragment.REPEAT_OFF)) {
if (!choiceSongPos(key)) {
pause();
sendMessageToActivity(MSG_PLAY_STATE, DATA_KEY_PLAY_STATE, 2);
return;
}
}
if (getSongPos() >= songsCursor.getCount() || getSongPos() < 0) {
preferences.setPrefSongPos(0);
}
sendDataToPlayer();
progressSong();
}
}
private void choiceRandomSongPos(int key) {
switch (key) {
case KEY_NEXT:
preferences.setPrefSongPos(randomSong.getRandomPos());
break;
case KEY_PREVIOUS:
if (RandomSong.randomPosList != null && !RandomSong.randomPosList.isEmpty()) {
Integer songPos = RandomSong.randomPosList.get(RandomSong.randomPosList.size() - 1);
RandomSong.randomPosList.remove(RandomSong.randomPosList.size() - 1);
preferences.setPrefSongPos(songPos);
} else {
preferences.setPrefSongPos(randomSong.getRandomPos());
}
break;
}
}
private void sendDataToPlayer() {
Intent intent = new Intent(BaseFragment.ACTION_SONG_DETAIL);
if (songsCursor.moveToPosition(getSongPos())) {
String songTitle = getSongTitle();
String albumId = songsCursor.getString(songsCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ALBUM_ID));
String albumPath = NowPlayingFragment.getAlbumPath(albumId, getBaseContext());
intent.putExtra(BaseFragment.KEY_SONG_TITLE, songTitle);
intent.putExtra(BaseFragment.KEY_ALBUM_ART_PATH, albumPath);
sendBroadcast(intent);
}
}
private String getSongTitle() {
return songsCursor.getString(songsCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.TITLE));
}
private void choiceSendMessage(int key, String dataKey, int data) {
switch (key) {
case KEY_NEXT:
sendMessageToActivity(MSG_NEXT, dataKey, data);
break;
case KEY_PREVIOUS:
sendMessageToActivity(MSG_PREVIOUS, dataKey, data);
break;
}
}
private void progressSong() {
play(getSongPath());
updateNotification();
updateWidget();
}
private void choiceFirstOrLastPos(int key) {
switch (key) {
case KEY_NEXT:
if (getSongPos() == songsCursor.getCount() - 1) {
preferences.setPrefSongPos(0);
} else {
preferences.setPrefSongPos(getSongPos() + 1);
}
break;
case KEY_PREVIOUS:
if (getSongPos() == 0) {
preferences.setPrefSongPos(songsCursor.getCount() - 1);
} else {
preferences.setPrefSongPos(getSongPos() - 1);
}
break;
}
}
private boolean choiceSongPos(int key) {
switch (key) {
case KEY_NEXT:
if (getSongPos() < songsCursor.getCount() - 1) {
preferences.setPrefSongPos(getSongPos() + 1);
} else {
return false;
}
break;
case KEY_PREVIOUS:
if (getSongPos() > 0) {
preferences.setPrefSongPos(getSongPos() - 1);
} else {
return false;
}
break;
}
return true;
}
private void updateNotification() {
setRemoteViewsValues();
notificationBuild.contentView = rvNotification;
notificationManager.notify(NOTIFY_ID, notificationBuild);
}
private String getSongPath() {
return songsCursor.getString(songsCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DATA));
}
private void play(String songPath) {
try {
isPlaying = true;
if (!isPause) {
newPlay(songPath);
} else {
if (oldSongPath == null) {
if (newPlay) {
newPlay = false;
NowPlayingFragment.song_duration_state = 0;
initMediaPlayerSong(songPath);
} else {
initMediaPlayerSong(songPath);
}
} else if (!oldSongPath.equalsIgnoreCase(songPath)) {
newPlay(songPath);
} else {
mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
}
}
mediaPlayer.start();
sendMessageCurrentDuration();
sendPlayStateToPlayer();
MediaPlayerService.songPath = songPath;
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
private void updateWidget() {
rvSmallWidget.setOnClickPendingIntent(R.layout.widget_small_layout, getMainPendingIntent());
rvLargeWidget.setOnClickPendingIntent(R.layout.widget_large_layout, getMainPendingIntent());
appWidgetSmallManager.updateAppWidget(playerWidgetSmallProvider, rvSmallWidget);
appWidgetLargeManager.updateAppWidget(playerWidgetLargeProvider, rvLargeWidget);
}
private void sendPlayStateToPlayer() {
//change player play button
sendBroadcast(new Intent(BaseFragment.ACTION_PLAY_STATE));
}
private void newPlay(String songPath) {
NowPlayingFragment.song_duration_state = 0;
mediaPlayer.reset();
initMediaPlayerSong(songPath);
}
private void initMediaPlayerSong(String songPath) {
try {
oldSongPath = songPath;
mediaPlayer.setDataSource(songPath);
mediaPlayer.prepare();
mediaPlayer.seekTo(NowPlayingFragment.song_duration_state);
isPause = false;
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), getString(R.string.title_song_error), Toast.LENGTH_SHORT).show();
}
}
private void sendMessageCurrentDuration() {
timerHandlerPostDelay();
}
@NonNull
private final Runnable currentDurationThread = new Runnable() {
@Override
public void run() {
try {
sendMessageToActivity(MSG_CURRENT_DURATION, DATA_KEY_CURRENT_POS, mediaPlayer.getCurrentPosition());
updateSongDurationPref();
if (isPlaying) {
timerHandlerPostDelay();
}
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
};
private void timerHandlerPostDelay() {
timerHandler.postDelayed(currentDurationThread, DELAY_MILLIS);
}
private void sendMessageToActivity(int what, @Nullable String dataKey, int data) {
for (int i = 0; i < client.size(); i++) {
Message msg = Message.obtain(null, what);
if (dataKey != null) {
Bundle bundle = new Bundle();
bundle.putInt(dataKey, data);
msg.setData(bundle);
}
try {
client.get(i).send(msg);
} catch (RemoteException e) {
e.printStackTrace();
client.remove(i);
}
}
}
private void pause() {
try {
if (!TarMediaPlayerActivity.isActivity) {
stopSelf();
return;
}
NowPlayingFragment.play_state = NowPlayingFragment.PLAY;
mediaPlayer.pause();
isPause = true;
isPlaying = false;
updateNotification();
sendPlayStateToPlayer();
updateWidget();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
private void stop() {
mediaPlayer.stop();
}
private void seekTo(int value) {
if (isPlaying) {
try {
mediaPlayer.seekTo(value);
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
private void showNotification() {
initRemoteViews();
setRemoteViewsValues();
setActionRemoteViews();
initNotificationBuild();
startForeground(NOTIFY_ID, notificationBuild);
}
private void setActionRemoteViews() {
rvNotification.setOnClickPendingIntent(R.id.ivPlaySongNotf, getPendingIntent(ACTION_PLAY));
rvNotification.setOnClickPendingIntent(R.id.ivNextSongNotf, getPendingIntent(ACTION_NEXT));
rvNotification.setOnClickPendingIntent(R.id.ivPreviousSongNotf, getPendingIntent(ACTION_PREVIOUS));
rvNotification.setOnClickPendingIntent(R.id.ivClear, getPendingIntent(ACTION_EXIT));
rvSmallWidget.setOnClickPendingIntent(R.id.ivPlaySongNotf, getPendingIntent(PlayerWidgetSmallProvider.ACTION_SMALL_WIDGET_PLAY));
rvSmallWidget.setOnClickPendingIntent(R.id.ivNextSongNotf, getPendingIntent(PlayerWidgetSmallProvider.ACTION_SMALL_WIDGET_NEXT));
rvSmallWidget.setOnClickPendingIntent(R.id.ivPreviousSongNotf, getPendingIntent(PlayerWidgetSmallProvider.ACTION_SMALL_WIDGET_PREVIOUS));
rvLargeWidget.setOnClickPendingIntent(R.id.ivPlaySongNotf, getPendingIntent(PlayerWidgetLargeProvider.ACTION_LARGE_WIDGET_PLAY));
rvLargeWidget.setOnClickPendingIntent(R.id.ivNextSongNotf, getPendingIntent(PlayerWidgetLargeProvider.ACTION_LARGE_WIDGET_NEXT));
rvLargeWidget.setOnClickPendingIntent(R.id.ivPreviousSongNotf, getPendingIntent(PlayerWidgetLargeProvider.ACTION_LARGE_WIDGET_PREVIOUS));
rvLargeWidget.setOnClickPendingIntent(R.id.ivRepeatWidget, getPendingIntent(PlayerWidgetLargeProvider.ACTION_LARGE_WIDGET_REPEAT));
rvLargeWidget.setOnClickPendingIntent(R.id.ivShuffle, getPendingIntent(PlayerWidgetLargeProvider.ACTION_LARGE_WIDGET_SHUFFLE));
}
private PendingIntent getPendingIntent(String action) {
Intent intent = new Intent(action);
return PendingIntent.getBroadcast(this, 0, intent, 0);
}
private void setRemoteViewsValues() {
if (songsCursor.moveToPosition(getSongPos())) {
String songTitle = getSongTitle();
String album_id = songsCursor.getString(songsCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ALBUM_ID));
String albumArt = NowPlayingFragment.getAlbumPath(album_id, getApplicationContext());
setRemoteViews(songTitle, albumArt);
}
}
private void setRemoteViews(String songTitle, String albumArtPath) {
initRemoteViews();
setActionRemoteViews();
Bitmap albumArt = BitmapFactory.decodeFile(albumArtPath);
Bitmap defaultArt = BitmapFactory.decodeResource(getResources(), R.drawable.ic_default_albumart);
//setbackground color
int primaryColor;
if (albumArt != null) {
Palette palette = Palette.from(albumArt).generate();
primaryColor = palette.getVibrantColor(getColorCode(R.color.primary_text));
} else {
albumArt = defaultArt;
primaryColor = getColorCode(R.color.primary);
}
rvSmallWidget.setImageViewBitmap(R.id.ivRepeat, albumArt);
rvLargeWidget.setImageViewBitmap(R.id.ivRepeat, albumArt);
rvNotification.setImageViewBitmap(R.id.ivRepeat, albumArt);
rvNotification.setInt(R.id.rlPlayer, "setBackgroundColor", primaryColor);
rvSmallWidget.setInt(R.id.rlPlayer, "setBackgroundColor", primaryColor);
rvLargeWidget.setInt(R.id.rlPlayer, "setBackgroundColor", primaryColor);
rvNotification.setTextViewText(R.id.tvSongDetailsNotf, songTitle);
rvSmallWidget.setTextViewText(R.id.tvSongDetailsNotf, songTitle);
rvLargeWidget.setTextViewText(R.id.tvSongDetailsNotf, songTitle);
if (isPlaying) {
rvNotification.setImageViewResource(R.id.ivPlaySongNotf, R.drawable.ic_pause);
rvSmallWidget.setImageViewResource(R.id.ivPlaySongNotf, R.drawable.ic_pause);
rvLargeWidget.setImageViewResource(R.id.ivPlaySongNotf, R.drawable.ic_pause);
} else {
rvNotification.setImageViewResource(R.id.ivPlaySongNotf, R.drawable.ic_play);
rvSmallWidget.setImageViewResource(R.id.ivPlaySongNotf, R.drawable.ic_play);
rvLargeWidget.setImageViewResource(R.id.ivPlaySongNotf, R.drawable.ic_play);
}
}
private int getColorCode(int id) {
return ContextCompat.getColor(getApplicationContext(), id);
}
private void initNotificationBuild() {
notificationBuild = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_song)
.setAutoCancel(false).setContentIntent(getMainPendingIntent()).setContent(rvNotification).build();
notificationBuild.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
}
private void initRemoteViews() {
rvNotification = new RemoteViews(getPackageName(), R.layout.notification_layout);
rvSmallWidget = new RemoteViews(getPackageName(), R.layout.widget_small_layout);
rvLargeWidget = new RemoteViews(getPackageName(), R.layout.widget_large_layout);
}
private PendingIntent getMainPendingIntent() {
Intent intent = new Intent(this, TarMediaPlayerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
if (intent != null) {
Bundle data = intent.getExtras();
if (data != null) {
String extra = data.getString(PlayerWidgetSmallProvider.EXTRA_WIDGET);
if (extra != null) {
if (extra.equalsIgnoreCase(PlayerWidgetSmallProvider.VALUE_PLAY)) {
play(songPath);
updateNotification();
updateWidget();
} else if (extra.equalsIgnoreCase(PlayerWidgetSmallProvider.VALUE_NEXT)) {
sendMessageNextOrPreviousSong(KEY_NEXT, null, 0);
} else if (extra.equalsIgnoreCase(PlayerWidgetSmallProvider.VALUE_PREVIOUS)) {
sendMessageNextOrPreviousSong(KEY_PREVIOUS, null, 0);
} else if (extra.equalsIgnoreCase(PlayerWidgetSmallProvider.VALUE_PAUSE)) {
stopSelf();
}
} else {
stopSelf();
}
}
}
return START_STICKY;
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
stopSelf();
}
@Override
public void onAudioFocusChange(int focusChange) {
try {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
System.out.println("GAIN");
if (isTransientDuck) {
isTransientDuck = false;
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, defaultVolume, 0);
}
if (mediaPlayer != null && isFocusPause) {
isFocusPause = false;
mediaPlayer.start();
}
break;
case AudioManager.AUDIOFOCUS_LOSS:
System.out.println("LOSS");
if (mediaPlayer != null && isPlaying) {
mediaPlayerStop();
audioManager.abandonAudioFocus(this);
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
System.out.println("LOSS_TRANSIENT");
if (mediaPlayer != null && isPlaying) {
pause();
isFocusPause = true;
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
System.out.println("DUCK");
if (mediaPlayer != null && isPlaying) {
isTransientDuck = true;
defaultVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 2, 0);
}
break;
}
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
isServiceStart = false;
stopForeground(true);
mediaPlayerStop();
isPlaying = false;
unregisterReceiver(receiver);
setRemoteViewsValues();
updateWidget();
if (!songsCursor.isClosed() && songsCursor != null && songsCursor.getCount() != 0) {
songsCursor.close();
}
super.onDestroy();
}
private void updateSongDurationPref() {
preferences.setPrefDuration(mediaPlayer.getCurrentPosition());
}
private void mediaPlayerStop() {
try {
if (mediaPlayer.isPlaying()) {
stop();
}
mediaPlayer.release();
} catch (IllegalStateException ex) {
ex.printStackTrace();
}
}
@NonNull
private final BroadcastReceiver receiver = new BroadcastReceiver() {
static final int DATA_PLAY = 1;
static final int DATA_PAUSE = 2;
@Override
public void onReceive(Context context, @NonNull Intent intent) {
if (intent.getAction().equalsIgnoreCase(ACTION_SONG_PLAY)) {
if (songsCursor.moveToPosition(getSongPos())) {
songPath = getSongPath();
play(songPath);
updateNotification();
updateWidget();
sendDataToPlayer();
sendMessageToActivity(MSG_PLAY_STATE, DATA_KEY_PLAY_STATE, DATA_PLAY);
}
} else if (intent.getAction().equalsIgnoreCase(ACTION_PLAY)) {
if (!mediaPlayer.isPlaying()) {
play(songPath);
updateNotification();
updateWidget();
sendMessageToActivity(MSG_PLAY_STATE, DATA_KEY_PLAY_STATE, DATA_PLAY);
} else {
pause();
sendMessageToActivity(MSG_PLAY_STATE, DATA_KEY_PLAY_STATE, DATA_PAUSE);
}
} else if (intent.getAction().equalsIgnoreCase(ACTION_PAUSE)) {
pause();
sendMessageToActivity(MSG_PLAY_STATE, DATA_KEY_PLAY_STATE, DATA_PAUSE);
sendDataToPlayer();
} else if (intent.getAction().equals(ACTION_NEXT)) {
sendMessageNextOrPreviousSong(KEY_NEXT, null, 0);
} else if (intent.getAction().equals(ACTION_PREVIOUS)) {
sendMessageNextOrPreviousSong(KEY_PREVIOUS, null, 0);
} else if (intent.getAction().equalsIgnoreCase(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
pause();
sendMessageToActivity(MSG_PLAY_STATE, DATA_KEY_PLAY_STATE, DATA_PAUSE);
} else if (intent.getAction().equalsIgnoreCase(ACTION_TIMER)) {
int timer_length = preferences.getPrefTimer();
if (timer_length > 0) {
setCountDownTimer(timer_length);
} else {
if (countDownTimer != null) {
countDownTimer.cancel();
}
}
} else if (intent.getAction().equalsIgnoreCase(ACTION_UPDATE)) {
setRemoteViewsValues();
rvNotification.setOnClickPendingIntent(R.layout.notification_layout, getMainPendingIntent());
initPlayerWidget();
} else if (intent.getAction().equalsIgnoreCase(ACTION_NWP_UPDATE)) {
if (songsCursor != null && songsCursor.getCount() == 0) {
updateNotification();
updateWidget();
sendDataToPlayer();
}
} else if (intent.getAction().equalsIgnoreCase(ACTION_REPEAT)) {
changeRepeatState();
rvLargeWidget.setImageViewResource(R.id.ivRepeatWidget, getRepeatRes());
appWidgetLargeManager.updateAppWidget(playerWidgetLargeProvider, rvLargeWidget);
} else if (intent.getAction().equalsIgnoreCase(ACTION_SHUFFLE)) {
changeShuffleState();
rvLargeWidget.setImageViewResource(R.id.ivShuffle, getShuffleRes());
appWidgetLargeManager.updateAppWidget(playerWidgetLargeProvider, rvLargeWidget);
} else if (intent.getAction().equalsIgnoreCase(ACTION_EXIT)) {
if (TarMediaPlayerActivity.isActivity) {
sendBroadcast(new Intent(TarMediaPlayerActivity.ACTION_FINISH));
} else {
stopSelf();
}
}
}
};
private int getRepeatRes() {
String repeat_state = preferences.getPrefRepeat();
if (repeat_state.equalsIgnoreCase(NowPlayingFragment.REPEAT_ALL)) {
return R.drawable.ic_repeat_all;
} else if (repeat_state.equalsIgnoreCase(NowPlayingFragment.REPEAT_ONE)) {
return R.drawable.ic_repeat_one;
} else {
return R.drawable.ic_repeat;
}
}
private void changeRepeatState() {
String repeat_state = preferences.getPrefRepeat();
if (repeat_state.equalsIgnoreCase(NowPlayingFragment.REPEAT_ALL)) {
repeat_state = NowPlayingFragment.REPEAT_OFF;
} else if (repeat_state.equalsIgnoreCase(NowPlayingFragment.REPEAT_OFF)) {
repeat_state = NowPlayingFragment.REPEAT_ONE;
} else if (repeat_state.equalsIgnoreCase(NowPlayingFragment.REPEAT_ONE)) {
repeat_state = NowPlayingFragment.REPEAT_ALL;
}
preferences.setPrefRepeat(repeat_state);
}
private int getShuffleRes() {
String shuffle_state = preferences.getPrefShuffle();
if (shuffle_state.equalsIgnoreCase(NowPlayingFragment.SHUFFLE_ON)) {
return R.drawable.ic_shuffle_on;
} else {
RandomSong.randomPosList = new ArrayList<>();
return R.drawable.ic_shuffle_off;
}
}
private void changeShuffleState() {
String shuffle_state = preferences.getPrefShuffle();
if (shuffle_state.equalsIgnoreCase(NowPlayingFragment.SHUFFLE_ON)) {
shuffle_state = NowPlayingFragment.SHUFFLE_OFF;
} else if (shuffle_state.equalsIgnoreCase(NowPlayingFragment.SHUFFLE_OFF)) {
shuffle_state = NowPlayingFragment.SHUFFLE_ON;
}
preferences.setPrefShuffle(shuffle_state);
}
}