我们有一个运行Nougat的自定义Android设备,并且包含在供应商特定的启动器中。我正在尝试使用API 23为所述设备实现文件管理器。这是因为我已经读过,从Android M开始的唯一方法是使用SAF。
我正在开发的设备有3个USB端口,当连接USB驱动器时,应用程序会检测并将自定义文件从USB传输到设备的内部存储设备(设备没有SD卡)。由于在Android N上直接访问可安装存储是不可取的,我想用SAF来做这件事。
我已经通过USB管理器和USB主机实现了USB分离和连接的广播接收器,并且可以成功检测USB插入的时间,但徒劳地尝试与设备通信并尝试提取文件。但我也读到Android USB框架仅用于发送小字节,用于与USB连接设备(如Arduino板)进行通信,而不是。
我现在正在尝试实施USB文档提供程序来浏览USB。由于我无法根据此post直接访问文件。
我正在关注此source code以实现我的USB文档提供程序。
我目前正在实现类的queryRoots和queryChildDocuments部分。 Cursor的大多数字段我都知道要放什么,但是COLUMN_DOCUMENT_ID的部分会让我感到困惑(对于这两种方法)。
由于该设备是可移动的USB,我不知道该把什么作为列的值
这是我的queryRoots方法实现:
@Override
public Cursor queryRoots(String[] projection) throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
final MatrixCursor.RowBuilder row = result.newRow();
row.add(Root.COLUMN_ROOT_ID, BuildConfig.DOCUMENTS_AUTHORITY);
row.add(Root.COLUMN_ICON, R.drawable.ic_menu_manage);
row.add(Root.COLUMN_TITLE, "Root Title");
row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_RECENTS);
row.add(Root.COLUMN_SUMMARY, "USB Reader");
row.add(Root.COLUMN_DOCUMENT_ID, "/");
row.add(Root.COLUMN_MIME_TYPES, "*/*");
Uri rootsUri = DocumentsContract.buildRootsUri(BuildConfig.DOCUMENTS_AUTHORITY);
getContext().getContentResolver().notifyChange(rootsUri, null);
return result;
}
如果我错了,请纠正我,但由于我要导出的文件不是典型的mime类型文件,我已将COLUMN_MIME_TYPES设置为
*/*
我的queryChildDocuments方法:
@Override
public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
String sortOrder) throws FileNotFoundException {
final MatrixCursor result = new
MatrixCursor(resolveDocumentProjection(projection));
String parentDocumenPath = getContext().getFilesDir().getPath() + "/" + parentDocumentId;
File dir = new File(parentDocumenPath);
for (File file : dir.listFiles()) {
String documentId = parentDocumentId + "/" + file.getName();
includeFile(result, documentId);
}
return result;
}
除此之外,我的实施没有别的特色。
然后,我打算通过导航菜单打开文档提供程序,使用以下代码:
if (id == R.id.nav_file_explorer) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
startActivityForResult(intent, 1);
}
自定义文档提供程序显示在列表中,但未列出USB驱动器。除此之外,当我点击文档提供程序从我指定的根目录打开时,它什么都不返回。我做错了什么?
答案 0 :(得分:0)
在Android M及更高版本中无需SAF即可访问可移动存储数据。你只需要进行低级编码。正如此project所示。 我们项目中可能会选择实施与此链接项目类似的内容,因为此时SAF证明是不可靠的。
该项目还包括SAF的实施,但以低级USB读取库为基础。