我正在使用第三方文件管理器从文件系统中选择一个文件(在我的情况下为PDF).
这是我启动活动的方式:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);
String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);
startActivityForResult(chooser, ActivityRequests.BROWSE);
Run Code Online (Sandbox Code Playgroud)
这就是我所拥有的onActivityResult:
Uri uri = data.getData();
if (uri != null) {
if (uri.toString().startsWith("file:")) {
fileName = uri.getPath();
} else { // uri.startsWith("content:")
Cursor c = getContentResolver().query(uri, null, null, null, null);
if (c != null && c.moveToFirst()) {
int id = c.getColumnIndex(Images.Media.DATA);
if (id != -1) {
fileName = c.getString(id);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
代码片段来自Open Intents文件管理器说明,网址为: …
首先要提到的是,这里问题的答案没有帮助。
源代码如下所示:
Intent intent = new Intent("com.mycompany.action.PICK_FILE");
String authority = "com.mycompany.fileprovider";
File file = Environment.getExternalStorageDirectory();
intent.setData(FileProvider.getUriForFile(this, authority, file));
Run Code Online (Sandbox Code Playgroud)
FileProvider.getUriForFile抛出异常,这是堆栈跟踪:
java.lang.StringIndexOutOfBoundsException: length=15; index=16
at java.lang.String.indexAndLength(String.java:500)
at java.lang.String.substring(String.java:1313)
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:687)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:377)
Run Code Online (Sandbox Code Playgroud)
在标签AndroidManifest.xml内部application我添加了以下内容:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mycompany.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"
/>
</provider>
Run Code Online (Sandbox Code Playgroud)
内容file_paths.xml如下:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="input_files" path="." />
<external-path name="output_files" path="MyAppName/" />
</paths>
Run Code Online (Sandbox Code Playgroud)
output_files在此上下文中不使用路径。
我已经通过运行调试器FileProvider.SimplePathStrategy.getUriForFile()。相关代码片段如下(第683-688行):
final String rootPath = mostSpecific.getValue().getPath();
if (rootPath.endsWith("/")) {
path = path.substring(rootPath.length());
} …Run Code Online (Sandbox Code Playgroud) 上传到 Google Play 的所有新应用都必须针对 Android 10(API 级别 29)或更高版本。Environment.getExternalStorageDirectory()但是,当应用程序以 API 级别 29 为目标时,应用程序将无法再直接访问从返回的路径。
文档建议使用Context.getExternalFilesDir()(不适合我的用例,因为放置在那里的文件位于应用程序内部,并且在卸载应用程序时被删除)或MediaStore,记录在此处。
我陷入了以下片段:
// Find all image files on the primary external storage device.
// On API <= 28, use VOLUME_EXTERNAL instead.
Uri collection = MediaStore.Images.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL_PRIMARY);
Run Code Online (Sandbox Code Playgroud)
当我尝试支持 API <= 28 和 API >= 29 时,我尝试了以下操作:
Uri collection;
if (VERSION.SDK_INT >= VERSION_CODES.Q) {
collection = MediaStore.Images.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
collection = MediaStore.Images.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL);
}
Run Code Online (Sandbox Code Playgroud)
但是,我仍然收到需要 API 级别 29 的警告。MediaStore.VOLUME_EXTERNAL …
我的服务扩展IntentService,当它开始时startService,onHandleIntent被调用.但是,当服务启动时bindService(我确实需要绑定),onHandleIntent不会被调用.
如果onHandleIntent当被调用IntentService时开始bindService?是startService唯一的方法IntentService应该开始吗?
文档IntentService说明如下:
客户端通过startService(Intent)调用发送请求; 根据需要启动服务,使用工作线程依次处理每个Intent,并在工作失败时自行停止.
目前,我通过调用解决我的问题startService后,正确的bindService,但我觉得它难看.我想知道有没有办法让它只用一个电话就可以工作.
代码片段随之而来,可能是我遗漏了一些明显的东西.
ExampleService.java
public class ExampleService extends IntentService {
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (message.replyTo != null) {
outMessenger = message.replyTo;
}
}
}
private Messenger messenger = new Messenger(new IncomingHandler());
private Messenger outMessenger = null;
public ExampleService() {
super("ExampleService");
} …Run Code Online (Sandbox Code Playgroud)