Android应用开发 Service使用

一、实验目的和要求

  1. 理解Service组件: 通过本实验,加深对Android Service组件的理解,包括它的生命周期、运行方式以及如何与Activity进行交互。
  2. 掌握后台播放音乐: 学习如何在后台使用Service组件播放音乐,实现音乐播放的持续性,即使用户切换应用或屏幕关闭。
  3. 学习Intent和BroadcastReceiver的使用: 通过实现音乐播放器的控制(播放、暂停、停止),掌握使用Intent传递信息和使用BroadcastReceiver监听广播事件的技巧。
  4. 提高UI更新技能: 学习如何根据Service的状态更新Activity界面,例如更新播放、暂停按钮的状态或显示当前播放的音乐信息。
  • 实验原理(技术分析)、方法与步骤
  1. 实验原理

Service 组件原理:Service 是 Android 中运行在后台的一种组件,它可以执行长时间运行的操作,不提供用户界面。ervice 可以是启停的(StartStop),也可以是绑定的(Bound),本项目中主要使用启停Service。

音乐播放原理:使用 MediaPlayer 类来加载和播放音乐文件。

广播通信原理:使用 BroadcastReceiver 和 Intent 来实现组件间的消息传递。当音乐播放状态改变时,Service 发送广播通知界面更新。

生命周期管理:理解 Service 的生命周期,包括 onCreate(), onStartCommand(), onDestroy() 等方法。

界面更新原理:使用 Handler 或 BroadcastReceiver 来实现从 Service 到 Activity 的通信,更新UI。

实验方法与步骤

  1. 创建一个新的Android Studio项目。
  2. 设置项目的最小SDK版本和目标SDK版本。
  3. 使用XML布局文件设计播放器创建一个Activity来承载计算器的UI界面。
  4. 编写MainActivity用于实现前台Activity。
  5. 编写Music Service用于实现后台Service。
  1. MainActivity
    public class MainActivity extends Activity implements  OnClickListener{
    
        //获取界面中的显示歌曲标题,作者文本框
        TextView title, author;
        //播放、暂停 终止按钮
        ImageButton play, stop;
        ActivityReceiver activityReceiver;
        public static final String CTL_ACTION =
                "org.crazyit.action.CTL_ACTION";
        public static final String UPDATE_ACTION =
                "org.crazyit.action.UPDATE_ACTION";
        // 定文音乐的播放状态,0x11 代表没有播放:0x12 代表正在播放:0x13 代表暂停
        int status = 0x11;
        String[] titleStrs = new String[]{"心愿", "约定", "美丽新世界"};
        String[] authorStrs = new String[]{"未知艺术家", "周蕙", "伍佰"};
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            //获取程序界面中的两个按钮
            play = (ImageButton) this.findViewById(R.id.play);
            stop = (ImageButton) this.findViewById(R.id.stop);
            title = (TextView) findViewById(R.id.titlel);
            author = (TextView) findViewById(R.id.author);
            //为两个按钮的单击事件添加监听器
            play.setOnClickListener(this);
            stop.setOnClickListener(this);
            activityReceiver = new ActivityReceiver();
            // 创建Intenteilter
            IntentFilter filter = new IntentFilter();
            // 指定 BroadcastReceiver 监听的 Action
            filter.addAction(UPDATE_ACTION);
            //注册 BroadcastReceiver
            registerReceiver(activityReceiver, filter);
            Intent intent = new Intent(this, MusicService.class);
            // 启动后台 Service
            startService(intent);
        }
    
        //自定义的 BroadcastReceiver,负责监听从Service 传回来的广播
        public class ActivityReceiver extends BroadcastReceiver
        {
            @Override
            public void onReceive(Context context, Intent intent)
            {
            //获取 Intent 中的update消息,update代表播放状态
            int update = intent.getIntExtra("update", -1);
            //获取 Intent 中的current 消息,current 代表当前正在播放的歌曲
            int current = intent.getIntExtra("current", -1);
            if(current >=0)
            {
                title.setText(titleStrs[current]);
                author.setText(authorStrs[current]);
            }
            switch(update)
            {
                case 0x11:
                    play.setImageResource(R.drawable.ic_play1);
                    status = 0x11;
                    break;
                //控制系统进入播放状态
                case 0x12:
                    //在播放状态下设置使用暂停图标
                    play.setImageResource(R.drawable.ic_stop1);
                    //设置当前状态
                    status = 0x12;
                    break;
                case 0x13:
                    play.setImageResource(R.drawable.ic_play1);
                    status = 0x13;
                    break;
                }
            }
        }
        @Override
        public void onClick(View source)
        {
            Intent intent = new Intent("org.crazyit.action.CTL_ACTION");
            switch (source.getId())
            {
                case R.id.play:
                    intent.putExtra("control",1);
                    break;
                case R.id.stop:
                    intent.putExtra("control",2);
                    break;
            }
            sendBroadcast(intent);
        }
    }

  2. Music Service
    public class MusicService extends Service {
        MyReceiver serviceReceiver;
        AssetManager am;
        String[] musics = new String[] {"wish.mp3","promise.mp3","beautiful.mp3"};
        MediaPlayer mPlayer;
        int status = 0x11;
        int current = 0;
        @Override
        public IBinder onBind(Intent intent)
        {
            return null;
        }
        @Override
        public void onCreate()
        {
            super.onCreate();
            am=getAssets();
            serviceReceiver=new MyReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(MainActivity.CTL_ACTION);
            registerReceiver(serviceReceiver,filter);
            mPlayer=new MediaPlayer();
            mPlayer.setOnCompletionListener(new OnCompletionListener()
            {
                @Override
                public void onCompletion(MediaPlayer mp){
                    current++;
                    if (current >= 3){
                        current = 0;
                    }
                    Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
                    sendIntent.putExtra("current",current);
                    sendBroadcast(sendIntent);
                    prepareAndPlay(musics[current]);
                }
            });
        }
        public class MyReceiver extends BroadcastReceiver
        {
            @Override
            public void onReceive(final Context context,Intent intent)
            {
                int control = intent.getIntExtra("control",-1);
                switch (control)
                {
                    case 1:
                        if (status == 0x11)
                        {
                            prepareAndPlay(musics[current]);
                            status=0x12;
                        }
                        else if (status == 0x12)
                        {
                            mPlayer.pause();
                            status=0x13;
                        }
                        else if (status == 0x13)
                        {
                            mPlayer.start();
                            status = 0x12;
                        }
                        break;
                    case 2:
                        if (status == 0x12||status == 0x13)
                        {
                            mPlayer.stop();
                            status=0x11;
                        }
                }
                Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
                sendIntent.putExtra("update",status);
                sendIntent.putExtra("current",current);
                sendBroadcast(sendIntent);
            }
        }
        private void prepareAndPlay(String music)
        {
            try
            {
                AssetFileDescriptor afd = am.openFd(music);
                mPlayer.reset();
                mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                mPlayer.prepare();
                mPlayer.start();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
  3. Maim.xml

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/titlel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/song_title"
        android:textSize="24sp"
        android:textStyle="bold"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="16dp" />

    <TextView
        android:id="@+id/author"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/song_author"
        android:textSize="18sp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="4dp" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="32dp">

        <ImageButton
            android:id="@+id/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/play_button"
            android:src="@drawable/ic_play1" />

        <ImageButton
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_stop1"
            android:contentDescription="@string/stop_button"
            android:layout_marginLeft="16dp" />

    </LinearLayout>

</LinearLayout>

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值