add a notification for controlling the player
This commit is contained in:
parent
13c9ca6a5c
commit
f59700671b
9 changed files with 188 additions and 50 deletions
|
@ -38,6 +38,7 @@
|
|||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="musicplayer.simplemobiletools.com.action.INIT"/>
|
||||
<action android:name="musicplayer.simplemobiletools.com.action.FINISH"/>
|
||||
<action android:name="musicplayer.simplemobiletools.com.action.PREVIOUS"/>
|
||||
<action android:name="musicplayer.simplemobiletools.com.action.PAUSE"/>
|
||||
<action android:name="musicplayer.simplemobiletools.com.action.PLAYPAUSE"/>
|
||||
|
@ -69,5 +70,7 @@
|
|||
<action android:name="android.intent.action.MEDIA_BUTTON"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".ControlActionsListener"/>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -6,13 +6,16 @@ public class Constants {
|
|||
public static final String WIDGET_TEXT_COLOR = "widget_text_color";
|
||||
public static final String SONG_POS = "song_position";
|
||||
|
||||
public static final String INIT = "musicplayer.simplemobiletools.com.action.INIT";
|
||||
public static final String PREVIOUS = "musicplayer.simplemobiletools.com.action.PREVIOUS";
|
||||
public static final String PAUSE = "musicplayer.simplemobiletools.com.action.PAUSE";
|
||||
public static final String PLAYPAUSE = "musicplayer.simplemobiletools.com.action.PLAYPAUSE";
|
||||
public static final String NEXT = "musicplayer.simplemobiletools.com.action.NEXT";
|
||||
public static final String STOP = "musicplayer.simplemobiletools.com.action.STOP";
|
||||
public static final String PLAYPOS = "musicplayer.simplemobiletools.com.action.PLAYPOS";
|
||||
public static final String CALL_START = "musicplayer.simplemobiletools.com.action.INCOMING_CALL_START";
|
||||
public static final String CALL_STOP = "musicplayer.simplemobiletools.com.action.INCOMING_CALL_STOP";
|
||||
private static final String PATH = "musicplayer.simplemobiletools.com.action.";
|
||||
|
||||
public static final String INIT = PATH + "INIT";
|
||||
public static final String FINISH = PATH + "FINISH";
|
||||
public static final String PREVIOUS = PATH + "PREVIOUS";
|
||||
public static final String PAUSE = PATH + "PAUSE";
|
||||
public static final String PLAYPAUSE = PATH + "PLAYPAUSE";
|
||||
public static final String NEXT = PATH + "NEXT";
|
||||
public static final String STOP = PATH + "STOP";
|
||||
public static final String PLAYPOS = PATH + "PLAYPOS";
|
||||
public static final String CALL_START = PATH + "CALL_START";
|
||||
public static final String CALL_STOP = PATH + "CALL_STOP";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package musicplayer.simplemobiletools.com;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class ControlActionsListener extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
switch (action) {
|
||||
case Constants.PREVIOUS:
|
||||
case Constants.PLAYPAUSE:
|
||||
case Constants.NEXT:
|
||||
case Constants.STOP:
|
||||
case Constants.FINISH:
|
||||
context.startService(new Intent(action));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,12 +3,6 @@ package musicplayer.simplemobiletools.com;
|
|||
import java.util.ArrayList;
|
||||
|
||||
public class Events {
|
||||
public static class IncomingCallStart {
|
||||
}
|
||||
|
||||
public static class IncomingCallStop {
|
||||
}
|
||||
|
||||
public static class SongChanged {
|
||||
private Song song;
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package musicplayer.simplemobiletools.com;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
|
@ -16,6 +18,8 @@ import android.provider.MediaStore;
|
|||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
|
@ -53,7 +57,8 @@ public class MusicService extends Service
|
|||
headsetPlugReceiver = new HeadsetPlugReceiver();
|
||||
incomingCallReceiver = new IncomingCallReceiver(this);
|
||||
wasPlayingAtCall = false;
|
||||
initMediaPlayer();
|
||||
initMediaPlayerIfNeeded();
|
||||
setupNotification();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,6 +98,9 @@ public class MusicService extends Service
|
|||
case Constants.CALL_STOP:
|
||||
incomingCallStop();
|
||||
break;
|
||||
case Constants.FINISH:
|
||||
destroyPlayer();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -101,7 +109,10 @@ public class MusicService extends Service
|
|||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
public void initMediaPlayer() {
|
||||
public void initMediaPlayerIfNeeded() {
|
||||
if (player != null)
|
||||
return;
|
||||
|
||||
player = new MediaPlayer();
|
||||
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
|
||||
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
|
@ -142,6 +153,56 @@ public class MusicService extends Service
|
|||
});
|
||||
}
|
||||
|
||||
private void setupNotification() {
|
||||
final Intent intent = new Intent(this, ControlActionsListener.class);
|
||||
|
||||
final RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification);
|
||||
remoteViews.setInt(R.id.widget_holder, "setBackgroundColor", 0);
|
||||
|
||||
updateSongInfo(remoteViews);
|
||||
updatePlayPauseButton(remoteViews);
|
||||
|
||||
setupIntent(intent, remoteViews, Constants.PREVIOUS, R.id.previousBtn);
|
||||
setupIntent(intent, remoteViews, Constants.PLAYPAUSE, R.id.playPauseBtn);
|
||||
setupIntent(intent, remoteViews, Constants.NEXT, R.id.nextBtn);
|
||||
setupIntent(intent, remoteViews, Constants.STOP, R.id.stopBtn);
|
||||
setupIntent(intent, remoteViews, Constants.FINISH, R.id.closeBtn);
|
||||
|
||||
remoteViews.setViewVisibility(R.id.closeBtn, View.VISIBLE);
|
||||
|
||||
final Notification notification = new Notification.Builder(this).setSmallIcon(R.mipmap.ic_launcher).build();
|
||||
notification.bigContentView = remoteViews;
|
||||
|
||||
final Intent contentIntent = new Intent(this, MainActivity.class);
|
||||
notification.contentIntent = PendingIntent.getActivity(this, 0, contentIntent, 0);
|
||||
|
||||
startForeground(1, notification);
|
||||
}
|
||||
|
||||
private void setupIntent(Intent intent, RemoteViews remoteViews, String action, int id) {
|
||||
intent.setAction(action);
|
||||
final PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
|
||||
|
||||
if (remoteViews != null)
|
||||
remoteViews.setOnClickPendingIntent(id, pendingIntent);
|
||||
}
|
||||
|
||||
private void updateSongInfo(RemoteViews remoteViews) {
|
||||
final String title = (currSong == null) ? "" : currSong.getTitle();
|
||||
final String artist = (currSong == null) ? "" : currSong.getArtist();
|
||||
|
||||
remoteViews.setTextViewText(R.id.songTitle, title);
|
||||
remoteViews.setTextViewText(R.id.songArtist, artist);
|
||||
}
|
||||
|
||||
private void updatePlayPauseButton(RemoteViews remoteViews) {
|
||||
int playPauseIcon = R.mipmap.play_white;
|
||||
if (isPlaying())
|
||||
playPauseIcon = R.mipmap.pause_white;
|
||||
|
||||
remoteViews.setImageViewResource(R.id.playPauseBtn, playPauseIcon);
|
||||
}
|
||||
|
||||
private int getNewSongId() {
|
||||
final int cnt = songs.size();
|
||||
if (cnt == 0) {
|
||||
|
@ -167,8 +228,7 @@ public class MusicService extends Service
|
|||
if (songs.isEmpty())
|
||||
return;
|
||||
|
||||
if (player == null)
|
||||
initMediaPlayer();
|
||||
initMediaPlayerIfNeeded();
|
||||
|
||||
// play the previous song if we are less than 5 secs into the song, else restart
|
||||
// remove the latest song from the list
|
||||
|
@ -184,8 +244,7 @@ public class MusicService extends Service
|
|||
if (songs.isEmpty())
|
||||
return;
|
||||
|
||||
if (player == null)
|
||||
initMediaPlayer();
|
||||
initMediaPlayerIfNeeded();
|
||||
|
||||
player.pause();
|
||||
songStateChanged(false);
|
||||
|
@ -199,8 +258,7 @@ public class MusicService extends Service
|
|||
if (songs.isEmpty())
|
||||
return;
|
||||
|
||||
if (player == null)
|
||||
initMediaPlayer();
|
||||
initMediaPlayerIfNeeded();
|
||||
|
||||
if (currSong == null)
|
||||
playNextSong();
|
||||
|
@ -237,8 +295,7 @@ public class MusicService extends Service
|
|||
return;
|
||||
|
||||
final boolean wasPlaying = isPlaying();
|
||||
if (player == null)
|
||||
initMediaPlayer();
|
||||
initMediaPlayerIfNeeded();
|
||||
|
||||
player.reset();
|
||||
if (addNewSong)
|
||||
|
@ -283,14 +340,13 @@ public class MusicService extends Service
|
|||
@Override
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
mp.start();
|
||||
setupNotification();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
destroyPlayer();
|
||||
if (bus != null)
|
||||
bus.unregister(this);
|
||||
}
|
||||
|
||||
private void destroyPlayer() {
|
||||
|
@ -300,8 +356,17 @@ public class MusicService extends Service
|
|||
player = null;
|
||||
}
|
||||
|
||||
if (bus != null) {
|
||||
songStateChanged(false);
|
||||
bus.post(new Events.SongChanged(null));
|
||||
bus.unregister(this);
|
||||
}
|
||||
|
||||
final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
||||
telephonyManager.listen(incomingCallReceiver, PhoneStateListener.LISTEN_NONE);
|
||||
|
||||
stopForeground(true);
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
public void incomingCallStart() {
|
||||
|
@ -321,6 +386,7 @@ public class MusicService extends Service
|
|||
}
|
||||
|
||||
private void songStateChanged(boolean isPlaying) {
|
||||
setupNotification();
|
||||
bus.post(new Events.SongStateChanged(isPlaying));
|
||||
|
||||
if (isPlaying) {
|
||||
|
|
|
@ -21,11 +21,6 @@ import com.squareup.otto.Bus;
|
|||
import com.squareup.otto.Subscribe;
|
||||
|
||||
public class MyWidgetProvider extends AppWidgetProvider {
|
||||
private static final String PREVIOUS = "previous";
|
||||
private static final String PLAYPAUSE = "playpause";
|
||||
private static final String NEXT = "next";
|
||||
private static final String STOP = "stop";
|
||||
|
||||
private static int[] widgetIds;
|
||||
private static RemoteViews remoteViews;
|
||||
private static AppWidgetManager widgetManager;
|
||||
|
@ -45,7 +40,7 @@ public class MyWidgetProvider extends AppWidgetProvider {
|
|||
|
||||
private void setupIntent(String action, int id) {
|
||||
intent.setAction(action);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(cxt, 0, intent, 0);
|
||||
final PendingIntent pendingIntent = PendingIntent.getBroadcast(cxt, 0, intent, 0);
|
||||
|
||||
if (remoteViews != null)
|
||||
remoteViews.setOnClickPendingIntent(id, pendingIntent);
|
||||
|
@ -171,17 +166,11 @@ public class MyWidgetProvider extends AppWidgetProvider {
|
|||
|
||||
final String action = intent.getAction();
|
||||
switch (action) {
|
||||
case PREVIOUS:
|
||||
context.startService(new Intent(Constants.PREVIOUS));
|
||||
break;
|
||||
case PLAYPAUSE:
|
||||
context.startService(new Intent(Constants.PLAYPAUSE));
|
||||
break;
|
||||
case NEXT:
|
||||
context.startService(new Intent(Constants.NEXT));
|
||||
break;
|
||||
case STOP:
|
||||
context.startService(new Intent(Constants.STOP));
|
||||
case Constants.PREVIOUS:
|
||||
case Constants.PLAYPAUSE:
|
||||
case Constants.NEXT:
|
||||
case Constants.STOP:
|
||||
context.startService(new Intent(action));
|
||||
break;
|
||||
default:
|
||||
super.onReceive(context, intent);
|
||||
|
@ -196,10 +185,10 @@ public class MyWidgetProvider extends AppWidgetProvider {
|
|||
}
|
||||
|
||||
private void setupButtons() {
|
||||
setupIntent(PREVIOUS, R.id.previousBtn);
|
||||
setupIntent(PLAYPAUSE, R.id.playPauseBtn);
|
||||
setupIntent(NEXT, R.id.nextBtn);
|
||||
setupIntent(STOP, R.id.stopBtn);
|
||||
setupIntent(Constants.PREVIOUS, R.id.previousBtn);
|
||||
setupIntent(Constants.PLAYPAUSE, R.id.playPauseBtn);
|
||||
setupIntent(Constants.NEXT, R.id.nextBtn);
|
||||
setupIntent(Constants.STOP, R.id.stopBtn);
|
||||
}
|
||||
|
||||
private void setupViews(Context context) {
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
android:id="@+id/controls"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/widget_row_height"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:layout_marginRight="@dimen/activity_margin"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
@ -21,6 +19,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:src="@mipmap/previous"/>
|
||||
|
||||
<ImageView
|
||||
|
@ -28,6 +28,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:src="@mipmap/play"/>
|
||||
|
||||
<ImageView
|
||||
|
@ -35,6 +37,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:src="@mipmap/next"/>
|
||||
|
||||
<ImageView
|
||||
|
@ -42,6 +46,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingTop="5dp"
|
||||
android:src="@mipmap/stop"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
54
app/src/main/res/layout/notification.xml
Normal file
54
app/src/main/res/layout/notification.xml
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
android:id="@+id/widget_holder"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/black"
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/closeBtn"
|
||||
android:layout_width="@dimen/widget_row_height"
|
||||
android:layout_height="@dimen/widget_row_height"
|
||||
android:layout_alignParentRight="true"
|
||||
android:paddingBottom="@dimen/medium_padding"
|
||||
android:paddingTop="@dimen/medium_padding"
|
||||
android:src="@mipmap/close_white"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/songTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:layout_marginRight="@dimen/activity_margin"
|
||||
android:layout_marginTop="@dimen/medium_padding"
|
||||
android:layout_toLeftOf="@+id/closeBtn"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/songArtist"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/songTitle"
|
||||
android:layout_marginBottom="@dimen/medium_padding"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:layout_marginRight="@dimen/activity_margin"
|
||||
android:layout_toLeftOf="@+id/closeBtn"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<include
|
||||
layout="@layout/widget_controls"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/widget_row_height"
|
||||
android:layout_below="@+id/songArtist"/>
|
||||
</RelativeLayout>
|
BIN
app/src/main/res/mipmap-hdpi/close_white.png
Normal file
BIN
app/src/main/res/mipmap-hdpi/close_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 826 B |
Loading…
Reference in a new issue