Android Studio新手开发第三十一天

利用MediaPlayer播放音频

        MediaPlayer 是 Android 系统中用于播放音频和视频文件的核心组件,它提供了一套完整的API,能够以较小的代价处理多媒体播放任务。它常用的方法说明如下:

        1.reset:重置播放器。

        2.prepare:准备播放。

        3.start:开始播放。

        4.pause:暂停播放。

        5.create:创建指定Uri或者资源编号的播放器。

        6.setDateSource:设置播放器数据来源的文件路径,它与create只需调用一次即可。

        7.setVolume:设置音量。它有两个参数,分别是左右声道的音量,取值范围0~1。

        8.setAudioStreamType:设置音频流的类型。

        9.setLooping:设置是否循环播放,true为循环播放,false为播放一次。

        10.isPlaying:判断是否正在播放。

        11.getCurrentPosition:获取当前播放进度所在位置。

        12.getDuration:获取播放时长,单位为毫秒。

        下面以播放音频为例,现在res/raw目录下添加一个音频文件,没有raw目录可以自行新建一个。示例代码如下,在布局文件中添加了三个按钮已经一个进度条。

<?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"
    tools:context=".MultiMedia.MediaPlayerActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/button_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="START"/>
    <Button
        android:id="@+id/button_pause"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="PAUSE"/>
    <Button
        android:id="@+id/button_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="STOP"/>

    <SeekBar
        android:id="@+id/seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

        部分Java代码如下,重点在于进度条监听器的逻辑处理代码,runnable的逻辑处理代码,按钮监听器的逻辑处理代码。



public class MediaPlayerActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button_start, button_pause, button_stop;
    private SeekBar seekbar;
    private MediaPlayer mediaPlayer;
    private boolean if_seek = false;
    private Time time;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_player);
        button_start = findViewById(R.id.button_start);
        button_pause = findViewById(R.id.button_pause);
        button_stop = findViewById(R.id.button_stop);
        seekbar = findViewById(R.id.seekbar);
        button_start.setOnClickListener(this);
        button_pause.setOnClickListener(this);
        button_stop.setOnClickListener(this);
        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                Log.d(TAG, "onProgressChanged: ");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStartTrackingTouch: ");
                if_seek = true;
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStopTrackingTouch: ");
                if (mediaPlayer != null) {
                    mediaPlayer.seekTo(seekBar.getProgress());
                }
                if_seek = false;
            }
        });

    }

    private Handler mHandler = new Handler();
    private Runnable mUpdateProgressRunnable = new Runnable() {
        @Override
        public void run() {
            if (mediaPlayer != null && !if_seek) { // 用户未拖动时才更新
                int currentPosition = mediaPlayer.getCurrentPosition(); // 获取当前播放位置[citation:5]
                seekbar.setProgress(currentPosition); // 更新SeekBar进度[citation:5]
                Log.d(TAG, "run: ");
            }
            //音乐播放结束,停止更新进度条,进度条重置
            if (mediaPlayer.getDuration() == seekbar.getProgress()){
                mHandler.removeCallbacks(mUpdateProgressRunnable);
                seekbar.setProgress(0);
            }
            // 每隔一定时间(如500毫秒)更新一次
            mHandler.postDelayed(this, 1000);
        }
    };

    // 开始更新进度
    private void startProgressUpdate() {
        mHandler.post(mUpdateProgressRunnable);
    }

    // 停止更新进度
    private void stopProgressUpdate() {
        mHandler.removeCallbacks(mUpdateProgressRunnable);
        mediaPlayer = null;
        seekbar.setMax(0);
    }

    //暂停更新进度
    private void pauseProgressUpdate() {
        mHandler.removeCallbacks(mUpdateProgressRunnable);
    }


    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.button_start) {
            if (mediaPlayer == null){
                mediaPlayer = MediaPlayer.create(this, R.raw.hsf);
                seekbar.setMax(mediaPlayer.getDuration());
            }
            if (!mediaPlayer.isPlaying()) {
                mediaPlayer.start();
                Log.d(TAG, "START");
            }
            startProgressUpdate();

        } else if (view.getId() == R.id.button_pause) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                Log.d(TAG, "PAUSE");
            }
            if (mediaPlayer == null){return;}
            pauseProgressUpdate();

        }else if (view.getId() == R.id.button_stop){
            mediaPlayer.stop();
            stopProgressUpdate();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.release();
        mediaPlayer = null;
    }
}

        效果图如下,点击对应的按钮实现音频的开始,暂停以及结束,点击进度条跳转至对应播放位置。注意在调用MediaPlayer的stop方法后若要开始音频则需要重新设置MediaPlayer的数据源。在退出APP时建议在onDestroy方法或者onStop方法上调用MediaPlayer的release方法释放系统资源或者在不使用MediaPlayer时调用该方法以减少系统资源占用。

利用MediaPlayer播放视频

        MediaPlayer除了可以用来播放音频,它也可以用来播放视频,不过它还需要配合其他视图来展示视频。利用MediaPlayer播放音频可以知道它是没有在页面上显示的,只有通过其他视图来控制播放等操作。而MediaPlayer播放视频就需要一个能够承载视频的视图SurfaceView。一般情况下可以使用视图VideoView直接展示视频,不过这种方式占用系统资源较大。利用MediaPlayer结合SurfaceView可以减少系统资源占用。示例代码如下,

<?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"
    tools:context=".MultiMedia.MediaPlayerActivity">

    <Button
        android:id="@+id/button_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="START" />

    <Button
        android:id="@+id/button_pause"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="PAUSE" />

    <Button
        android:id="@+id/button_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="STOP" />


    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:layout_marginTop="10dp"
        android:layout_gravity="center"/>

</LinearLayout>

        部分Java代码如下。




public class MediaPlayerActivity extends AppCompatActivity implements View.OnClickListener, SurfaceHolder.Callback {
    private Button button_start, button_pause, button_stop;
    private SurfaceView surfaceView;
    private MediaPlayer  mediaPlayer_surface;
    private SurfaceHolder surfaceHolder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_player);

        button_start = findViewById(R.id.button_start);
        button_pause = findViewById(R.id.button_pause);
        button_stop = findViewById(R.id.button_stop);
        surfaceView = findViewById(R.id.surfaceView);

        button_start.setOnClickListener(this);
        button_pause.setOnClickListener(this);
        button_stop.setOnClickListener(this);

        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
    }


    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.button_start) {

            mediaPlayer_surface.start();

        } else if (view.getId() == R.id.button_pause) {

            mediaPlayer_surface.pause();
        } else if (view.getId() == R.id.button_stop) {
            mediaPlayer_surface.stop();
        }
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
        mediaPlayer_surface = MediaPlayer.create(this, R.raw.hby);
        mediaPlayer_surface.setDisplay(surfaceHolder);
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
    }
}

效果图如下。

消息 优快云首页 发布文章 【数据驱动】【航空航结构的高效损伤检测技术】一种数据驱动的结构健康监测(SHM)方法,用于进行原位评估结构健康状态,即损伤位置和程度,在其中利用了选定位置的引导式兰姆波响应(Matlab代码实现) 99 100 摘要:会在推荐、列表等场景外露,帮助读者快速了解内容,支持一键将正文前 256 字符键入摘要文本框 0 256 AI提取摘要 您已同意GitCode 用户协议 和 隐私政策,我们会为您自动创建账号并备份文章至我的项目。 活动 话题 共 0 字 意见反馈内容概要:本文研究了在湍流气条件下,无人机发生发动机故障时的自动着陆问题,提出了一种多级适配控制策略,并通过Matlab进行仿真代码实现。该策略旨在提升无人机在极端环境下的安全着陆能力,重点解决了气流干扰与动力失效双重挑战下的姿态稳定与轨迹规划问题。研究涵盖了故障检测、控制系统重构、自适应调整及安全着陆路径生成等关键技术环节,验证了所提方法在复杂气象条件下的有效性与鲁棒性。; 适合人群:具备一定无人机控制、自动控制理论基础及Matlab编程能力的科研人员、研究生以及从事航空航、智能控制领域的工程技术人员。; 使用场景及目标:①用于无人机故障应急控制系统的设计与仿真;②支持复杂环境下无人机动态响应分析与控制算法开发;③为飞行器自主安全着陆技术提供解决方案参考。; 阅读建议:建议结合Matlab代码与控制理论深入理解多级适配机制,重点关注故障识别与控制切换逻辑,可通过修改仿真参数测试不同湍流强度下的系统表现,以加深对算法鲁棒性的认识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值