安卓开发绕不开一个词——适配。
不同的安卓版本需要适配;不同的屏幕尺寸需要适配;不同的屏幕类型需要适配;不同的厂商的系统也需要适配……
我来分享一个开发中遇到的小米手机的适配问题。
项目需要从媒体库中查询并处理数据,唰唰唰写完代码,在自己手机(oppo和华为)上一试,没问题。。。然后测试过来说,有问题呀!连上测试机一看,处理媒体库数据时报异常了,测试用的是小米手机。
原因是在处理图片数据的时候,我从媒体库中读取了duration的数值。
int duration = cursor.getInt(cursor.getColumnIndex(MediaStore.Files.FileColumns.DURATION));
其中获取到的index的值为11,没问题,但你用这个index去取值的时候,他就会报错……
总结了以前踩的坑,给大家一点建议,我也不知道对不对,因为毕竟不清楚他们底层是怎么弄的,只能依靠我写代码过程中测试和改错的经验。
重点一:小米手机读媒体库时,非视频不要去读取Duration这种视频特有的属性。
重点二:小米手机读媒体库时,如果使用的是File的uri:
MediaStore.Files.getContentUri("external");
那么查询的字段中一定不要使用非File的Columns,例如:
MediaStore.Images.Media.LONGITUDE;
MediaStore.Images.Media.LATITUDE;
哪怕你查询的文件本身就是图片(其他手机是可以的,但小米不行)。
……
没有重点三了……
另外,我在开发中还遇到了其他的问题,例如:
Uri mediaUri = MediaStore.Files.getContentUri("external");
String[] projection = new String[] {MediaStore.Files.FileColumns._ID};
String selection = MediaStore.Files.FileColumns.DATA + " = ?";
String[] selectionArgs = new String[] {path};
String sortOrder = MediaStore.Files.FileColumns._ID + " DESC";
Log.d(TAG,"projection:"
+ projection
+ " | selection="
+ selection
+ " | selectionArgs="
+ selectionArgs
+ " | sortOrder="
+ sortOrder);
Cursor cursor = context.getContentResolver()
.query(mediaUri, projection, selection, selectionArgs, sortOrder);
Log.d(TAG, "query:" + cursor);
很简单的查媒体库,通过已知的path查询其在媒体库的id,然后是日志:
2022-03-03 17:24:14.024 23309-23414/com.fxjc.album.pre D/FileUtil: [RxCachedThreadScheduler-2]projection:[Ljava.lang.String;@e7615cf | selection=_data = ? | selectionArgs=[Ljava.lang.String;@68b5c | sortOrder=_id DESC
2022-03-03 17:24:14.024 23309-23414/com.fxjc.album.pre E/Parcel: Reading a NULL string not supported here.
2022-03-03 17:24:14.028 23309-23414/com.fxjc.album.pre D/FileUtil: [RxCachedThreadScheduler-2]query:android.content.ContentResolver$CursorWrapperInner@6678e65
就是这样,在我两行日志中间,查询语句那里输出了一句E级日志,然而我完全不知道是为啥……我的oppo和华为都没有这东西,就小米的测试机会报。
一旦循环处理媒体库内容这东西就会刷屏,不使用过滤,日志根本没法看,烦死了。
谁要是知道怎么弄没它就给支个招哈。