首页 > 其他分享 >模仿网易音乐播放器

模仿网易音乐播放器

时间:2024-08-30 11:56:01浏览次数:15  
标签:播放器 网易 layout Service public import android id 模仿

要求:

1.实验报告要完整,即要有实验要求与目的、实验内容与步骤(必要流程图或活动图、代码)、运行结果与分析、实验体会与收获;

2.代码要有必要的注释;

3.标题为四号黑体,其他为宋体小四号,行间距为单倍行间距,纸张大小为A4;

4.考核项目

考核项目

格式与完成性

实验内容

实验结果与分析

实验体会与收获

总成绩

权重

20%

60%

10%

10%

100%

得分

  • 实验目的

1.了解服务的概述,能够说出什么是服务;

2.掌握服务的创建方式,能够独立创建一个服务;

3. 熟悉服务的生命周期,能够阐述服务生命周期中的方法;

4.掌握服务的两种启动方式,能够实现服务的启动与关闭功能;

5.掌握服务的通信,能够完成仿网易音乐播放器案例。

  • 实验工具

Android studio。

  • 实验内容

运行效果图如下:

  1. 完成上图的布局;

  2. 点击“播放”按钮、“暂停”按钮、“继续”按钮完成相应功能。

  • 实验过程(含代码)

   activity_main.xml: <?xml version="1.0" encoding="utf-8"?>

<LinearLayout 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"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:gravity="center"

    android:background="@drawable/music_bg"

    tools:context=".MainActivity">



    <RelativeLayout

        android:layout_width="match_parent"

        android:layout_height="160dp">

        <RelativeLayout

            android:layout_width="300dp"

            android:layout_height="70dp"

            android:id="@+id/rl_title"

            android:layout_centerHorizontal="true"

            android:background="@drawable/title_bg"

            android:gravity="center_horizontal"

            android:paddingLeft="80dp">



            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:id="@+id/tv_music_title"

                android:layout_marginTop="8dp"

                android:text="体面"

                android:textSize="12sp"

                android:textStyle="bold"

                android:textColor="@color/black"/>

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:id="@+id/tv_type"

                android:layout_marginTop="4dp"

                android:layout_below="@id/tv_music_title"

                android:layout_alignLeft="@id/tv_music_title"

                android:text="流行音乐"

                android:textSize="10dp"/>

            <SeekBar

                android:layout_width="150dp"

                android:layout_height="wrap_content"

                android:id="@+id/sb"

                android:layout_below="@+id/rl_time"

                android:layout_alignParentBottom="true"

                android:thumb="@null"/>

            <RelativeLayout

                android:layout_width="150dp"

                android:layout_height="wrap_content"

                android:layout_marginTop="4dp"

                android:id="@+id/rl_time"

                android:layout_below="@id/tv_type">

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:id="@+id/tv_progress"

                    android:text="00:00"

                    android:textSize="10dp"/>

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:id="@+id/tv_total"

                    android:layout_alignParentRight="true"

                    android:text="00:00"/>



            </RelativeLayout>

        </RelativeLayout>

        <LinearLayout

            android:layout_width="340dp"

            android:layout_height="90dp"

            android:layout_below="@id/rl_title"

            android:layout_centerHorizontal="true"

            android:background="@drawable/btn_bg"

            android:gravity="center_vertical"

            android:paddingLeft="120dp"

            android:paddingRight="10dp">

            <Button

                android:layout_width="0dp"

                android:layout_height="55dp"

                android:layout_margin="4dp"

                android:id="@+id/btn_play"

                android:layout_weight="1"

                android:background="@drawable/btn_bg_selector"

                android:text="播放"

                android:textSize="10sp"/>

            <Button

                android:layout_width="0dp"

                android:layout_height="55dp"

                android:id="@+id/btn_pause"

                android:layout_margin="4dp"

                android:layout_weight="1"

                android:background="@drawable/btn_bg_selector"

                android:text="暂停"

                android:textSize="10sp"/>

            <Button

                android:layout_width="0dp"

                android:layout_height="55dp"

                android:id="@+id/btn_continue_play"

                android:layout_margin="4dp"

                android:layout_weight="1"

                android:background="@drawable/btn_bg_selector"

                android:text="继续"

                android:textSize="10sp"/>

            <Button

                android:layout_width="0dp"

                android:layout_height="55dp"

                android:id="@+id/btn_exit"

                android:layout_margin="4dp"

                android:layout_weight="1"

                android:background="@drawable/btn_bg_selector"

                android:text="退出"

                android:textSize="10sp"/>

        </LinearLayout>

        <ImageView

            android:layout_width="100dp"

            android:layout_height="100dp"

            android:id="@+id/iv_music"

            android:layout_centerVertical="true"

            android:layout_marginLeft="35dp"

            android:layout_marginBottom="50dp"

            android:src="@drawable/img_music"/>

    </RelativeLayout>

</LinearLayout>
btn_bg_selector.xml: <?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" >

        <shape android:shape="rectangle">

            <corners android:radius="3dp"/>

            <solid android:color="#d4d4d4"/>

        </shape>

    </item>

    <item android:state_pressed="false" >

        <shape android:shape="rectangle">

            <corners android:radius="3dp"/>

            <solid android:color="#ffffff" />

        </shape>

    </item>

</selector>
MainActivity.java:     package com.example.musicdemo;



import androidx.annotation.NonNull;

import androidx.appcompat.app.AppCompatActivity;



import android.animation.ObjectAnimator;

import android.animation.ValueAnimator;

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.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=findViewById(R.id.tv_progress);

        tv_total=findViewById(R.id.tv_total);

        sb=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);

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

                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(@NonNull Message msg) {

            Bundle bundle=msg.getData();

            int duration=bundle.getInt("duration");

            int currentPosition=bundle.getInt("currentPosition");

            sb.setMax(duration);

            sb.setProgress(currentPosition);

            int minute=duration/1000/60;

            int second=duration/1000%60;

            String strMinute=null;

            String strSecond=null;

            if (minute<10){

                strMinute="0"+minute;// //如果歌曲时间中的分钟数小于10在分钟前+0



            }else {

                strMinute=minute+"";

            }

            if (second<10){

                strSecond="0"+second;// //如果歌曲时间中的秒数小于10在秒钟前+0

            }else {

                strSecond=second+"";

            }

            tv_total.setText(strMinute+":"+strSecond);

            minute=currentPosition/1000/60;

            second=currentPosition/1000%60;

            if (minute<10){

                strMinute="0"+minute;

            }else {

                strMinute=minute+"";

            }

            if (second<10){

                strSecond="0"+second;

            }else {

                strSecond=second+"";

            }

            tv_progress.setText(strMinute+":"+strSecond);

            super.handleMessage(msg);

        }

    };

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

            stopService(intent);

        }

    }

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

                isUnbind=true;

                finish();

                break;

        }

    }



    @Override

    protected void onDestroy() {

        super.onDestroy();

        unbind(isUnbind);

    }

}

AndroidMainfest.xml: <?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.musicdemo">



    <application

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:roundIcon="@mipmap/ic_launcher_round"

        android:supportsRtl="true"

        android:theme="@style/Theme.Musicdemo">

        <activity android:name=".MainActivity">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />



                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <service android:name=".MusicService"

            android:enabled="true"

            android:exported="true"/>

    </application>



</manifest>

           
自定义MediaServer.java类,继承Server,然后在AndroidManifest里添加
MusicService.java: package com.example.musicdemo;



import android.app.Service;

import android.content.Intent;

import android.media.MediaPlayer;

import android.os.Binder;

import android.os.Bundle;

import android.os.IBinder;

import android.os.Message;



import androidx.annotation.Nullable;



import java.util.Timer;

import java.util.TimerTask;



public class MusicService extends Service {

    private MediaPlayer player;

    private Timer timer;

    public MusicService(){

    }

    @Nullable

    @Override

    public IBinder onBind(Intent intent) {

        return new MusicControl();

    }



    @Override

    public void 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);

                }

            };

            timer.schedule(task,5,500);  
//开始计时任务5毫秒后,第一次执行task任务,以后每500毫秒执行一次

        }

    }

    class MusicControl extends Binder{

        public void play(){

            try{

                player.reset();  //重置音乐播放器

                player=MediaPlayer.create(getApplicationContext(),R.raw.music);

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

        if (player==null)return;

        if (player.isPlaying())player.stop();  //停止播放

        player.release();  //释放占用资源

        player=null;  //player置为空

    }

}
  • 运行结果与分析

播放中:

暂停:

继续:

退出:

  • 实验体会与收获

本实验学习了什么是服务,服务种类有哪些,怎么实现服务,了解服务的两种启动方式并采用第二种服务启动方式

Service:

是android四大组件之一,主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务。必要的时候我们甚至可以在程序退出的情况下,让Service在后台继续保持运行状态。而Service是运行在主线程里的,如果直接在Service中处理一些耗时的逻辑,就会导致程序ANR,所以需要另外开启子线程来处理。

两种模式: startService()/bindService()

.Service的第一种启动方式

采用start的方式开启服务

使用Service的步骤:

1.定义一个类继承Service

2.在Manifest.xml文件中配置该Service

3.使用Context的startService(Intent)方法启动该Service

4.不再使用时,调用stopService(Intent)方法停止该服务

使用这种start方式启动的Service的生命周期如下:

onCreate() --> onStartCommand() (onStart()方法已过时) --> onDestory()

Service的第二种启动方式

采用bind的方式开启服务

使用Service的步骤:

1.定义一个类继承Service

2.在Manifest.xml文件中配置该Service

3.使用Context的bindService(Intent,ServiceConnection,int)方法启动该Service

4.不再使用时,调用unbindService(ServiceConnection)方法停止该服务

使用这种start方式启动的Service的生命周期如下:

onCreate() -->> onBind() --> onUnbind() -->> onDestory()

标签:播放器,网易,layout,Service,public,import,android,id,模仿
From: https://blog.csdn.net/2301_80950699/article/details/141714435

相关文章

  • VB版本电子琴简谱播放器代码QZQ-2024-8-30
    OptionExplicitPrivateDeclareSubSleepLib“kernel32”(ByValdwMillisecondsAsLong)PrivateConstsColr=&H4000&DimmmAsVariant'不再使用NewsMidi,而是使用Variant类型,可以存储不同类型的数据PrivateDeclareFunctionmidiOutCloseLib“winmm.dl......
  • VB版本MIDI钢琴简谱播放器全代码QZQ-2024-8-30
    PrivateDeclareFunctionGetKeyState%Lib“user32”(ByValnVirtKeyAsLong)PrivateDeclareSubSleepLib“kernel32”(ByValdwMillisecondsAsLong)PrivatesuduAsIntegerPrivateConstVK_LBUTTON&=&H1PrivateisOgainAsBoolean'是否重复按键Pri......
  • 操作指南:在Ubuntu 24.04上安装网易邮箱大师
    网易邮箱大师是一款功能强大的邮箱客户端,支持多种邮箱的管理,提供了便利的邮件收发、日历管理和任务跟踪等功能。对于使用Ubuntu的用户而言,虽然Linux系统上的邮箱客户端有所限制,但我们仍然希望能够在这个开源的环境中实现高效的邮件管理。本文将详细介绍如何在Ubuntu24.04上安......
  • 游戏AI中的模仿学习
    模仿学习在游戏AI中的应用已经逐渐成为提升游戏智能和玩家体验的重要技术。通过模仿人类玩家的行为,游戏AI可以表现出更加智能、自然的决策和操作能力,使得游戏更加富有挑战性和趣味性。以下是关于游戏AI中模仿学习的详细探讨。1.什么是模仿学习?模仿学习(ImitationLearning)是......
  • 【Sceneform-EQR】scenefrom-eqr中的几种背景实现(不仅用于AR、三维场景,在图片、视频
    Sceneform-EQR简介Sceneform-EQR是EQ基于sceneform(filament)扩展的一个用于安卓端的三维渲染器。相关链接Git仓库Sceneform-EQR码云EQ-Renderer的示例工程EQ-R相关文档文档目录CSDN专栏几种背景实现方式示例工程Sceneform-EQR实现透明背景代码样例示例地址:Sc......
  • 【持续更新】Mχ Plaayer Pro 1.86.0安卓知名播放器最新免费高级修改版
    MχPlaayerProMOD版本免费APK,专为安卓手机和平板打造。这是一款功能强大的视频播放器,具备先进的硬件加速技术和字幕支持功能。•硬件加速-新增HW+解码器帮助更多视频格式实现硬件加速。•多核心解码-MχPlaayer是首款支持多核心解码的安卓视频播放器。测......
  • MPG是什么格式?MPG格式用什么播放器打开?
    MPG(MPEG)是一种常用的视频格式,广泛应用于存储和传输视频数据。由于其历史久远且兼容性好,许多不同的播放器都能支持MPG格式的播放。本教程将向你介绍几种常见的能够播放MPG格式视频的播放器,并指导你如何使用它们。什么是MPG格式?MPG文件通常包含使用MPEG-1或MPEG-2标准压缩的......
  • 出手自适应影视网站 带采集整合无广告播放器
    出手自适应影视网站 带采集整合无广告播放器自适应影视网站源码介绍自适应影视网站源码是一个专为影视爱好者设计的网站模板,它能够自动适应不同设备的屏幕大小,提供流畅的观影体验。该网站集成了采集功能,可以自动抓取网络上的影视资源,并通过无广告播放器进行播放,为用户提供纯......
  • QuickTime Player媒体播放器软件安装包下载地址及安装教程!
    软件介绍QuickTimePlayer中文版是苹果公司开发的一款功能强大的媒体播放器。除了播放MP3外,还支持MIDI播放,并且可以收听/收看网络播放,支持HTTP、RTP和RTSP标准。该软件还支持主要的图像格式,比如:JPEG、BMP、PICT、PNG和GIF。软件:QuickTime版本:7.7.9语言:简体中文大小:40.1M安......
  • 用C#写一个随机音乐播放器
    form1中namespce里的代码如下publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){stringfolder=textBox1.Text;stringfolderPath......