add a notification for controlling the player

This commit is contained in:
tibbi 2016-02-13 18:44:58 +01:00
parent 13c9ca6a5c
commit f59700671b
9 changed files with 188 additions and 50 deletions

View file

@ -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>

View file

@ -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";
}

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -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) {

View file

@ -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) {

View file

@ -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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B