一、FileProvider
前几天学习了如何分享文字、图片、音乐或其他流文件,那么提供让我们选择文件的应用,比如图库不仅能查看图片还能从其他应用跳转到图库去挑选图片然后返回选择的结果,这是如何做的呢?官方提供了 FileProvider 来帮助我们完成。
1、Manifest中声明
<application> 标签中声明 <provider>,例子中的属性必须有
说明:
(1)authorities:android:package + fileprovider;
(2)<mete-data> 中指出 FileProvider 允许访问的目录
(3)这些目录存放在 res/xml/filepath.xml 文件中
注意:(特别感谢小爱_小世界)
<file-path> 代表的根目录:Context.getFilesDir()
<external-path> 代表的根目录:Environment.getExternalStorageDirectory()
<cache-path> 代表的根目录:getCacheDir()
2、选择界面的创建-- Activity
Manifest中应该这样声明
说明(针对 <intent-filter>):
(1)<action>:android.Intent.action.PICK;
(2)<category>:DEFAULT 和 OPENABLE 都要有;
(3)<data>:要设置 MIME 类型。自己根据需求设置。
至于 Activity 的创建和其他没有区别,一般是一个列表供用户选择。
3、选择结果的处理及返回结果
说明:
(1)选择文件后,会得到一个File对象,使用 FileProvider.getUriForFile(Context context,String authority,File file) 方法获取Uri。如果该文件在不允许访问的目录下(filepath.xml),则会抛异常。
(2)返回结果的 Intent 要通过 addFlags(FLAG_GRANT_READ_URI_PERMISSION) 方法进行临时授权,要设置 data 和 MIME type。
(3)使用 setResult(resultCode , intent) 将结果设置好,并 finish() 当前 Activity。
二、音频---Audio
1、音频简介
Android 音频控制是由 AudioManager 来管理,通过 getSystemService(Context.AUDIO_SERVICE) 来获取该服务。
音频分为 AudioManager.STREAM_SYSTEM、AudioManager.STREAM_MUSIC、AudioManager.STREAM_RING、AudioManager.STREAM_NOTIFICATION、AudioManager.STREAM_ALARM、AudioManager.STREAM_VOICE_CALL、AudioManager.STREAM_DTMF(双音多频,拨号键的声音)七种。
2、音量
当启动一个新应用,要在 onCreate() 中使用 AudioManager.setVolumeControlStream(int type) 设置应用控制的音量种类。
各种音量的最大值一般都一样(自己测试得到)。
设置音量大小两种方法:
(1)渐进式
就是像按音量控制按钮似的,一点一点的调节。
AudioManager.adjustStreamVolume(int streamType, int direction, int flags)
1)streamType 不介绍,同上面。
2)direction 是调整的方向:
ADJUST_LOWER 降低音量
ADJUST_RAISE 升高音量
ADJUST_SAME 保持不变,这个主要用于向用户展示当前的音量
3)flags 两种常见:
FLAG_PLAY_SOUND 调整音量时播放声音
FLAG_SHOW_UI 调整时显示音量条,就是按音量键出现的界面
(2)直接设置
Audiom.setStreamVolume(streamType , index , flags)
index:音量大小
3、硬件按键控制
无论用户按下设备上任意一个控制按钮,系统都会广播一个带有ACTION_MEDIA_BUTTON的Intent。因此使用广播来处理这些事件。
因为可能会有多个程序在监听与媒体按钮相关的事件,所以我们必须在代码中控制应用接收相关事件的时机。我们使用 AudioManager 来为我们的应用注册监听与取消监听媒体按钮事件,当Receiver被注册上时,它将是唯一一个能够响应媒体按钮广播的Receiver。
4、音频焦点
由于可能会有多个应用可以播放音频,所以我们应当考虑一下他们应该如何交互。为了防止多个音乐播放应用同时播放音频,Android 使用音频焦点(Audio Focus)来控制音频的播放——即只有获取到音频焦点的应用才能够播放音频。
(1)处理焦点变化事件
使用 AudioManager.OnAudioFocusChangeListener,共有八种事件:
AUDIOFOCUS_GAIN:永久获取焦点,只有手动释放才会失去焦点;
AUDIOFOCUS_GAIN_TRANSIENT:暂时获取焦点;
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:暂时获取焦点,其他音频降低音量播放;
AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:暂时获取焦点,其他音频停止播放。
对应四种失去焦点事件 AUDIOFOCUS_LOSS、AUDIOFOCUS_LOSS_TRANSIEN、AUDIOFOCUS_LOSS_TRANSIENT_MAY_DUCK、AUDIOFOCUS_LOSS_TRANSIENT_EXCLUSIVE。
疑问:
经过查阅资料和自己试验,未发现 TRANSIENT 和 TRANSIENT_EXCLUSIVE 的区别。
如有朋友知晓,请分享,谢谢。
(2)申请音频焦点
AudioManager.requestAudioFocus( listener , streamType , durationHint )
1)listener:OnAudioFocusChangeListener,指处理申请成功之后 AudioFocus 变化情况的Listener,因为在获得焦点期间可能又有别的应用申请焦点。
2)streamType:音频流类型
3)durationHint:(是 AudioManager 中的常量,有以下几种值)
4)返回值是 AudioManager.AUDIOFOCUS_REQUEST_GAINED 或 AudioManager.AUDIOFOCUS_REQUEST_FAILED。
(3)释放音频焦点
abandonAudioFocus( listener ) 这样相当于告知系统我们不再需要获取焦点并且注销所关联的 AudioManager.OnAudioFocusChangeListener 监听器。
5、处理音频输出设备的改变
当有线耳机被拔出或者蓝牙设备断开连接的时候,音频流会自动输出到内置的扬声器上。假设播放声音很大,这个时候突然转到扬声器播放会显得非常嘈杂。幸运的是,系统会在这种情况下广播带有 ACTION_AUDIO_BECOMING_NOISY 的 Intent,所以使用广播来处理这些事件。