Moja aplikacja odtwarza muzykę, a gdy użytkownicy otwierają ekran powiadomień, przesuwając palcem od góry ekranu (lub ogólnie od prawego dolnego rogu ekranu na tabletach), chcę im pokazać przycisk zatrzymujący aktualnie odtwarzaną muzykę i rozpoczynający ją ponownie, jeśli chcą.
Nie planuję umieszczać widżetu na ekranie głównym użytkownika, a tylko do powiadomień. Jak mogę to zrobić?
android
button
widget
notifications
szczery
źródło
źródło
Odpowiedzi:
Możesz stworzyć intencję akcji (w tym przypadku przestań grać) i dodać ją jako przycisk akcji do swojego powiadomienia.
Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class); snoozeIntent.setAction(ACTION_SNOOZE); snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0); PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .addAction(R.drawable.ic_snooze, getString(R.string.snooze), snoozePendingIntent);
Zapoznaj się z dokumentacją systemu Android .
źródło
Dodaj przycisk akcji do powiadomienia
Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class); snoozeIntent.setAction(ACTION_SNOOZE); snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0); PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .addAction(R.drawable.ic_snooze, getString(R.string.snooze), snoozePendingIntent);
Aby uzyskać więcej informacji, odwiedź https://developer.android.com/training/notify-user/build-notification.html
źródło
Postaram się zapewnić rozwiązanie, z którego korzystałem, a większość odtwarzaczy muzyki również używa tej samej techniki do wyświetlania kontrolek odtwarzacza na pasku powiadomień.
Prowadzę usługę, która służy do zarządzania odtwarzaczem multimedialnym i wszystkimi jego kontrolkami. Kontrola użytkownika działania współdziała z usługą, na przykład wysyłając intencje do usługi
Intent i = new Intent(MainActivity.this, MyRadioService.class); i.setAction(Constants.Player.ACTION_PAUSE); startService(i);
Aby odebrać intencje i wykonać akcję w klasie Service używam następującego kodu w metodzie Service onStartCommand
@Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent.getAction().equals(Constants.Player.ACTION_PAUSE)) { if(mediaPlayer.isPlaying()) { pauseAudio(); } }
Teraz do dokładnej odpowiedzi na twoje pytanie, aby pokazać powiadomienie z kontrolkami odtwarzania. Możesz wywołać następujące metody, aby wyświetlić powiadomienie z kontrolkami.
// showNotification private void startAppInForeground() { // Start Service in Foreground // Using RemoteViews to bind custom layouts into Notification RemoteViews views = new RemoteViews(getPackageName(), R.layout.notification_status_bar); // Define play control intent Intent playIntent = new Intent(this, MyRadioService.class); playIntent.setAction(Constants.Player.ACTION_PLAY); // Use the above play intent to set into PendingIntent PendingIntent pplayIntent = PendingIntent.getService(this, 0, playIntent, 0); // binding play button from layout to pending play intent defined above views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent); views.setImageViewResource(R.id.status_bar_play, R.drawable.status_bg); Notification status = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { status = new Notification.Builder(this).build(); } status.flags = Notification.FLAG_ONGOING_EVENT; status.icon = R.mipmap.ic_launcher; status.contentIntent = pendingIntent; startForeground(Constants.FOREGROUND_SERVICE, status);
} Mam nadzieję, że to naprawdę ci pomoże. I będziesz w stanie osiągnąć to, co chcesz. Miłego kodowania :)
źródło
complete
odpowiedziąfit
na ten przypadek użytkownika.// It shows buttons on lock screen (notification). Notification notification = new Notification.Builder(context) .setVisibility(Notification.VISIBILITY_PUBLIC) .setSmallIcon(R.drawable.NotIcon) .addAction(R.drawable.ic_prev, "button1",ButtonOneScreen) .addAction(R.drawable.ic_pause, "button2", ButtonTwoScreen) ..... .setStyle(new Notification.MediaStyle() .setShowActionsInCompactView(1) .setMediaSession(mMediaSession.getSessionToken()) .setContentTitle("your choice") .setContentText("Again your choice") .setLargeIcon(buttonIcon) .build();
Więcej informacji można znaleźć tutaj. Kliknij tutaj
źródło
Myślę, że oprócz
Ankit Gupta
odpowiedzi możesz użyć MediaSession (API> 21), aby dodać natywny widok mediaController :notificationBuilder .setStyle(new Notification.MediaStyle() .setShowActionsInCompactView(new int[]{playPauseButtonPosition}) // show only play/pause in compact view .setMediaSession(mSessionToken)) .setColor(mNotificationColor) .setSmallIcon(R.drawable.ic_notification) .setVisibility(Notification.VISIBILITY_PUBLIC) .setUsesChronometer(true) .setContentIntent(createContentIntent(description)) // Create an intent that would open the UI when user clicks the notification .setContentTitle(description.getTitle()) .setContentText(description.getSubtitle()) .setLargeIcon(art);
Źródło: poradnik
można ALSE tworzyć własne i wyświetlenia go w obszarze notificcation, pierwsza odpowiedź tutaj jest super.
źródło
przetestowany, działający kod z Androidem Pie. Wszystkie mieszczą się w tej samej klasie usług.
Pokaż powiadomienie:
public void setNotification() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("a", "status", NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription("notifications"); notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } else notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Receiver.service = this; Notification.MediaStyle style = new Notification.MediaStyle(); notification = new Notification.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("Notification") .addAction(R.drawable.close_icon, "quit_action", makePendingIntent("quit_action")) .setStyle(style); style.setShowActionsInCompactView(0); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notification.setChannelId("a"); } // notificationManager.notify(123 , notification.build()); // pre-oreo startForeground(126, notification.getNotification()); }
Funkcja pomocnicza:
public PendingIntent makePendingIntent(String name) { Intent intent = new Intent(this, FloatingViewService.Receiver.class); intent.setAction(name); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); return pendingIntent; }
Aby obsłużyć działania:
static public class Receiver extends BroadcastReceiver { static FloatingViewService service; @Override public void onReceive(Context context, Intent intent) { String whichAction = intent.getAction(); switch (whichAction) { case "quit_action": service.stopForeground(true); service.stopSelf(); return; } } }
Musisz też zaktualizować swój manifest:
<receiver android:name=".FloatingViewService$Receiver"> <intent-filter> <action android:name="quit_action" /> </intent-filter> </receiver>
źródło
możesz dodać przycisk jak poniżej i możesz wykonać akcję na tym przycisku, również zrobiłem dla mnie, jak poniżej, sprawdź.
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_logo) .setAutoCancel(true) .setContentTitle(name) .setContentText(body) .setGroupSummary(true) .addAction(android.R.drawable.ic_menu_directions, "Mark as read", morePendingIntent);
// morePendingIntent (rób swoje)
PendingIntent morePendingIntent = PendingIntent.getBroadcast( this, REQUEST_CODE_MORE, new Intent(this, NotificationReceiver.class) .putExtra(KEY_INTENT_MORE, REQUEST_CODE_MORE) .putExtra("bundle", object.toString()), PendingIntent.FLAG_UPDATE_CURRENT );
źródło
Nie wiem, czy to właściwy sposób, czy nie, ale działa.
BroadCastReceiver
klasę, aby otrzymywać dane po naciśnięciu przycisku.public class MyBroadCastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String log = "URI: " + intent.toUri(Intent.URI_INTENT_SCHEME); Log.d("my", "LOG:::::::" + log); } }
Intent intent = new Intent(); intent.setAction("unique_id"); intent.putExtra("key", "any data you want to send when button is pressed"); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, 0);
BroadcastReceiver br = new MyBroadCastReceiver(); IntentFilter filter = new IntentFilter("unique_id"); registerReceiver(br, filter);
Teraz, jeśli chcesz wykonać określone czynności po naciśnięciu przycisku, możesz to zrobić w
onReceive()
metodzie wMyBroadCastReceiver
klasie.źródło