手机影音第五天 视频列表的显示与播放以及个别牌子手机播放的问题

先展示下本次做好的效果:

接着上次的说,上次说到了去获取手机里的视频信息,下面就用listview来展示视频列表与调用系统播放器来播放视频。

1、根据获取到的视频列表,去设置适配器Adapter,然后利用前面写的listview的例子,来展示数据,这个就不详细说明了。

2、点击单个listview的数据,来监听其事件,在监听的方法里,去调取播放方法。

2.1利用隐式意图去调用所有符合要求的播放器。

    class MyOnItemClickListener implements AdapterView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //根据position获取list中的结果
            MediaItem item = mediaList.get(position);
            //Toast.makeText(context,"当前视频名称"+item.getName(),Toast.LENGTH_SHORT).show();

            //调取系统播放器  ---隐式意图
            Intent intent=new Intent(Intent.ACTION_VIEW);
           Uri uri=Uri.parse("file://"+item.getData());
            intent.setDataAndType(uri,"video/mp4"); //所有格式
            context.startActivity(intent);
        }
    }

在这里就是要注意了,网上有的文章里,是这样写的

             Intent intent=new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(item.getData(),"video/mp4"); //所有格式
            context.startActivity(intent);

这样写就导致无法弹出系统里符合播放条件的播放器,需要在URI做下处理,在前面加上file://这样才行。

2.2 利用显示意图,直接调用mediaplayer来播放,自己封装了一下mediaplayer,以后可以自己定义播放器的样式,甚至打广告。这个SystemVideoPlayer是自己写的类。

Intent intent=new Intent(context,SystemVideoPlayer.class);
Uri uri=Uri.parse("file://"+item.getData());
intent.setDataAndType(uri,"video/mp4"); //所有格式
context.startActivity(intent);

2.3 自定义的systemVideoPlayer,注意这个类继承Activity,要去AndroidManifext.xml里注册

在这个类里,去监听videoView的准备播放状态,播放出错状态,播放完成状态,并且设置控制器来控制视频的暂停,快进,快退功能

package com.yuanlp.mobileplayer.activity;

import android.app.Activity;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;

import com.yuanlp.mobileplayer.R;

/**
 * Created by 原立鹏 on 2017/7/16.
 * 系统播放器
 * 注意去Manifext.xml里注册
 */

public class SystemVideoPlayer extends Activity{
    private VideoView videoview;
    private Uri uri;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.system_video_player); //自定义的播放器样式,暂时为简单版    
        videoview= (VideoView) findViewById(R.id.videoview);

        //得到播放地址,从intent中获取
        uri = getIntent().getData();
        if (uri!=null){
            videoview.setVideoURI(uri);
        }

        //准备好的监听,监听是否视频准备好
        videoview.setOnPreparedListener(new MyOnPreparedListener());
        //播放出错了的监听
        videoview.setOnErrorListener(new MyOnErrorListener());
        //播放完成的监听
        videoview.setOnCompletionListener(new MyOnCompletionListener());

        //设置控制面板,系统自带的
        videoview.setMediaController(new MediaController(this));

    }
    /**
     * 准备好播放时的监听
     */
    class MyOnPreparedListener implements MediaPlayer.OnPreparedListener {

        @Override
        public void onPrepared(MediaPlayer mp) {
            videoview.start(); //开始播放

        }
    }

    /**
     * 播放出错
     */
    class MyOnErrorListener implements MediaPlayer.OnErrorListener {

        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            //出错后,系统会自动提示播放出错,同时自己也弹一个吐司
            Toast.makeText(SystemVideoPlayer.this,"播放出错",Toast.LENGTH_SHORT).show();
            return false;
        }
    }

    /**
     * 播放完成的监听
     */
    class MyOnCompletionListener implements MediaPlayer.OnCompletionListener {

        @Override
        public void onCompletion(MediaPlayer mp) {
            Toast.makeText(SystemVideoPlayer.this, "播放完成", Toast.LENGTH_SHORT).show();
        }
    }
}

2.4 播放器样式布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
                android:gravity="center"
                android:background="#000000"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <VideoView
        android:layout_centerInParent="true"
        android:id="@+id/videoview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

3、VideoPager的完整代码

package com.yuanlp.mobileplayer.pager;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.yuanlp.mobileplayer.R;
import com.yuanlp.mobileplayer.activity.SystemVideoPlayer;
import com.yuanlp.mobileplayer.adapter.MyAdapter;
import com.yuanlp.mobileplayer.base.BasePager;
import com.yuanlp.mobileplayer.bean.MediaItem;
import com.yuanlp.mobileplayer.utils.LogUtil;
import com.yuanlp.mobileplayer.utils.Utils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 原立鹏 on 2017/7/13.
 * 本地视频的页面
 */

public class VideoPager extends BasePager {

    private ListView listview;
    private TextView nomedia;
    private ProgressBar pb_loding;
    private Utils utils;

    //保存所有的媒体信息的集合
    private List<MediaItem> mediaList;

    private MyAdapter myAdapter;

    public VideoPager(Context context) {
        super(context);
        utils=new Utils();

    }

    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mediaList!=null&&mediaList.size()>0){
                //有数据
                //设置适配器
                myAdapter=new MyAdapter(context,mediaList);
                listview.setAdapter(myAdapter);
               //Toast.makeText(context,"有数据",Toast.LENGTH_SHORT).show();
                nomedia.setVisibility(View.GONE);

            }else{
                //没有数据
                //文本显示
                Toast.makeText(context,"没有数据",Toast.LENGTH_SHORT).show();

            }
            pb_loding.setVisibility(View.GONE);
            //progressbar隐藏
        }
    };
    /**
     * 强制子类实现特定的效果
     *
     * @return
     */
    @Override
    public View initView() {
        LogUtil.e("本地视频被初始化了");
       View view=View.inflate(context, R.layout.video_pager,null);
        listview= (ListView) view.findViewById(R.id.listview);
        nomedia= (TextView) view.findViewById(R.id.tv_nomedia);
        pb_loding= (ProgressBar) view.findViewById(R.id.pb_loading);

        //设置listview的item的点击事件
        listview.setOnItemClickListener(new MyOnItemClickListener());

        return view;
    }

    @Override
    public void initData() {
        super.initData();
        LogUtil.e("本地视频页面的数据被初始化了");
        //加载本地数据
        getDataFromLocal();

    }

    class MyOnItemClickListener implements AdapterView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //根据position获取list中的结果
            MediaItem item = mediaList.get(position);
            //Toast.makeText(context,"当前视频名称"+item.getName(),Toast.LENGTH_SHORT).show();

//            //调取系统播放器  ---隐式意图
//            Intent intent=new Intent(Intent.ACTION_VIEW);
//           Uri uri=Uri.parse("file://"+item.getData());
//            intent.setDataAndType(uri,"video/mp4"); //所有格式
//            context.startActivity(intent);

            //调用自己写的播放器 ---显示意图

            Intent intent=new Intent(context,SystemVideoPlayer.class);
            Uri uri=Uri.parse("file://"+item.getData());
            intent.setDataAndType(uri,"video/mp4"); //所有格式
            context.startActivity(intent);

        }
    }

    /**
     * 从本地sd卡获取数据,有2中办法
     * 1、遍历sd卡,根据后缀名
     * 2、从内容提供者中获取,系统有自己会去扫描所有media信息。
     * 3/6.0后的系统,需要加上动态权限
     */
    private void getDataFromLocal() {
        mediaList=new ArrayList<>();

        new Thread(){
            @Override
            public void run() {
                super.run();
                SystemClock.sleep(2000);
                //根据上下文,去获取内容解析者
                ContentResolver resolver = context.getContentResolver();

                Uri uri= MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                String[] objs={
                       MediaStore.Video.Media.DISPLAY_NAME, //视频文件名称
                        MediaStore.Video.Media.DURATION,  //视频时长
                        MediaStore.Video.Media.SIZE, //文件大小
                        MediaStore.Video.Media.DATA, //视频的绝对地址
                        MediaStore.Video.Media.ARTIST,  //歌曲的演唱者,艺术家(音频可能会有该字段)
                };
                Cursor cursor = resolver.query(uri, objs, null, null, null);
                if (cursor!=null){
                    while(cursor.moveToNext()){
                        MediaItem item=new MediaItem();

                        String name=cursor.getString(0); //名称
                        item.setName(name);

                        long duration=cursor.getLong(1); //时长
                        item.setDuration(duration);

                        long size=cursor.getLong(2); //视频大小
                        item.setSize(size);

                        String data=cursor.getString(3); //视频的绝对地址
                        item.setData(data);

                        String artist=cursor.getString(4); //艺术家
                        item.setArtist(artist);

                        mediaList.add(item); //把每个item数据放到集合中
                    }
                    cursor.close();
                }

                //发消息,提示加载完media

                handler.sendEmptyMessage(0);
            }
        }.start();

    }

}

4、SystemVideoPlayer 自定义播放器类的代码

package com.yuanlp.mobileplayer.activity;

import android.app.Activity;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;

import com.yuanlp.mobileplayer.R;

/**
 * Created by 原立鹏 on 2017/7/16.
 * 系统播放器
 * 注意去Manifext.xml里注册
 */

public class SystemVideoPlayer extends Activity{
    private VideoView videoview;
    private Uri uri;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.system_video_player);
        videoview= (VideoView) findViewById(R.id.videoview);

        //得到播放地址,从intent中获取
        uri = getIntent().getData();
        if (uri!=null){
            videoview.setVideoURI(uri);
        }

        //准备好的监听,监听是否视频准备好
        videoview.setOnPreparedListener(new MyOnPreparedListener());
        //播放出错了的监听
        videoview.setOnErrorListener(new MyOnErrorListener());
        //播放完成的监听
        videoview.setOnCompletionListener(new MyOnCompletionListener());

        //设置控制面板,系统自带的
        videoview.setMediaController(new MediaController(this));

    }
    /**
     * 准备好播放时的监听
     */
    class MyOnPreparedListener implements MediaPlayer.OnPreparedListener {

        @Override
        public void onPrepared(MediaPlayer mp) {
            videoview.start(); //开始播放

        }
    }

    /**
     * 播放出错
     */
    class MyOnErrorListener implements MediaPlayer.OnErrorListener {

        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            //出错后,系统会自动提示播放出错,同时自己也弹一个吐司
            Toast.makeText(SystemVideoPlayer.this,"播放出错",Toast.LENGTH_SHORT).show();
            return false;
        }
    }

    /**
     * 播放完成的监听
     */
    class MyOnCompletionListener implements MediaPlayer.OnCompletionListener {

        @Override
        public void onCompletion(MediaPlayer mp) {
            Toast.makeText(SystemVideoPlayer.this, "播放完成", Toast.LENGTH_SHORT).show();
        }
    }
}
时间: 2024-08-02 05:11:37

手机影音第五天 视频列表的显示与播放以及个别牌子手机播放的问题的相关文章

手机影音第十一天,显示视频缓冲,显示卡顿时的网速,播放系统视频时调用播放器的选择

代码已经托管到码云,有兴趣的小伙伴可以下载看看 https://git.oschina.net/joy_yuan/MobilePlayer 一.设置视频缓冲进度 显示视频播放进度的效果图如下:灰色的是缓冲的进度. 原理:只有播放网络视频时,才有缓冲这个说法,所以要先判断视频资源是否为网络资源 /**  * 判断是否是网络的资源  * @param uri  * @return  */ public boolean isNetUri(String uri) {     boolean reault

手机影音第七天 视频的播放下一个视频功能实现,视频进度、电量变化的实现

先看下效果图: 在这里,视频进度条会根据视频播放变化,下方的按钮中,播放下一个,上一个都已实现. 代码已经托管到码云上,想下载看的小伙伴可以从下方地址中获取 https://git.oschina.net/joy_yuan/MobilePlayer 1.在这张图上,自定义的显示电量的那一列已经被系统自带的状态栏遮盖,下面就说一下实现方法: 系统电量变化时,系统会发送一个广播,所有对这个广播感兴趣的activity都可以注册广播来接收这个广播.在这里接收系统电量变化,屏幕锁屏.开屏的广播,只能使用

黑马2018年最新kotlin项目实战视频 (手机影音、即时通讯、黑马外卖、坦克大战等)

├─1.kotlin简介和学习方法│ 01_kotlin课程简介_01.mp4│ 02_kotlin学习方法_01.mp4│ 03_kotlin选好教练车_01.mp4│ 03_kotlin选好教练车_02.mp4│ 04_kotlin你好世界_01.mp4│ 05_kotlin变量与输出_01.mp4│ 05_kotlin变量与输出_02.mp4│ ├─10.类,对象和接口(三)│ 38_kotlin面向对象-抽象类和接口_01.mp4│ 38_kotlin面向对象-抽象类和接口_02.mp4

手机影音第四天,顶部标题栏的布局实现与本地视频的搜索

前面讲了下面的菜单布局与中间的fragmentLayout的布局与实现,今天就写了顶部title的布局以及去搜索本地sd卡里的视频. 一.顶部布局实现 效果图如下: 1.分析下: a.这个顶部布局是个LinearLayout布局 b.左侧这个321影音是个ImageView,然后这个搜索框是一个TextView,右侧的游戏图标是个相对布局,里面是一个textview和一个Image构成的点,最右侧的那个记录是一个Imageview c.最主要的是中间的这个搜索框,为什么是一个textview呢,

手机影音第十五天,利用service实现后台播放音乐,在通知栏显示当前音乐信息等

代码已经托管到码云上,有兴趣的小伙伴可以下载看看 https://git.oschina.net/joy_yuan/MobilePlayer 先来一张目前的音乐播放器的效果图,当播放时,手机的状态通知栏也会有音乐信息显示. 这里可以看到有歌名.演唱者,还有歌曲的总时间,当前播放时间,当前播放进度,音乐暂停.下一首,上一首,音乐循环模式(单曲循环,顺序播放.循环播放)功能的实现.下一步就是把中间空白的部分填充歌词,然后做成根据进度显示歌词. 由于这次的内容有点多,是写了一天半的代码,讲的没那么细,

手机影音第九天,控制视频全屏播放与退出全屏播放,音量调节按钮来控制视频音量与静音的实现

代码以托管到码云,有兴趣的小伙伴可以下载看看 https://git.oschina.net/joy_yuan/MobilePlayer 一.视频全屏播放与退出全屏 系统默认的videoview类,没有调整大小的方法,因此需要自定义一个类,继承videoview,然后重写里面的三个构造方法,再自定义一个调整视频播放页面大小的方法. 1.布局文件 同时,在视频播放的布局文件中,videoview布局要引用上面自定义的类. <?xml version="1.0" encoding=&

手把手教你做视频播放器(五)-视频列表的横屏

第6节 视频列表的横屏 设备在横放或者竖放的时候都会自动调整应用的布局,进行对应的横屏显示或者竖屏显示.我们的视频列表也是如此. 我们可以用两种方法处理设备旋转的问题, 让Activity不跟随设备方向的旋转而旋转,它只有竖屏(或只有横屏)的界面.要做到这一点很容易,在AndroidManifest.xml文件中,给这个Activity组件加上android:screenOrientation="portrait" (保持竖屏)或者android:screenOrientation=&

手机影音第六天 自定义播放器页面的实现(按钮暂时未监听)

目前进度的项目源代码托管在里码云上,地址如下: https://git.oschina.net/joy_yuan/MobilePlayer 感兴趣的可以去下载看看,多多支持 这次就摒弃了系统自带的控制栏,即之前写的通过系统自带的控制栏 videoview.setMediaController(new MediaController(this)); 转而自己写控制器布局,实际截图如下: 效果图: 一.Activity的声明周期重温与横竖屏切换时的问题 有2个页面,A页面,B页面,下面括号里的A,B

WPF技术触屏上的应用系列(五): 图片列表异步加载、手指进行缩小、放大、拖动 、惯性滑入滑出等效果

原文:WPF技术触屏上的应用系列(五): 图片列表异步加载.手指进行缩小.放大.拖动 .惯性滑入滑出等效果 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统,54寸大屏电脑电视一体机.要求有很炫的展示效果,要有一定的视觉冲击力,可触控操作.当然满足客户的要求也可以有其它途径.但鉴于咱是搞 .NET技术的,首先其冲想到的微软WPF方面,之前对WPF的了解与学习也只是停留在比较浅的层面,没有进一步深入学习与应用.所以在项目接来以后,也就赶鸭子上架了,经过努力