Android开发:用通知栏(Notification Bar)控制音乐的后台播放

最近要制作一个后台播放音乐的功能,可是在UI中不给控制按钮,于是只好通过通知栏来控制了,网上找了许多,没有找到相关的文章,经过不断摸索,终于实现了该功能,在此记录下来,即作为备忘,也可作为分享。


1、首先,创建一个service来播放音乐:


public class AudioService extends Service {
    private MediaPlayer mediaPlayer;
    private final static String TAG = "debug";
    public ButtonBroadcastReceiver bReceiver;
    public final static String ACTION_BUTTON = "com.weidongjian.weigan.ButtonClick";
    public NotificationManager mNotificationManager;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("debug", "oncrete");
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            mediaPlayer.setDataSource("http://abv.cn/music/%E5%85%89%E8%BE%89%E5%B2%81%E6%9C%88.mp3");
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        initButtonReceiver();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("debug", "onStartCommnad");
        if (!mediaPlayer.isPlaying()){
            mediaPlayer.start();
        }
        showButtonNotify();
        return START_STICKY;
    }

    public void onDestroy(){
        Log.i("debug", "onDestory");
        //super.onDestroy();
        if(mediaPlayer.isPlaying()){
            mediaPlayer.stop();
        }
        mediaPlayer.release();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

我在onCreate里面,初始化了MediaPlayer对象,并用于播放网络地址音乐,并有一个初始化Receive的公式: initButtonReceiver();,这个留到后面讲。


2、第二部是创建一个Notification了,这个在网上有许多的资源了,我这里用的是remoteView创建一个自定义的Notification,而且在控制音乐这里,只能用remoteView;

public void showButtonNotify(){
        Notification.Builder mBuilder = new Notification.Builder(this);
        RemoteViews mRemoteViews = new RemoteViews(getPackageName(), R.layout.view_custom_button);
        mRemoteViews.setImageViewResource(R.id.custom_song_icon, R.drawable.sing_icon);
       
        mBuilder.setContent(mRemoteViews)
                .setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT))
                .setWhen(System.currentTimeMillis())// 通知产生的时间,会在通知信息里显示
                .setTicker("正在播放")
                .setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级
                .setOngoing(true)
                .setSmallIcon(R.drawable.sing_icon);
        Notification notify = mBuilder.build();
        notify.flags = Notification.FLAG_ONGOING_EVENT;
        //会报错,还在找解决思路
//		notify.contentView = mRemoteViews;
//		notify.contentIntent = PendingIntent.getActivity(this, 0, new Intent(), 0);
        mNotificationManager.notify(200, notify);
    }

这个是RemoteView的layout:


    

    

        

        

        
    

    

        

        
    


现在问题来了,如何处理RemoteView上面的点击事件,并且传给service呢,原来RemoteView有一个可以发广播的方法,如下:

public void setOnClickPendingIntent (int viewId, PendingIntent pendingIntent)

Added in  API level 3

Equivalent to calling setOnClickListener(android.view.View.OnClickListener) to launch the provided PendingIntent. When setting the on-click action of items within collections (eg. ListViewStackView etc.), this method will not work. Instead, use {@link RemoteViews#setPendingIntentTemplate(int, PendingIntent) in conjunction with RemoteViews#setOnClickFillInIntent(int, Intent).

Parameters
viewId The id of the view that will trigger the PendingIntent when clicked
pendingIntent The PendingIntent to send when user clicks
点击后,用PendingIntent.gotbroadCast来发送广播,实现代码如下:

	 Intent buttonIntent = new Intent(ACTION_BUTTON);
		/* 上一首按钮 */
        buttonIntent.putExtra(INTENT_BUTTONID_TAG, BUTTON_PREV_ID);
        //这里加了广播,所及INTENT的必须用getBroadcast方法
        PendingIntent intent_prev = PendingIntent.getBroadcast(this, 1, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_prev, intent_prev);
		/* 播放/暂停  按钮 */
        buttonIntent.putExtra(INTENT_BUTTONID_TAG, BUTTON_PALY_ID);
        PendingIntent intent_paly = PendingIntent.getBroadcast(this, 2, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_play, intent_paly);
		/* 下一首 按钮  */
        buttonIntent.putExtra(INTENT_BUTTONID_TAG, BUTTON_NEXT_ID);
        PendingIntent intent_next = PendingIntent.getBroadcast(this, 3, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_next, intent_next);

这样的话,只要在service里面,建立一个receiver,就可以接收广播了,从而操控音乐的播放:

public void initButtonReceiver(){
        bReceiver = new ButtonBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_BUTTON);
        registerReceiver(bReceiver, intentFilter);

    }

    public final static String INTENT_BUTTONID_TAG = "ButtonId";
    /** 上一首 按钮点击 ID */
    public final static int BUTTON_PREV_ID = 1;
    /** 播放/暂停 按钮点击 ID */
    public final static int BUTTON_PALY_ID = 2;
    /** 下一首 按钮点击 ID */
    public final static int BUTTON_NEXT_ID = 3;

    public class ButtonBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            String action = intent.getAction();
            if(action.equals(ACTION_BUTTON)){
                //通过传递过来的ID判断按钮点击属性或者通过getResultCode()获得相应点击事件
                int buttonId = intent.getIntExtra(INTENT_BUTTONID_TAG, 0);
                switch (buttonId) {
                    case BUTTON_PREV_ID:
                        Log.d(TAG , "上一首01");
                        Toast.makeText(getApplicationContext(), "上一首", Toast.LENGTH_SHORT).show();
                        break;
                    case BUTTON_PALY_ID:
                        Log.d(TAG , "play");
                        Toast.makeText(getApplicationContext(), play_status, Toast.LENGTH_SHORT).show();
                        break;
                    case BUTTON_NEXT_ID:
                        Log.d(TAG , "next song);
                        Toast.makeText(getApplicationContext(), "下一首", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            }
        }
    }

这样我们就可以在service的广播里面处理Notification的点击事件了。


参考文章:
1、我的Android进阶之旅------>Android MediaPlayer播放网络音频的实例--网络mp3播放器
2、 Android实现在线播放音乐





你可能感兴趣的:(Android开发)