Android获取手机内的音频数据

我们经常需要获取手机信息,例如我们想做一个音乐播放器,我们需要拿到本地的音频信息,这样一来,我们就需要考虑如何拿到这些数据了

1,一个神秘的apk

在这里插入图片描述
这个叫做MediaProvider.apk是干什么的呢,和我们今天讲的东西有啥关联吗,其实这是一个正在运行的apk,这个apk是没有界面的,因此我们是看不见的,他的作用就是在后台默默的为我们收集相关的数据信息。,然后保存在数据库里面
在这里插入图片描述

在这里插入图片描述
从上面的截图上看,这个apk把我们收集内的媒体信息都存储在数据库中了,那么接下来我们只需要读取数据库,拿到相关的资源即可了。

2,获取资源之 子线程+handler方式

这里获取资源,我给大家提供三种方式

  1. 子线程+handler
  2. 自带的异步任务AsyncTask
  3. AsyncQueryHandler

子线程+handler:
这个首先是创建子线程:

//这个是android中的内容提供者,上面所说的三种方式都需要用到这个,主要提供android手机的内的基本数据信息
val resolver = context?.contentResolver
Thread(
object:Runable{
	override fun run(){
			var cursor = resolver?.query(
			//这方法不懂请看下面的源码分析,看完我们再接着往下看
			MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
			arrayOf(
			MediaStore.Audio.Media.DATA,
			MediaStore.Audio.Media.SIZE,
			MediaStore.Audio.Media.DISPLAY_NAME,
			MediaStore.Audio.Media.ARIST
			), null ,null.null
		)
		//上面返回的是一个游标,我们定义一个处理游标的方法类,接着看下面的游标类
		CursorUtil(cursor)
		var msg = Message.obtain()
		msg.obj = cursor
		handler.setMessage(mgs)
		//注意 handler创建我这里就不写了,注意最好使用防止内存泄漏的写法
	}
}
).start()

object CursorUtil{
	fun logCursor(cursor: Cursor){
		cursor.let{
			//游标复位
			it.moveToPisition(-1)
			//每次游标向下移动一位,读取一条数据,然后获取每条数据的具体
			while(it.moveToNext){
				//每条数据来一次for循环
				for(index in 0 until it.columnCount){
					println("key======${it.getColumn(index)}----value===${it.getString(index)}")
				}
				println("=========下一条数据")
			}
		}
	}
}

下面我们来看一下query的源码信息

    /**
    通过提供的uri信息,返回一个Cursor数据
     * Query the given URI, returning a {@link Cursor} over the result set.
     * 第一个参数是uri信息
     * @param uri The URI, using the content:// scheme, for the content to
     *         retrieve.
     * 第二个参数是需要返回的数据条目有哪些,例如名字、作者、大小
     * @param projection A list of which columns to return. Passing null will
     *         return all columns, which is inefficient.
     * 第三个参数是根据条件返回多少行。如果为空则返回所有行 这个相当于sql语句后面的where语句
     * @param selection A filter declaring which rows to return, formatted as an
     *         SQL WHERE clause (excluding the WHERE itself). Passing null will
     *         return all rows for the given URI.
     * 选择包括哪些选项,一般写null
     * @param selectionArgs You may include ?s in selection, which will be
     *         replaced by the values from selectionArgs, in the order that they
     *         appear in the selection. The values will be bound as Strings.
     * 这个参数相当于orderby的效果,一般写null
     * @param sortOrder How to order the rows, formatted as an SQL ORDER BY
     *         clause (excluding the ORDER BY itself). Passing null will use the
     *         default sort order, which may be unordered.
     * @return A Cursor object, which is positioned before the first entry, or null
     * @see Cursor
     */
    public final @Nullable Cursor query(@RequiresPermission.Read @NonNull Uri uri,
            @Nullable String[] projection, @Nullable String selection,
            @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        return query(uri, projection, selection, selectionArgs, sortOrder, null);
    }

下面是打印出来的结果

2019-04-17 09:27:49.123 7252-7252/app.bxvip.com.myphone I/System.out: 搜索成功了
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======_data---value====/data/hw_init/product/media/Pre-loaded/Music/Bach_Suite.flac
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======_size---value====13016489
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======_display_name---value====Bach_Suite.flac
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======artist---value====Cory J. Wong
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: =========================下一条数据
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======_data---value====/data/hw_init/product/media/Pre-loaded/Music/Dream_It_Possible.flac
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======_size---value====25558969
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======_display_name---value====Dream_It_Possible.flac
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: key=======artist---value====Delacey
2019-04-17 09:27:49.124 7252-7252/app.bxvip.com.myphone I/System.out: =========================下一条数据
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_data---value====/data/hw_init/product/media/Pre-loaded/Music/Goldberg_Variations.flac
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_size---value====15273741
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_display_name---value====Goldberg_Variations.flac
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======artist---value====Johann Sebastian Bach
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: =========================下一条数据
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_data---value====/data/hw_init/product/media/Pre-loaded/Music/Music_My_Love.flac
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_size---value====24201533
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_display_name---value====Music_My_Love.flac
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======artist---value====Marye Lobb
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: =========================下一条数据
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_data---value====/storage/emulated/0/msc/哈喽.wav
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_size---value====377600
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======_display_name---value====哈喽.wav
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: key=======artist---value====<unknown>
2019-04-17 09:27:49.125 7252-7252/app.bxvip.com.myphone I/System.out: =========================下一条数据

上面是直接的handler+线程的方式

2,获取资源之 异步任务方式

/**
 *这里注意这个三个参数
 第一个参数数传递进来的参数
 第二个参数表示的进度更新的时候向外传递的数据
 第三个参数是处理完后的参数
 */
class AudioTask:AsyncTask<ContentResolver,Void, Cursor>(){
	ovrride fun doInBackground(vararg param: ContentResolver?):Cursor{
		//这个方法是在子线程中运行的
		val cursor = param[0]?.query(
			//这方法不懂请看下面的源码分析,看完我们再接着往下看
			MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
			arrayOf(
			MediaStore.Audio.Media.DATA,
			MediaStore.Audio.Media.SIZE,
			MediaStore.Audio.Media.DISPLAY_NAME,
			MediaStore.Audio.Media.ARIST
			), null ,null.null
		)
		retturn cursor // 这里跟第三个参数对应
	}
	ovveride fun onPostExecute(result: Cursor?){
		super.onPostExecute(result)
		//打印
		CursorUtil.logCursor(result!!)
	}
		//这个方式是在异步任务之前准备的函数
        override fun onPreExecute() {
            super.onPreExecute()
        }
		//这个函数是在主线程中执行的,一般用于更新进度
        override fun onProgressUpdate(vararg values: Void?) {
            super.onProgressUpdate(*values)
        }
        
]

上面就是以异步任务的方式,是不是感觉很爽呢,下面再介绍一个种更爽的方式。

2,获取资源之 AsyncQueryHandler

从名字上看是不是已经看出来了是异步加handler呢,接下来看怎么实现吧

val handler = object: AsyncQueryHandler(resolver){
	//查询完成的回调  还没查嫩怎么回调,不要急,查询的在后面,相当于观察者模式一样
	override fun onQueryComple(token: Int, cookie: Any?, cursor: Cursor?){
		//回调到这里,线程就已经切换到了主线程
		 CursorUtil.logCursor(cursor!!)
	}
	
}
handler.startQuery(0,null,MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,arrayOf(MediaStore.Audio.Media.DATA,
                                MediaStore.Audio.Media.SIZE,
                                MediaStore.Audio.Media.DISPLAY_NAME,
                                MediaStore.Audio.Media.ARTIST),null,null,null)
                      

上面这种是不是更爽呢,三种方式就介绍到这里把,看大家怎么选择

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值