Android Studio初学者实例:音乐播放器与Service学习

这篇具有很好参考价值的文章主要介绍了Android Studio初学者实例:音乐播放器与Service学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本次一个案例实现的一个简单的音乐播放器

用到的知识点最主要的几点是:Service、handler(实现音乐播放的进度条更新与图片旋转)以及用于播放音频的MediaPlayer

看一下案例效果:

音乐播放器service方式实现,Android初学者,Android学习与探索,学习,android音乐播放器service方式实现,Android初学者,Android学习与探索,学习,android

 由于Service是Android的四大组件之一,Activity、Service等等一个重要知识点就是生命周期的问题,以下图片借鉴于W3Cschool

图示中分别描述了通过startService与通过bindService来启动Service的生命周期,

可以看到无论是通过哪个方法,都必然的调用生命周期中的onCreate与onDesroy方法,这里简单的解释一下使用startService与bindService来启动Service的主要区别:startService与它的调用者无必然的联系,就是说当调用者结束了自己的生命周期, 但是只要不调用stopService,那么Service还是会继续运行bindService来说就是在一条船上

而在本案例中使用的bindService

音乐播放器service方式实现,Android初学者,Android学习与探索,学习,android

 

首先看一下

主界面

<?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:background="@drawable/beij"
    android:gravity="center"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/iv_music"
        android:layout_width="240dp"
        android:layout_height="240dp"
        android:layout_gravity="center_horizontal"
        android:layout_margin="15dp"
        android:src="@drawable/musics" />

    <SeekBar
        android:id="@+id/sb"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:thumb="@drawable/iconbiao"
        android:layout_marginTop="74dp" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="8dp"
        android:paddingRight="8dp">
        <TextView
            android:id="@+id/tv_progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00:00" />
        <TextView
            android:id="@+id/tv_total"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="00:00" />
    </RelativeLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_play"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_margin="8dp"
            android:layout_weight="1"
            android:background="@drawable/btn_bg_selector"
            android:text="播放音乐" />
        <Button
            android:id="@+id/btn_pause"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_margin="8dp"
            android:layout_weight="1"
            android:background="@drawable/btn_bg_selector"
            android:text="暂停播放" />
        <Button
            android:id="@+id/btn_continue_play"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_margin="8dp"
            android:layout_weight="1"
            android:background="@drawable/btn_bg_selector"
            android:text="继续播放" />
        <Button
            android:id="@+id/btn_exit"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_margin="8dp"
            android:layout_weight="1"
            android:background="@drawable/btn_bg_selector"
            android:text="退出" />
    </LinearLayout>
</LinearLayout>

其次是Activity代码

import android.animation.ObjectAnimator;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
    private static SeekBar sb;
    private static TextView tv_progress, tv_total;
    private ObjectAnimator animator;
    private MusicService.MusicControl musicControl;
    MyServiceConn conn;
    Intent intent;
    private boolean isUnbind = false;//记录服务是否被解绑
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    private void init() {
        tv_progress = (TextView) findViewById(R.id.tv_progress);
        tv_total = (TextView) findViewById(R.id.tv_total);
        sb = (SeekBar) findViewById(R.id.sb);
        findViewById(R.id.btn_play).setOnClickListener(this);
        findViewById(R.id.btn_pause).setOnClickListener(this);
        findViewById(R.id.btn_continue_play).setOnClickListener(this);
        findViewById(R.id.btn_exit).setOnClickListener(this);
        intent = new Intent(this, MusicService.class);//创建意图对象
        conn = new MyServiceConn();//创建服务连接对象
        bindService(intent, conn, BIND_AUTO_CREATE);  //绑定服务
        Log.i("MusicService","使用了bindService进行绑定服务");
        //为滑动条添加事件监听
        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean
                    fromUser) {                          //滑动条进度改变时,会调用此方法
                if (progress == seekBar.getMax()) { //当滑动条滑到末端时,结束动画
                    animator.pause();                   //停止播放动画
                }
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {//滑动条开始滑动时调用
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) { //滑动条停止滑动时调用
                //根据拖动的进度改变音乐播放进度
                int progress = seekBar.getProgress();//获取seekBar的进度
                musicControl.seekTo(progress);         //改变播放进度
            }
        });
        ImageView iv_music = (ImageView) findViewById(R.id.iv_music);
        animator = ObjectAnimator.ofFloat(iv_music, "rotation", 0f, 360.0f);
        animator.setDuration(10000);  //动画旋转一周的时间为10秒
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatCount(-1);  //-1表示设置动画无限循环
    }
    public static Handler handler = new Handler() {//创建消息处理器对象
        //在主线程中处理从子线程发送过来的消息
        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData(); //获取从子线程发送过来的音乐播放进度
            int duration = bundle.getInt("duration");                  //歌曲的总时长
            int currentPostition = bundle.getInt("currentPosition");//歌曲当前进度
            sb.setMax(duration);                //设置SeekBar的最大值为歌曲总时长
            sb.setProgress(currentPostition);//设置SeekBar当前的进度位置
            //歌曲的总时长
            int minute = duration / 1000 / 60;
            int second = duration / 1000 % 60;
            String strMinute = null;
            String strSecond = null;
            if (minute < 10) {              //如果歌曲的时间中的分钟小于10
                strMinute = "0" + minute; //在分钟的前面加一个0
            } else {
                strMinute = minute + "";
            }
            if (second < 10) {             //如果歌曲的时间中的秒钟小于10
                strSecond = "0" + second;//在秒钟前面加一个0
            } else {
                strSecond = second + "";
            }
            tv_total.setText(strMinute + ":" + strSecond);
            //歌曲当前播放时长
            minute = currentPostition / 1000 / 60;
            second = currentPostition / 1000 % 60;
            if (minute < 10) {             //如果歌曲的时间中的分钟小于10
                strMinute = "0" + minute;//在分钟的前面加一个0
            } else {
                strMinute = minute + "";
            }
            if (second < 10) {               //如果歌曲的时间中的秒钟小于10
                strSecond = "0" + second;  //在秒钟前面加一个0
            } else {
                strSecond = second + "";
            }
            tv_progress.setText(strMinute + ":" + strSecond);
        }
    };
    class MyServiceConn implements ServiceConnection { //用于实现连接服务
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            musicControl = (MusicService.MusicControl) service;
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    }
    private void unbind(boolean isUnbind){
        if(!isUnbind){                  //判断服务是否被解绑
            musicControl.pausePlay();//暂停播放音乐
            unbindService(conn);      //解绑服务
            Log.i("MusicService","使用了unbindService进行解绑");
        }
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_play:                //播放按钮点击事件
                musicControl.play();           //播放音乐
                animator.start();               //播放动画
                break;
            case R.id.btn_pause:               //暂停按钮点击事件
                musicControl.pausePlay();     //暂停播放音乐
                animator.pause();              //暂停播放动画
                break;
            case R.id.btn_continue_play:     //继续播放按钮点击事件
                musicControl.continuePlay(); //继续播放音乐
                animator.start();              //播放动画
                break;
            case R.id.btn_exit:                //退出按钮点击事件
                unbind(isUnbind);               //解绑服务绑定
                Log.i("MusicService","使用了unbind进行解绑");
                isUnbind = true;                //完成解绑服务
                finish();                         //关闭音乐播放界面
                break;
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbind(isUnbind); //解绑服务
        Log.i("MusicService","使用了unbind进行解绑");
    }
}

 然后就是最重要的Service组件

音乐播放器service方式实现,Android初学者,Android学习与探索,学习,android

 以及代码文章来源地址https://www.toymoban.com/news/detail-771402.html

public class MusicService extends Service {
    private MediaPlayer player;
    private Timer timer;
    public MusicService() {}

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i("MusicService","我是onUnbind方法");
        return super.onUnbind(intent);
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i("MusicService","我是onBind方法");
        return new MusicControl();
    }
    @Override
    public void onCreate() {
        Log.i("MusicService","我是onCreate方法");
        super.onCreate();
        player = new MediaPlayer();//创建音乐播放器对象
    }
    public void addTimer() {        //添加计时器用于设置音乐播放器中的播放进度条
        if (timer == null) {
            timer = new Timer();     //创建计时器对象
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    if (player == null) return;
                    int duration = player.getDuration();                //获取歌曲总时长
                    int currentPosition = player.getCurrentPosition();//获取播放进度
                    Message msg = MainActivity.handler.obtainMessage();//创建消息对象
                    //将音乐的总时长和播放进度封装至消息对象中
                    Bundle bundle = new Bundle();
                    bundle.putInt("duration", duration);
                    bundle.putInt("currentPosition", currentPosition);
                    msg.setData(bundle);
                    //将消息发送到主线程的消息队列
                    MainActivity.handler.sendMessage(msg);
                }
            };
            //开始计时任务后的5毫秒,第一次执行task任务,以后每500毫秒执行一次
            timer.schedule(task, 5, 500);
        }
    }
    class MusicControl extends Binder {
        public void play() {
            try {
                player.reset();//重置音乐播放器
                //加载多媒体文件
                player = MediaPlayer.create(getApplicationContext(), R.raw.music);
                player.start();//播放音乐
                addTimer();     //添加计时器
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        public void pausePlay() {
            player.pause();//暂停播放音乐
        }
        public void continuePlay() {
            player.start();//继续播放音乐
        }
        public void seekTo(int progress) {
            player.seekTo(progress);//设置音乐的播放位置
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("MusicService","我是onDestroy方法");
        if (player == null) return;
        if (player.isPlaying()) player.stop();//停止播放音乐
        player.release();//释放占用的资源
        player = null;//将player置为空
    }
}

到了这里,关于Android Studio初学者实例:音乐播放器与Service学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Studio初学者实例:ContentProvider读取手机通讯录

    该实验是通过ContentProvider读取手机通讯录 知识点包含了RecyclerView控件、UriMatcher、ContentResolver 先看效果,显示手机通讯录  首先是界面的布局代码 activity_main59.xml 其次是RecyclerView的item布局代码,其中使用了CardView是为了方便快捷的弄个圆角储来 main59_item.xml 一个联系人的实体

    2024年02月03日
    浏览(50)
  • Android Studio初学者实例:SQLite实验:绿豆通讯录

    本次实验是使用SQLite对一个通讯录表进行简单增删改查 以下是实验效果:  首先是继承SQLiteOpenHelper的数据库自定义类 对于此类必须继承于SQLiteOpenHelper ,当new创造该类的实例的时候会执行创建数据库以及表的操作,例如本代码中数据库名为itcast,数据库表名为informatoin。db

    2024年02月08日
    浏览(48)
  • Android Studio初学者实例:Fragment学习--仿美团外卖界面

    本次课程为Fragment为主题,课程的示例仿美团外卖界面,不同于底部导航栏的Fragment案例,此界面分为左侧切换与顶部切换。本文先是发布代码与效果,后续讲解将会在后续补充。先看看效果: 首先是布局文件代码:Activity布局:activity_main.xml: 首先父布局用的LinearLayout布局,

    2024年02月03日
    浏览(69)
  • git初学者使用教程(包含Android studio中git使用)

    参考博客 git地址 如: 点击创建后会出这个页面 我推荐使用这个部分命令行来设置仓库 在想要创建git仓库的文件夹右键打开Git Bash Here(前提是安装了git) 输入命令(每次输入一句) 3. 右键打开Git设置 在Git中就会出现用户信息(我电脑的Git用户是别人的,我没有修改) 先看

    2024年02月06日
    浏览(42)
  • R语言爬虫实例 初学者自用

    本文记录了使用rvest RSelenium 包进行爬虫与网页渲染的相关知识点及本人的编程操作过程。涉及到基本爬取操作、爬取缺失部分如何处理、操作网页过滤等步骤。 本人非计算机专业,如有措辞不慎敬请提出。 这学期为了凑学分,选了一门R语言的课,才发现R语言远比我们想象

    2024年02月02日
    浏览(45)
  • OpenCV实例解析(OpenCV初学者)

    一、计算机视觉 1.定义:给计算机安装上眼睛(照相机)和大脑(算法),让其能感知周围的环境。它是对生物视觉的一种模拟,通常的做法是通过对采集的图像或视频进行处理来获得相应场景的三维信息。 2.应用: 计算机科学和工程、信号处理、物理学、应用数学和统计学

    2024年02月08日
    浏览(45)
  • 在 Android 中使用 C/C++:初学者综合指南

    Java 作为一种编程语言,具有许多良好的功能,使其成为应用程序开发的首选语言。它独立于平台(因为虚拟机执行)、JIT 编译、多线程支持以及为程序员提供的富有表现力的简单语法。由于其与平台无关的特性,Java 包可以跨 CPU 架构移植,这使得库开发变得更加容易,从而

    2024年03月13日
    浏览(65)
  • Mac安装配置Visual Studio Code(vscode)以及Java环境详细教程(初学者必看)

    原本博主今天想继续给大家出Java接下来的教程,但是就在昨天我在配置vscode的时候遇到了一些问题,Windows系统的小伙伴配置起来肯定很方便,但是在Mac的小伙伴却显得十分无奈,所以我想给大家出一篇Mac的Visual Studio Code配置以及Java环境搭建教程! 博客主页:Jovy.的博客_CSDN博客-领

    2024年02月01日
    浏览(88)
  • 初学者不会写接口怎么办?微软Visual Studio 2022无脑式API接口创建——Swagger一键导入APIKit快速测试

    目录 VsualStudio2022各版本说明 社区版本具体说明 VisualStudio2022下载选项 VisualStudio2022启动样式 VisualStudio2022图标样式 VisualStudio2022初始内存消耗 创建项目ASP.NET Core项目 具体项目创建 编辑项目名称与项目位置 创建配置 创建API控制器 修改路由配置 配置跨域 准备创建接口 创建【

    2024年02月05日
    浏览(50)
  • Android Studio 实现音乐播放器

    🍅 文章末尾有获取完整项目源码方式 🍅         Android初学者开发第一个完整的实例项目应该就属《音乐播放器》了,项目包含SQLlit数据库的使用、listview、Fragment、等。话不多说先上成品: Android Studio 音乐播放器 图片效果展示: 1.启动页效果 2.登录页效果 3.注册页效果

    2024年02月06日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包