安卓第五次实训

创建应用程序常量接口保存广播频道常量
在音乐播放器应用程序类里添加两个属性
– currentMusicIndex
– currentPosition
– 访问它们的方法
创建MusicPlayService来完成音乐的播放、暂停以及切换工作
利用广播来实现MainActivity与MusicPlayService之间的通信

涉及知识点
标签(TextView)
按钮(Button)
媒体播放器(MediaPlayer)
进度条(ProgressBar)
线程(Thread)
消息处理器(Handler)
列表视图(ListView)
异步任务(AsyncTask)
应用程序(Application)
服务(Service)
广播接收者(BroadcastReceiver)

创建安卓应用
在这里插入图片描述
将图片素材拷贝到drawable目录与mipmap目录
在这里插入图片描述
创建按钮背景图片选择器
在这里插入图片描述
在项目清单文件里授权访问外置存储卡,设置应用程序图标
在这里插入图片描述
主布局资源文件activity_main.xml
在这里插入图片描述
字符串资源文件strings.xml
在这里插入图片描述
创建音乐名列表项模板music_name_list_item.xml
在这里插入图片描述
在这里插入图片描述

创建ui子包,将MainActivity拖进ui子包
在这里插入图片描述
创建entity子包,在里面创建音乐实体类 - Music

在这里插入图片描述
在这里插入图片描述
创建app子包,在里面创建音乐播放器应用程序类 - MusicPlayerApplication
在这里插入图片描述
在这里插入图片描述
创建adapter子包,在里面创建音乐适配器 - MusicAdapter
在这里插入图片描述
**在app子包常见应用程序常量接口 - AppConstants
在这里插入图片描述
package com.example.v05.app;

/**

  • 功能:应用程序常量接口
  • 作者:王丹婷
  • 日期:2021年01月06日
    */
    interface AppConstants {
    String TAG = “net.hw.sdcard_musicplayer_v05”; // 应用程序标记
    String INTENT_ACTION_PREVIOUS = TAG + “.intent.action.PREVIOUS”; // 广播频道常量:播放上一首
    String INTENT_ACTION_PLAY = TAG + “.intent.action.PLAY”; // 广播频道常量:播放
    String INTENT_ACTION_PLAY_OR_PAUSE = TAG + “.intent.action.PLAY_OR_PAUSE”; // 广播频道常量:播放或暂停
    String INTENT_ACTION_NEXT = TAG + “.intent.action.NEXT”; // 广播频道常量:播放下一首
    String INTENT_ACTION_UPDATE_PROGRESS = TAG + “.intent.action.UPDATE_PROGRESS”; // 广播频道常量:更新播放进度
    String CONTROL_ICON = “control_icon”; // 控制图标名称常量
    String DURATION = “duration”; // 播放时长名称常量
    String CURRENT_POSITION = “current_position”; // 当前播放位置名称常量
    }

创建service子包,在里面创建音乐播放服务类 - MusicPlayService
在这里插入图片描述
创建音乐广播接收器内部类 - MusicReceiver()
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

主界面
package com.example.v05.ui;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.example.v05.R;
import java.util.List;

/**

  • 功能:基于存储卡音乐播放器v0.5

  • 王丹婷
    */
    public class MainActivity extends AppCompatActivity implements AppConstants {

    private String musicName; // 音乐文件名
    private TextView tvMusicName; // 音乐名标签
    private Button btnPlayOrPause; // 播放|暂停按钮
    private MusicReceiver receiver; // 音乐广播接收器
    private TextView tvCurrentPosition; // 显示当前播放位置的标签
    private TextView tvDuration; // 显示音乐播放时长的标签
    private ProgressBar pbMusicProgress; // 音乐播放进度条
    private ListView lvMusicName; // 音乐名列表控件
    private List musicList; // 音乐列表(数据源)
    private MusicAdapter adapter; // 音乐适配器
    private MusicPlayerApplication app; // 音乐播放器应用程序对象
    private ProgressBar pbScanMusic; // 扫描存储卡音乐进度条
    private TextView tvScanMusic; // 扫描存储卡音乐标签(提示用户耐心等待)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //利用布局资源文件设置用户界面
    setContentView(R.layout.activity_main);

     // 通过资源标识符获取控件实例
     lvMusicName = findViewById(R.id.lvMusicName);
     tvMusicName = findViewById(R.id.tvMusicName);
     btnPlayOrPause = findViewById(R.id.btnPlayOrPause);
     tvCurrentPosition = findViewById(R.id.tvCurrentPosition);
     tvDuration = findViewById(R.id.tvDuration);
     pbMusicProgress = findViewById(R.id.pbMusicProgress);
     pbScanMusic = findViewById(R.id.pbScanMusic);
     tvScanMusic = findViewById(R.id.tvScanMusic);
    
     //获取音乐播放器应用程序对象
     app = (MusicPlayerApplication) getApplication();
    
     // 定义存储读写权限数组
     String[] PERMISSIONS_STORAGE = {
             Manifest.permission.READ_EXTERNAL_STORAGE,
             Manifest.permission.WRITE_EXTERNAL_STORAGE
     };
     // 检查是否有读权限
     final int permission = ActivityCompat.checkSelfPermission(this, PERMISSIONS_STORAGE[0]);
     // 如果没有授权,那么就请求读权限
     if (permission != PackageManager.PERMISSION_GRANTED) {
         ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 0);
         return;
     }
    
     //执行填充音乐列表的异步任务
     new FillMusicListTask().execute();
    
     // 给音乐列表控件注册监听器
     lvMusicName.setOnItemClickListener(new AdapterView.OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
             // 获取音乐索引
             app.setCurrentMusicIndex(position);
             // 当前播放位置归零
             app.setCurrentPosition(0);
             //获取音乐名
             musicName = app.getMusicList().get(position).getMusicName();
             // 设置音乐名标签内容,去掉路径和扩展名
             tvMusicName.setText("No." + (app.getCurrentMusicIndex() + 1) + " " + musicName.substring(
                     musicName.lastIndexOf("/") + 1, musicName.lastIndexOf(".")));
             //创建意图
             Intent intent = new Intent();
             //设置广播频道
             intent.setAction(INTENT_ACTION_PLAY);
             //按意图发送广播
             sendBroadcast(intent);
         }
     });
    
     //创建音乐广播接收器
     receiver = new MusicReceiver();
     //创建意图过滤器
     IntentFilter filter = new IntentFilter();
     //通过意图过滤器添加广播频道
     filter.addAction(INTENT_ACTION_UPDATE_PROGRESS);
     //注册音乐广播接收器
     registerReceiver(receiver, filter);
    

    }

    /**

    • 填充音乐列表异步任务类
      /
      private class FillMusicListTask extends AsyncTask<Void, Integer, Void> {
      /
      *

      • 耗时工作执行前
        */
        @Override
        protected void onPreExecute() {
        super.onPreExecute();
        // 显示扫描音乐进度条
        pbScanMusic.setVisibility(View.VISIBLE);
        // 显示扫描音乐标签
        tvScanMusic.setVisibility(View.VISIBLE);
        }

      @Override
      protected Void doInBackground(Void… voids) {
      // 获取音乐列表
      musicList = app.getMusicList();
      // 故意耗时,要不然扫描太快结束
      for (long i = 0; i < 2000000000; i++) {
      }
      return null;
      }

      /**

      • 耗时工作执行后

      • @param aVoid
        */
        @Override
        protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // 隐藏扫描音乐进度条
        pbScanMusic.setVisibility(View.GONE);
        // 隐藏扫描音乐标签
        tvScanMusic.setVisibility(View.GONE);

        // 判断音乐列表是否有元素
        if (musicList.size() > 0) {
        // 创建音乐适配器
        adapter = new MusicAdapter(MainActivity.this, musicList);
        // 给音乐列表控件设置适配器
        lvMusicName.setAdapter(adapter);
        // 获取当前要播放的音乐名(默认是音乐播放列表的第一首)
        musicName = musicList.get(0).getMusicName();
        // 设置音乐名标签内容,去掉路径和扩展名,添加序号
        tvMusicName.setText(“No.” + (app.getCurrentMusicIndex() + 1) + " " + musicName.substring(
        musicName.lastIndexOf("/") + 1, musicName.lastIndexOf(".")));
        //创建意图,用于启动音乐播放服务
        Intent intent = new Intent(MainActivity.this, MusicPlayService.class);
        //按意图启动服务
        startService(intent);
        } else {
        // 提示用户没有音乐文件
        Toast.makeText(MainActivity.this, “外置存储卡上没有音乐文件!”, Toast.LENGTH_SHORT);
        }
        }
        }

    /**

    • 音乐广播接收器
      */
      private class MusicReceiver extends BroadcastReceiver {
      @Override
      public void onReceive(Context context, Intent intent) {
      //获取广播频道
      String action = intent.getAction();
      //判断广播频道是否为空
      if (action != null) {
      //根据不同广播频道执行不同操作
      if (INTENT_ACTION_UPDATE_PROGRESS.equals(action)) {
      //获取播放时长
      int duration = intent.getIntExtra(DURATION, 0);
      //获取播放控制图标
      int controlIcon = intent.getIntExtra(CONTROL_ICON,
      R.drawable.play_button_selector);
      //计算进度值
      int progress = app.getCurrentPosition() * 100 / duration;
      //获取音乐名
      musicName = app.getMusicList().get(app.getCurrentMusicIndex()).getMusicName();
      //设置正在播放的文建明(去掉扩展名)
      tvMusicName.setText(“No.” + (app.getCurrentMusicIndex() + 1) + " "
      + musicName.substring(musicName.lastIndexOf("/") + 1, musicName.lastIndexOf(".")));
      //设置播放进度值标签
      tvCurrentPosition.setText(app.getFormatTime(app.getCurrentPosition()));
      //设置播放时长标签
      tvDuration.setText(app.getFormatTime(duration));
      //设置播放进度条的进度值
      pbMusicProgress.setProgress(progress);
      //设置【播放|暂停】按钮显示的图标
      btnPlayOrPause.setBackgroundResource(controlIcon);
      }
      }
      }
      }

    /**

    • 上一首按钮单击事件处理方法
    • @param view
      */
      public void doPrevious(View view){
      //创建意图
      Intent intent = new Intent();
      //设置广播频道
      intent.setAction(INTENT_ACTION_PREVIOUS);
      //按意图发送广播
      sendBroadcast(intent);
      }

    /**

    • 下一首按钮单击事件处理方法
    • @param view
      */
      public void doNext(View view){
      //创建意图
      Intent intent = new Intent();
      //设置广播频道
      intent.setAction(INTENT_ACTION_NEXT);
      //按意图发送广播
      sendBroadcast(intent);
      }

    /**

    • 播放|暂停按钮单击事件处理方法
    • @param view
      */
      public void doPlayOrPause(View view) {
      //创建意图
      Intent intent = new Intent();
      //设置广播频道
      intent.setAction(INTENT_ACTION_PLAY_OR_PAUSE);
      //按意图发送广播
      sendBroadcast(intent);
      }

    /**

    • 销毁回调方法,释放资源
      */
      @Override
      protected void onDestroy() {
      super.onDestroy();
      //停止音乐播放器
      stopService(new Intent(MainActivity.this, MusicPlayService.class));
      //注销广播接收器
      unregisterReceiver(receiver);
      }

    private class MusicAdapter {
    }

    private class MusicPlayerApplication {
    }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值