J'ai écrit Music Player complet pour diffuser de la musique à partir du Web, mais je ne sais pas comment mettre les commandes du lecteur multimédia dans Notification et lorsque l'écran est verrouillé.
Je suis ce didacticiel pour afficher les commandes dans la barre de notification, mais je n’obtiens toujours pas l’utilisation des mêmes fonctionnalités dans mon programme, j’ai importé les classes requises telles que: NotificationService.Java
et Constants.Java
.
Voici ce que je reçois dans la barre de notification:
[]
Je suis confus. Pourquoi je ne reçois pas le titre de la chanson que je joue, pourquoi les boutons pause, prev et next ne fonctionnent pas, etc.
NotificationService.Java:
public class NotificationService extends Service {
Notification status;
private final String LOG_TAG = "NotificationService";
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
showNotification();
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
} else if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
Toast.makeText(this, "Clicked Previous", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Clicked Previous");
} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
Toast.makeText(this, "Clicked Play", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Clicked Play");
} else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
Toast.makeText(this, "Clicked Next", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Clicked Next");
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
Toast.makeText(this, "Service Stoped", Toast.LENGTH_SHORT).show();
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
private void showNotification() {
// Using RemoteViews to bind custom layouts into Notification
RemoteViews views = new RemoteViews(getPackageName(), R.layout.status_bar);
RemoteViews bigViews = new RemoteViews(getPackageName(), R.layout.status_bar_expanded);
// showing default album image
views.setViewVisibility(R.id.status_bar_icon, View.VISIBLE);
views.setViewVisibility(R.id.status_bar_album_art, View.GONE);
bigViews.setImageViewBitmap(R.id.status_bar_album_art,
Constants.getDefaultAlbumArt(this));
Intent notificationIntent = new Intent(this, MusicPlayerActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Intent previousIntent = new Intent(this, NotificationService.class);
previousIntent.setAction(Constants.ACTION.PREV_ACTION);
PendingIntent ppreviousIntent = PendingIntent.getService(this, 0, previousIntent, 0);
Intent playIntent = new Intent(this, NotificationService.class);
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
PendingIntent pplayIntent = PendingIntent.getService(this, 0, playIntent, 0);
Intent nextIntent = new Intent(this, NotificationService.class);
nextIntent.setAction(Constants.ACTION.NEXT_ACTION);
PendingIntent pnextIntent = PendingIntent.getService(this, 0, nextIntent, 0);
Intent closeIntent = new Intent(this, NotificationService.class);
closeIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
PendingIntent pcloseIntent = PendingIntent.getService(this, 0, closeIntent, 0);
views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
bigViews.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
views.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);
bigViews.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);
views.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);
bigViews.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);
views.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);
bigViews.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);
views.setImageViewResource(R.id.status_bar_play,
R.drawable.apollo_holo_dark_pause);
bigViews.setImageViewResource(R.id.status_bar_play,
R.drawable.apollo_holo_dark_pause);
views.setTextViewText(R.id.status_bar_track_name, "Song Title");
bigViews.setTextViewText(R.id.status_bar_track_name, "Song Title");
views.setTextViewText(R.id.status_bar_artist_name, "Artist Name");
bigViews.setTextViewText(R.id.status_bar_artist_name, "Artist Name");
bigViews.setTextViewText(R.id.status_bar_album_name, "Album Name");
status = new Notification.Builder(this).build();
status.contentView = views;
status.bigContentView = bigViews;
status.flags = Notification.FLAG_ONGOING_EVENT;
status.icon = R.drawable.ic_launcher;
status.contentIntent = pendingIntent;
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, status);
}
}
Constants.Java:
public class Constants {
public interface ACTION {
public static String MAIN_ACTION = "com.marothiatechs.customnotification.action.main";
public static String INIT_ACTION = "com.marothiatechs.customnotification.action.init";
public static String PREV_ACTION = "com.marothiatechs.customnotification.action.prev";
public static String PLAY_ACTION = "com.marothiatechs.customnotification.action.play";
public static String NEXT_ACTION = "com.marothiatechs.customnotification.action.next";
public static String STARTFOREGROUND_ACTION = "com.marothiatechs.customnotification.action.startforeground";
public static String STOPFOREGROUND_ACTION = "com.marothiatechs.customnotification.action.stopforeground";
}
public interface NOTIFICATION_ID {
public static int FOREGROUND_SERVICE = 101;
}
public static Bitmap getDefaultAlbumArt(Context context) {
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
try {
bm = BitmapFactory.decodeResource(context.getResources(),
R.drawable.default_album_art, options);
} catch (Error ee) {
} catch (Exception e) {
}
return bm;
}
}
MusicPlayerActivity.Java:
public class MusicPlayerActivity extends Activity {
// ....
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
mediaPlayer = new MediaPlayer();
audiosArrayList = new ArrayList<MusicPlayer>();
listview = (ListView) findViewById(R.id.list_slidermenu);
// ...
btnPlay.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
try {
play();
} catch (Exception exception){
Log.v("exception:play", exception.toString());
}
}
});
btnPause.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
try {
pause();
} catch (Exception exception){
Log.v("exception:pause", exception.toString());
}
}
});
btnNext.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
try {
next();
} catch (Exception exception){
Log.v("exception:next", exception.toString());
}
}
});
btnPrev.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
try {
prev();
} catch (Exception exception){
Log.v("exception:pause", exception.toString());
}
}
});
new JSONAsyncTask().execute("http://myurl/json/musics.json");
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (mediaPlayer != null && mediaPlayer.isPlaying())
try {
mediaPlayer.stop();
} catch (Exception e) {
}
play();
}
});
......
}
// ...
public void startService(View v) {
Intent serviceIntent = new Intent(MusicPlayerActivity.this, NotificationService.class);
serviceIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(serviceIntent);
}
Vous devez définir une action d'intention personnalisée, et non la classe de composant AudioPlayerBroadcastReceiver.
Créer une intention avec un nom d'action personnalisé comme celui-ci
Intent switchIntent = new Intent("com.example.app.ACTION_PLAY");
Ensuite, enregistrez le récepteur PendingIntent Broadcast
PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 100, switchIntent, 0);
Ensuite, définissez un onClick pour le contrôle de lecture, effectuez une action personnalisée similaire pour les autres contrôles si nécessaire.
notificationView.setOnClickPendingIntent(R.id.btn_play_pause_in_notification, pendingSwitchIntent);
Enregistrez ensuite l'action personnalisée dans AudioPlayerBroadcastReceiver comme ceci
<receiver Android:name="com.example.app.AudioPlayerBroadcastReceiver" >
<intent-filter>
<action Android:name="com.example.app.ACTION_PLAY" />
</intent-filter>
</receiver>
Enfin, lorsque vous cliquez sur Lecture dans la présentation Notification RemoteViews, l’action de lecture de BroadcastReceiver
public class AudioPlayerBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equalsIgnoreCase("com.example.app.ACTION_PLAY")) {
// do your stuff to play action;
}
}
}
EDIT: comment définir le filtre d'intention pour le récepteur de radiodiffusion enregistré dans le code
Vous pouvez également définir le filtre Action personnalisée par intention à partir du code pour le récepteur de radiodiffusion enregistré, comme ceci
// instance of custom broadcast receiver
CustomReceiver broadcastReceiver = new CustomReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
// set the custom action
intentFilter.addAction("com.example.app.ACTION_PLAY");
// register the receiver
registerReceiver(broadcastReceiver, intentFilter);
vérifier ce lien pour plus d'informations
essayez quelque chose comme ceci (j'ai utilisé des entiers pour les actions):
intent.putExtra("action", ACTION_EXIT);
pendingIntent = PendingIntent.getService(this, intent.getIntExtra("action", 0), intent, PendingIntent.FLAG_UPDATE_CURRENT);
dans PendingIntent statique public getService (contexte de contexte, int requestCode, intention d'intention, int flags) le requestCode doit être unique.
Avez-vous trouvé une solution? Je peux vous expliquer avec un autre code. C'est un peu similaire, mais je l'ai modifié parce que je joue un Streaming Audio. Faites-moi savoir si vous avez besoin d'aide.
Je veux juste partager avec vous ma méthode showNotification()
private void showNotification() {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
//Start IntentNotification
Log.i(LOG_TAG, "Received Start Foreground Intent ");
Intent notificationIntent = new Intent(ForegroundService.this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
//With this settings you can open the same Activity without recreate.
//But you have to put in your AndroidManifest.xml the next line: to your Activity
//activity Android:name=".MainActivity" Android:launchMode="singleInstance"
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//Intent for Play
Intent playIntent = new Intent(this, ForegroundService.class);
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
PendingIntent pplayIntent = PendingIntent.getService(this, 0, playIntent, 0);
//Intent for Pause
Intent pausaIntent = new Intent(this, ForegroundService.class);
pausaIntent.setAction(Constants.ACTION.PAUSE_ACTION);
PendingIntent pauseIntent = PendingIntent.getService(this, 0, pausaIntent, 0);
//Intent for Close
stopIntent = new Intent(this, ForegroundService.class);
stopIntent.setAction(Constants.ACTION.CLOSE_ACTION);
PendingIntent closeIntent = PendingIntent.getService(this, 0, stopIntent, 0);
//Icon for your notification
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
notifManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(getApplicationContext(), MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
// Build the notification object.
mNotificationBuilder = new Notification.Builder(this)
.setContentTitle("Thinking out Loud")
.setContentText("Ed Sheeran")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.addAction(R.drawable.ic_play_service, "PLAY", pplayIntent) //you can set a specific icon
.addAction(R.drawable.ic_pause_service, "PAUSE", pauseIntent) //you can set a specific icon
.addAction(R.drawable.ic_close_service, "CLOSE", closeIntent);//you can set a specific icon
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, mNotificationBuilder.build());
} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
Log.i(LOG_TAG, "Clicked Play");
//Click Play notification
} else if (intent.getAction().equals(Constants.ACTION.PAUSE_ACTION)) {
Log.i(LOG_TAG, "Clicked PAUSE");
//This is for Pause
} else if (intent.getAction().equals(Constants.ACTION.CLOSE_ACTION)) {
Log.i(LOG_TAG, "Clicked Close");
//This is for close the NotificationService
stopForeground(true);
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
stopForeground(true);
//Stop Notification Service
stopSelf();
}
}
Mon Constants.class
public class Constants {
public interface ACTION {
public static String MAIN_ACTION = "action.main";
public static String PREV_ACTION = "action.prev";
public static String PLAY_ACTION = "action.play";
public static String PAUSE_ACTION = "action.pause";
public static String NEXT_ACTION = "action.next";
public static String CLOSE_ACTION = "action.close";
public static String STARTFOREGROUND_ACTION = "action.startforeground";
public static String STOPFOREGROUND_ACTION = "action.stopforeground";
}
public interface NOTIFICATION_ID {
public static int FOREGROUND_SERVICE = 101;
}
}