通过服务+广播+通知实现的一个通知栏音乐控制器

来源:互联网 发布:单片机是什么专业学的 编辑:程序博客网 时间:2024/06/06 20:14

之前的一段时间在学习服务和广播这两个知识点,然后在网上看到一些对于后台操作需要通过服务与广播的一些例子,便索性做一个小demo对这些知识点进行巩固;通过服务+广播+通知对后台音乐进行播放、暂停、停止这三样简单的控制。



创建demo后的第一步便是创建服务,创建一个名为MusicService的类,继承Service类;然后在MusicService里实现音乐文件的初始化,同时创建各种方法对音乐播放的控制,其中音乐控制相关方法与通知控制都设为静态,其他类可直接通过类进行调用,以下为代码,材料自找

public class MusicService extends Service {    private static MediaPlayer mediaPlayer; //声明操作媒体的对象    static int pos = 0; //记录播放的位置    private static NotificationManager notificationManager;    private String TAG = "media";    private static Notification notification;        class MyBinder extends Binder{        public MusicService getService(){            //绑定服务同时进行播放            play();            return MusicService.this;        }    }    @Override    public IBinder onBind(Intent intent) {        return new MyBinder();    }    @Override    public void onCreate() {        super.onCreate();        showMusicNotification();        //初始化播放对象        if (mediaPlayer == null){            mediaPlayer = mediaPlayer.create(MusicService.this,R.raw.lit);            mediaPlayer.setLooping(false);        }        //监听播放结束,释放资源        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {            @Override            public void onCompletion(MediaPlayer mp) {                mediaPlayer.release();            }        });    }    //用于开始播放的方法    public static void play(){        if (mediaPlayer != null && !mediaPlayer.isPlaying()){            try {                if (pos != 0){                    //根据指定位置进行播放                    mediaPlayer.seekTo(pos);                    mediaPlayer.start();                }else {                    //首次或从头播放,并显示通知                    notificationManager.notify(200,notification);                    mediaPlayer.stop();                    mediaPlayer.prepare();                    mediaPlayer.start();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }    //暂停播放    public static void pause(){        if (mediaPlayer != null && mediaPlayer.isPlaying()){            //获取播放位置            pos = mediaPlayer.getCurrentPosition();            mediaPlayer.pause();        }    }    //停止播放    public static void stop(){        if (mediaPlayer != null){            mediaPlayer.stop();            pos = 0; //停止后播放位置置为0        }

}


服务类需要在AndroidManifest.xml里进行注册

<service            android:name=".MusicService"            android:enabled="true"            android:exported="true"/>

接着是创建通知,通过使用RemoteViews类创建自定义通知样式的对象,样式自己可通过创建布局进行自定义,而其中对布局控件的点击操作是通过发送广播进行操作

public void showMusicNotification(){        Notification.Builder builder = new Notification.Builder(this);        RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.notification);        remoteViews.setImageViewResource(R.id.image,R.drawable.timg);        builder.setContent(remoteViews)                .setWhen(System.currentTimeMillis())                .setTicker("正在播放")                .setPriority(Notification.PRIORITY_DEFAULT)                .setAutoCancel(false)                .setOngoing(true)                .setSmallIcon(R.mipmap.ic_launcher);        //通知栏控制器播放按钮广播操作        Intent intentPlay = new Intent("play");//新建意图,设置action标记为“play”,用于接收广播时过滤意图信息        PendingIntent playPendingIntent = PendingIntent.getBroadcast(this,0,intentPlay,0);        remoteViews.setOnClickPendingIntent(R.id.play,playPendingIntent);//为play控件注册事件        //通知栏控制器暂停按钮广播操作        Intent intentPause = new Intent("pause");        PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this,0,intentPause,0);        remoteViews.setOnClickPendingIntent(R.id.pause,pausePendingIntent);        //通知栏控制器停止按钮广播操作        Intent intentStop = new Intent("stop");        PendingIntent stopPendingIntent = PendingIntent.getBroadcast(this,0,intentStop,0);        remoteViews.setOnClickPendingIntent(R.id.stop,stopPendingIntent);        ////通知栏控制器关闭通知按钮广播操作        Intent intentDead = new Intent("clear");        PendingIntent deadPendingIntent = PendingIntent.getBroadcast(this,0,intentDead,0);        remoteViews.setOnClickPendingIntent(R.id.dead,deadPendingIntent);        notification = builder.build();        notification.flags = notification.FLAG_ONGOING_EVENT;        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);    }


以下是我的通知栏的布局文件,图片可网上找

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal"    android:layout_width="match_parent"    android:layout_height="80dp">    <ImageView        android:id="@+id/image"        android:src="@mipmap/ic_launcher"        android:layout_width="80dp"        android:layout_height="80dp" />    <LinearLayout        android:layout_centerInParent="true"        android:layout_toRightOf="@+id/image"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <ImageView            android:layout_marginTop="10dp"            android:layout_marginLeft="30dp"            android:src="@mipmap/pause"            android:id="@+id/pause"            android:layout_width="40dp"            android:layout_height="40dp" />        <ImageView            android:layout_marginTop="10dp"            android:layout_marginLeft="40dp"            android:src="@mipmap/play"            android:id="@+id/play"            android:layout_width="40dp"            android:layout_height="40dp" />        <ImageView            android:layout_marginTop="10dp"            android:layout_marginLeft="40dp"            android:src="@mipmap/stop"            android:id="@+id/stop"            android:layout_width="40dp"            android:layout_height="40dp" />        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="60dp">            <ImageView                android:id="@+id/dead"                android:src="@mipmap/clear"                android:layout_width="35dp"                android:layout_height="35dp"                android:layout_centerVertical="true"                android:layout_centerHorizontal="true" />        </RelativeLayout>    </LinearLayout></RelativeLayout>

接下来是广播接收器,创建名为MusicReciver的类,继承BroadcastReceiver类,以下为代码文件

public class MusicReceiver extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        String ctrl_code = intent.getAction();        if ("play".equals(ctrl_code)){            //通知栏音乐播放操作            MusicService.play();        }else if ("pause".equals(ctrl_code)){            //通知栏音乐暂停操作            MusicService.pause();        }else if ("stop".equals(ctrl_code)){            //通知栏音乐停止操作            MusicService.stop();        }else if ("clear".equals(ctrl_code)){            //通知栏关闭通知操作            MusicService.clearNotification();            MusicService.stop();        }    }}

接收器需要在AndroidManifest.xml里进行注册,并且自定义的广播消息需要在注册的接收器内进行定义,否则程序会报错

<receiver android:name=".MusicReceiver"            android:exported="true">            <intent-filter>                <action android:name="play"/>                <action android:name="pause"/>                <action android:name="stop"/>                <action android:name="clear"/>            </intent-filter>        </receiver>

最后的是主activity的布局与类文件,主布局如下

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    tools:context="com.example.li.musictest.MainActivity"    android:layout_width="match_parent"    android:layout_height="match_parent">    <ImageView        android:src="@drawable/timg"        android:layout_marginTop="100dp"        android:layout_centerHorizontal="true"        android:layout_width="200dp"        android:layout_height="200dp" />    <LinearLayout        android:layout_marginBottom="100dp"        android:layout_alignParentBottom="true"        android:layout_centerInParent="true"        android:layout_toRightOf="@+id/image"        android:layout_width="wrap_content"        android:layout_height="wrap_content">        <ImageView            android:src="@mipmap/pause"            android:id="@+id/pause"            android:layout_width="50dp"            android:layout_height="50dp" />        <ImageView            android:layout_marginLeft="40dp"            android:layout_marginRight="40dp"            android:src="@mipmap/play"            android:id="@+id/play"            android:layout_width="50dp"            android:layout_height="50dp" />        <ImageView            android:src="@mipmap/stop"            android:id="@+id/stop"            android:layout_width="50dp"            android:layout_height="50dp" />    </LinearLayout></RelativeLayout>

主类主要实现主布局的点击操作,其中有一内部类继承了ServiceConnection类,为与服务通讯的主要实现类,其余是我们平常的点击操作

public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private Intent intent;    private MusicService musicService;    private MusicConnection myConnection = new MusicConnection();    private String TAG = "media";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findViewById(R.id.play).setOnClickListener(this);        findViewById(R.id.pause).setOnClickListener(this);        findViewById(R.id.stop).setOnClickListener(this);    }    @Override    public void onClick(View v) {        //activity页面的相关点击操作        switch (v.getId()){            //播放            case R.id.play:                if (musicService == null) {                    //首次播放绑定服务                    intent = new Intent(MainActivity.this,MusicService.class);                    bindService(intent,myConnection, Context.BIND_AUTO_CREATE);                    startService(intent);                }else {                    musicService.play();                }                break;            //暂停            case R.id.pause:                if (musicService != null){                    musicService.pause();                }                break;            //停止            case R.id.stop:                if (musicService != null){                    musicService.stop();                }                break;        }    }    private class MusicConnection implements ServiceConnection {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            MusicService.MyBinder myBinder = (MusicService.MyBinder) service;            musicService = myBinder.getService();        }        @Override        public void onServiceDisconnected(ComponentName name) {            myConnection = null;        }    }    @Override    protected void onDestroy() {        super.onDestroy();        unbindService(myConnection);        MusicService.clearNotification();        Log.i(TAG, "onDestroy: ");    }}


第一次写博客,可能有很多不足的地方,代码也可能有错误的地方,希望多加指正

以下为运行图


                      


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 安卓8.0不兼容app怎么办 两条内存不兼容怎么办 王者荣耀软件不兼容怎么办 冒险岛不兼容win7怎么办 百度网盘手机号换了怎么办 破解版游戏闪退怎么办 安卓手机软件不兼容怎么办 安卓8.0软件闪退怎么办 游戏与手机系统不兼容怎么办 耳机和手机不兼容怎么办 软件和手机不兼容怎么办 小米6开关键失灵怎么办 同步助手下载不了微信旧版本怎么办 闲鱼退货卖家拒收怎么办 闲鱼把联系人删了怎么办 闲鱼付款了卖家不发货怎么办 红米4c卡怎么办 如果买鞋子买到假的怎么办 猎趣永久封号钱怎么办 支付宝换绑定手机后怎么办 为什么回收站的删除键不见了怎么办 微信在异地登录怎么办 支付宝帐号被冻结怎么办 进不了路由器设置页面怎么办 支付宝支付密码忘记了怎么办 淘宝忘记登录密码了怎么办 手机换卡了微信怎么办 淘宝退款成功后收到货怎么办 没收到货退款商家不处理怎么办 没收到货申请退款卖家不处理怎么办 京东已收到货却不处理退款怎么办 货退了卖家不退款怎么办 淘宝退了货卖家不退款怎么办 手机淘宝不显示图片怎么办 京东申请退款卖家不处理怎么办 企业网银冻结了怎么办 农行k宝坏了怎么办 手机检测不到u盾怎么办 农行有k宝怎么办信用卡 k米怎么点不了怎么办 c1驾照被扣3分怎么办