Media Player контролирует уведомление

Я написал полный музыкальный проигрыватель для потоковой передачи музыки из Интернета, но я не знаю, как установить элементы управления медиаплеером в Notification и когда на экране заблокирован.

Я следую за этот учебник, чтобы отображать элементы управления на панели уведомлений, но все еще не получая. Как использовать те же функции в моей программе, я импортировали необходимые классы, такие как: NotificationService.java и Constants.java.

Это то, что я получаю в панели уведомлений:

[Notification]

Я смущен. Почему я не получаю название песни, которую я играю, почему пауза, предыдущие и следующие кнопки не работают и т.д....

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

Ответы

Ответ 1

Привет, Софи, код ниже поможет вам.

Вызовите этот метод в своем MainActivity

public void showNotification(View view){
    new MyNotification(this);
    finish();
}

Создать новый пользовательский класс уведомлений

public class MyNotification extends Notification {

private Context ctx;
private NotificationManager mNotificationManager;

@SuppressLint("NewApi")
public MyNotification(Context ctx){
    super();
    this.ctx=ctx;
    String ns = Context.NOTIFICATION_SERVICE;
    mNotificationManager = (NotificationManager) ctx.getSystemService(ns);
    CharSequence tickerText = "Shortcuts";
    long when = System.currentTimeMillis();
    Notification.Builder builder = new Notification.Builder(ctx);
    @SuppressWarnings("deprecation")
    Notification notification=builder.getNotification();
    notification.when=when;
    notification.tickerText=tickerText;
    notification.icon=R.drawable.ic_launcher;

    RemoteViews contentView=new RemoteViews(ctx.getPackageName(), R.layout.messageview);

    //set the button listeners
    setListeners(contentView);

    notification.contentView = contentView;
    notification.flags |= Notification.FLAG_ONGOING_EVENT;
    CharSequence contentTitle = "From Shortcuts";
    mNotificationManager.notify(548853, notification);
}

public void setListeners(RemoteViews view){
    //radio listener
    Intent radio=new Intent(ctx,HelperActivity.class);
    radio.putExtra("DO", "radio");
    PendingIntent pRadio = PendingIntent.getActivity(ctx, 0, radio, 0);
    view.setOnClickPendingIntent(R.id.radio, pRadio);

    //volume listener
    Intent volume=new Intent(ctx, HelperActivity.class);
    volume.putExtra("DO", "volume");
    PendingIntent pVolume = PendingIntent.getActivity(ctx, 1, volume, 0);
    view.setOnClickPendingIntent(R.id.volume, pVolume);

    //reboot listener
    Intent reboot=new Intent(ctx, HelperActivity.class);
    reboot.putExtra("DO", "reboot");
    PendingIntent pReboot = PendingIntent.getActivity(ctx, 5, reboot, 0);
    view.setOnClickPendingIntent(R.id.reboot, pReboot);

    //top listener
    Intent top=new Intent(ctx, HelperActivity.class);
    top.putExtra("DO", "top");
    PendingIntent pTop = PendingIntent.getActivity(ctx, 3, top, 0);
    view.setOnClickPendingIntent(R.id.top, pTop);*/

    //app listener
    Intent app=new Intent(ctx, com.example.demo.HelperActivity.class);
    app.putExtra("DO", "app");
    PendingIntent pApp = PendingIntent.getActivity(ctx, 4, app, 0);
    view.setOnClickPendingIntent(R.id.btn1, pApp);
}

}

Создать класс HelperActivity

public class HelperActivity extends Activity {

private HelperActivity ctx;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    ctx = this;
    String action = (String) getIntent().getExtras().get("DO");
    if (action.equals("radio")) {
        //Your code
    } else if (action.equals("volume")) {
        //Your code
    } else if (action.equals("reboot")) {
        //Your code
    } else if (action.equals("top")) {
        //Your code
    } else if (action.equals("app")) {
        //Your code
    }

    if (!action.equals("reboot"))
        finish();
}

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
}
}

И XML-макет для уведомления здесь

    <TextView
    android:id="@+id/msglbl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="test" />

<TextView
    android:id="@+id/message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/msglbl" />

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="play" android:layout_margin="10dp"/>

Ответ 2

попробуйте что-то вроде этого (я использовал целые числа для действий):

intent.putExtra("action", ACTION_EXIT);
pendingIntent = PendingIntent.getService(this, intent.getIntExtra("action", 0), intent, PendingIntent.FLAG_UPDATE_CURRENT);

в общедоступном статическом PendingIntent getService (контекст контекста, int requestCode, намерение Intent, int flags) requestCode должен быть уникальным.

Ответ 3

Вам нужно установить действие пользовательского намерения, а не класс компонента AudioPlayerBroadcastReceiver.

Создайте намерение с пользовательским именем действия, подобным этому

Intent switchIntent = new Intent("com.example.app.ACTION_PLAY");

Then, register the PendingIntent Broadcast receiver

  PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 100, switchIntent, 0);

Then, set a onClick for the play control , do similar custom action for other controls if required.

  notificationView.setOnClickPendingIntent(R.id.btn_play_pause_in_notification, pendingSwitchIntent);

Затем зарегистрируйте пользовательское действие в AudioPlayerBroadcastReceiver, как это

<receiver android:name="com.example.app.AudioPlayerBroadcastReceiver" >
    <intent-filter>
        <action android:name="com.example.app.ACTION_PLAY" />
    </intent-filter>
</receiver>

Наконец, при нажатии на макет Notification RemoteViews, вы получите действие воспроизведения с помощью BroadcastReceiver

public class AudioPlayerBroadcastReceiver extends BroadcastReceiver{

@Override public void onReceive (контекстный контекст, намерение намерения) {

String action = intent.getAction();

if(action.equalsIgnoreCase("com.example.app.ACTION_PLAY")){
    // do your stuff to play action;
}

} }

EDIT: как установить фильтр намерений для широковещательного приемника, зарегистрированного в коде

Вы также можете настроить фильтр Custom Action to Intent из кода для зарегистрированного широковещательного приемника, такого как

    // 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); 

проверьте эту ссылку для получения дополнительной информации

https://www.binpress.com/tutorial/using-android-media-style-notifications-with-media-session-controls/165

Ответ 4

Вы нашли решение? Я могу объяснить вам код antoher, его немного то же самое, но я уже изменил для меня, потому что я играю Streaming Audio. Дайте мне знать, если вам нужна помощь.

Просто хочу поделиться с вами, как использовать метод 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", //you can set a specific icon
                                    pplayIntent)
                            .addAction(R.drawable.ic_pause_service, "PAUSE",//you can set a specific icon
                                    pauseIntent)
                            .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();
            }

    }

Мой 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;
    }
}