在Android开发中,识别U盘并进行读写操作是一个常见需求,以下将详细介绍如何在Android应用中实现这一功能,包括识别U盘、安全弹出U盘以及读写U盘文件的具体步骤和代码示例。
要识别U盘,主要用到两个Android官方类:ContentResolver
和AsyncQueryHandler
,以下是具体实现步骤:
1、获取状态并遍历:
创建一个ContentObserver
对象,用于监听U盘的挂载和拔出事件。
创建一个Runnable
对象,当U盘状态发生变化时,通过Handler
延迟执行查询操作。
ContentObserver contentObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); mHandler.removeCallbacks(arg.runnable); mHandler.postDelayed(arg.runnable, DELAY); } }; Runnable runnable = new Runnable() { @Override public void run() { mAsyncQueryHandler.startQuery(token, null, uri, projection, selection, selectionArgs, orderBy); } };
2、回调数据给UI:
创建一个AsyncQueryHandler
对象,用于异步查询U盘的状态。
在onQueryComplete
方法中处理查询结果,并通过回调通知UI更新。
mAsyncQueryHandler = new AsyncQueryHandler(mCR) { @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { super.onQueryComplete(token, cookie, cursor); if (!mArgs.isEmpty() && token < mArgs.size()) { QueryArg arg = mArgs.get(token); if (mCallback != null) { mCallback.QueryNotify(arg.uri, cursor); } if (!cursor.isClosed()) { cursor.close(); } } } };
弹出U盘的操作相对简单,类似于删除数据库中的记录,以下是具体实现步骤:
1、获取ContentResolver
实例。
2、创建ContentValues
对象,并设置MediaStore.MediaDevice.FIELD_VALID
字段为false
。
3、调用update
方法,使用MediaStore.MediaDevice.CONTENT_URI
作为URI,执行更新操作。
ContentResolver cr = mContext.getContentResolver(); ContentValues values = new ContentValues(); values.put(MediaStore.MediaDevice.FIELD_VALID, false); cr.update(MediaStore.MediaDevice.CONTENT_URI, values, where, selectionArgs);
注意:在自己软件中弹出U盘仅改变此软件的U盘状态,对系统无影响。
读写U盘文件需要先识别U盘,然后在遍历到的文件上进行读写操作,以下是具体实现步骤:
1、读取文件:
在识别U盘的回调方法中,获取文件的Uri
。
使用ContentResolver.openInputStream
方法打开文件输入流,并读取文件内容。
2、写入文件:
使用ContentResolver.openOutputStream
方法打开文件输出流。
将数据写入文件输出流中,并关闭输出流。
// 读取文件示例 InputStream inputStream = mContext.getContentResolver().openInputStream(fileUri); // 在此处添加读取文件内容的代码 inputStream.close(); // 写入文件示例 OutputStream outputStream = mContext.getContentResolver().openOutputStream(fileUri); // 在此处添加写入文件内容的代码 outputStream.close();
问:为什么需要动态获取读写权限?
答:从Android 6.0(API级别23)开始,Android引入了动态权限的概念,即使在AndroidManifest.xml
文件中声明了权限,应用仍需在运行时请求这些权限,对于外部存储的读写操作,需要请求READ_EXTERNAL_STORAGE
和WRITE_EXTERNAL_STORAGE
权限,这是因为这些操作可能涉及到用户隐私和设备安全,所以需要在运行时明确获得用户的授权。
问:如何确保应用具有访问U盘的权限?
答:除了在AndroidManifest.xml
文件中声明权限外,还需要在应用运行时通过ActivityCompat.requestPermissions
方法请求必要的权限,如果用户授予了权限,应用才能执行后续的读写操作,也需要处理用户拒绝授权的情况,给予用户适当的提示或采取替代方案。