zoukankan      html  css  js  c++  java
  • Android12_播放器_surfaceVIew_照相机_传感器

    编程的时间与空间的概念,两者不可兼得(技术固定),时间换空间,空间换时间

    sufaceView占用比较大的空间但是效率高

    1,音乐播放器 MediaPlayer

    ①同步的

    大致流程按下图走即可,播放最好写在服务里,因为要在后台播放

     

    1.1 new出来的mediaplayer 默认处于Idie(空闲),reset()也可以让其处于初始状态

    1.2 setDataSource()设置好文件之后就处于Initialized()初始化状态

    1.3 可以通过setOnErrorListener方法查看播放过程中失败原因,对应的int what是为什么失败.

    1.4 prepare();处于准备状态.

    1.5 start()开始播放,进入Starer状态

    1.6 setOnCompletionListener()播放状态监听

    ②不同步的音乐播放

    prepareAsync()异步准备,播放网络的音乐文件,

    记得添加权限

    Prepare()同步的准备,运行在主线程,网速够快的前提下没问题,但是也有可能导致应用程序无响应

    prepareAsync()异步的准备,会自己开启子线程去播放,但是这里可能会有没有准备好就开启播放的可能,这里要设置一个setOnprepareListener()的监听,当准备好了之后再去调用start()方法去播放

    可以在准备监听的事件中去设置一个消息框:正在缓冲

     

    2,soundpool

    mediaPlayer底层实现比较复制,步骤繁琐,当一个音频资源在单位时间内大量的重复播放,mediaPlayer就不方便了.

    Soundpool:单位时间内大量播放音频,应用场景,游戏按扳机开枪

    res目录下,创建一个文件夹raw放置音频文件,会自动生成R文件的id

    步骤:①创建声音池

    SoundPool soundpool = new SoundPool(音频的数量,推荐使用AUdioManager.STREAM_MUSIC(还有其他类型,MUSIC时间长短不容),声音的质量);

    ②把音频资源加载到内存 ,返回一个声音在内存中的id

    Int Soundid = Soundpool.load(上下文,资源id,优先级); //放在点击事件里就无法载入

    ③播放声音

    Soundpool.play(声音id,左声道1.0,右声道1.0,优先级(0最低),循环次数0不循环,-1永远循环,rate音频播放的速率0.5-2.0)

    音频播放的速率应用场景:汤姆猫的声音app

    左右声道的音量大小,最大为1.0

     

    3,视频播放器

    ①一般都是横屏播放,Activity标签中定义screenOrientation=”LandScope”//设置为横屏

    样式标签中定义:item,name=android:windowFullScreen  true

    (Theme.NoTitleBar.Fullscreen的样式中有)

    ②新的控件VideoView vv

    activity中找到它(3GP,MP4的都可以播放)

    vv.setVideoPath()//设置播放路径

    //需要进度条,快进快退

    MediaController mc = new xx(this);//创建控制器

    mc.setAnchorView(vv)//设置控制器控制的videoView

    vv.setMediaContro aller(mc)// 设置控制器

    Vv.start();开始播放

    真实的手机支持的格式更多

     

    4,SurfaceView 控件sv

    一般安卓里比较复杂的控件由mvc组成(ListView)

    4.1 SurfaceView单位时间内完成界面的大量多次更新

    因为它有双缓冲机制

    线程A ----更新ui -----后台计算 ---更新ui

    线程B ----后台计算----更新ui ---后台计算

    SurfaceView可以在子线程中更新ui(视频播放底层就是用的它可以大量跟新)

       4.2 子线程更新ui的使用步骤:

    ①创建一个子线程

    SurfaceHolder holder = sv.getHolder();//界面里面的内容显示控制器

    Canvas = holder.lockCanvas();//返回一个画板,并且锁定了画布

    Paint = new paint(),paint.setColor();

    canvas.drawCircle(x,y,半径,画笔);

    ②直接运行会报异常,lockCanvas//锁定了画布

    holder.unlockCanvasAndPost(canvas)//解锁画布并更新ui

    锁定画布之后立刻更新ui,睡眠的代码放到最后

    4.3 细节问题:

    ①如果把带有SurfaceView的子线程放到onCreate()中使用lockCanvas获取的画布有可能为null,但是如果之前有睡眠的代码,就可以正常进行.

    因为sv占用的内存和cpu开销很大,当界面完全可见的时候才会创建完毕,如果界面最小化holder就会被销毁掉,所以在onCreate()中去更新ui,svholder可能还没有创建,所以会报空指针异常

    解决方法:sv.getHolder().addCallBack(接口)//注册一个SurfaceView控制器的回调

     里面有三个子方法创建,销毁,大小发生了变化

    ②如果SurfaceView被销毁了,执行的代码也应该全部销毁掉(终止一个线程可以通过return结束它)

    4.4 采用SurfaceView进行播放视频

    ①创建控制器的回调方法sv.getHolder().addCallBack();

    ②创建一个mediaplayer去设置路径,//它在后台也会播放

    ③在回调方法中,如果sv被创建了

    就准备播放,开始播放,可以设置进度seekto(位置);

    ④在回调的方法中,如果sv被销毁了,就准备暂停视频

    Int weizhi = mediaplayer.getCurrentPosition();//把位置信息保存下来,可以通过sp保存.

    Mediaplayer.stop()//停止的方法

    Mediaplayer.release();//释放资源

    一般还是用mediaplayer因为它比较方便,要自定义就SurfaceView控件

    5,照相机拍照

    查看离线文档>>标题栏Develop>>Media and Camera>>Camera 使用已经存在的照相机应用

    里面有一段示例代码,可以用来使用照相机应用

      // create Intent to take a picture and return control to the calling application
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        filename = new File(); // create a file to save the image
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); //Uri.fromfile(filename)

        // start the image capture Intent
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

    使用onActivityResult方法获取返回结果

    要记得判断照片是否存在,且有内容

    不从intent里面直接获取图片是因为这个图片被严重的压缩,很模糊,所以通过文件的方式进行传递

    6.手机录制视频

    大致流程跟拍照一致,不过不能在ImageView中显示,而要在VideoView 中显示

    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

    需要配权限.

    7,传感器相关

    安卓默认支持很多传感器,利用这些传感器可以开发出很多有意思的应用,摇一摇用的是方向传感器.加速度传感器,丢手机加速度的软件

      

    但是实际上手机里面的传感器是有限的,看手机价位来,查询手机上传感器的数量,谷歌已经封装好了一套接口用来查看.

    SensorManager sm = getSystemService(SENSOR_SERVICE);

    sm.getSensorList(Sensor.TYPE_ALL)//拿到所有的传感器,返回一个list集合

    对于每一个元素getName()即可获取名称.

    //不过模拟器虽然有传感器,但是不能用(你想摇晃你的电脑吗?)

    实例:光线传感器.应用场景打电话的时候,屏幕变黑了.

    Sensor = sm.getDefaultSensor(Sensor.TYPE_LIGHT)//获取一个传感器,根据参数获取

    sm.registerListener(传感器监听,sensor,rate);

    rate采样频率,敏感度.游戏开发采样速度一分钟几百次,越快越费电,

    SENSOR_DELAY_NORMAL //采用默认的采样速度

    传感器监听里面有两个方法

    一个onSensorChanged(event):当传感器数据发生变化的时候调用,

    Event的帮助文档里有关于各种传感器的说明

    Float light = Event.value[0]//光传感器的强度

    可以对光线强度做判断,然后判断是否开启夜间模式,屏幕降低亮度等

    一个是onAccurayChanged(sensor,accuracy)//精度发生变化:如地磁传感器,位置发生改变

    额外:应用程序使用完了传感器要记得关闭,因为它会在后台运行,并且很耗电.

    sm.unregisterListener(监听器);

    7.2 指南针应用:使用传感器:方向传感器

    ①获取传感器服务管理,获取传感器

    ②查看帮助文档value[0]代表:地磁北极和手机Y轴的夹角,0=,90=,180=,270=西.

    Z轴是水平垂直,X,Y轴是手机屏幕中心为原点的平面X,Y轴

    ③然后可以对角度进行判断,可以判断出东南西北,通过一张指南针图片,指针的旋转角度来判断对应的角度.

  • 相关阅读:
    Ansible-Tower--安装配置及破解
    Ansible-playbook--配置及使用
    Ansible-基础配置及常用模块
    基于SLB实现滚动发布
    CentOS7 部署yapi API 文档管理工具
    node及pm2环境安装
    MySQL参数max_connect_errors分析
    CentOS7搭建confluence企业级文档管理
    Gitlab用户密码忘记如何修改
    Docker私有仓库Harbor介绍与部署
  • 原文地址:https://www.cnblogs.com/adventurer/p/5559697.html
Copyright © 2011-2022 走看看