首页 > 解决方案 > 从 Android 共享意图下载文件

问题描述

我的应用程序可以选择与其他应用程序共享生成的 GPX 文件(远足路线)。我为此使用了 ACTION_SEND 意图。它运行良好,用户可以与其他应用程序以及通过电子邮件等方式与其他人共享 GPX 文件。

然而,一些应用似乎不接受通过意图接收这些数据。当我使用内容类型“application/gpx+xml”共享 GPX 文件时,Garmin Connect 未显示在应用程序列表中。

如果我手动下载 GPX 文件然后打开它,则 Garmin Connect 被列为可以打开它的应用程序。

有没有办法将“下载文件”添加到共享文件时弹出的共享选择器意图?

这是我正在使用的客户端代码:

private final WeakReference<MainActivity> mainActivityWeakReference;

public FileExportTask(MainActivity mainActivity) {
    this.mainActivityWeakReference = new WeakReference<>(mainActivity);
}

@Override
public void run() {
    MainActivity mainActivity = mainActivityWeakReference.get();

    if (mainActivity == null) {
        // TODO: handle that mainActivity doesn't exist
        return;
    }

    try {
        Uri uri = getUriForSelectedRoute();
        mainActivity.runOnUiThread(() -> {
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND);
            shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
            shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            shareIntent.setType("application/gpx+xml");
            Intent chooser = Intent.createChooser(shareIntent, mainActivity.getString(R.string.share_route));

            List<ResolveInfo> resInfoList = mainActivity.getPackageManager().queryIntentActivities(chooser, PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo resolveInfo : resInfoList) {
                String packageName = resolveInfo.activityInfo.packageName;
                mainActivity.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }

            mainActivity.startActivity(chooser);
        });
    } catch (Exception ioe) {
        mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, R.string.failed_route_share, Toast.LENGTH_SHORT).show());
    }
}

private Uri getUriForSelectedRoute() throws Exception {

    Route selectedRoute = RouteResponseProvider.getInstance().getSelectedRoute();
    return downloadRoute(selectedRoute.toGpxUrl());
}

private Uri downloadRoute(String url) throws IOException {

    String filename = "route_"+System.currentTimeMillis()+".gpx";
    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new UserAgentInterceptor())
            .build();

    Request httpRequest = new Request.Builder()
            .url(url)
            .build();

    try (Response response = client.newCall(httpRequest).execute()) {
        File downloadedFile = new File(getFilesDirectory(), filename);
        BufferedSink sink = Okio.buffer(Okio.sink(downloadedFile));
        sink.writeAll(response.body().source());
        sink.close();
        return getContentUri(downloadedFile);
    }
}

private File getFilesDirectory() {
    MainActivity mainActivity = mainActivityWeakReference.get();
    File dir = mainActivity.getFilesDir();
    if (dir != null && !dir.exists()) {
        dir.mkdirs();
    }
    return dir;
}

private Uri getContentUri(File file) {
    MainActivity mainActivity = mainActivityWeakReference.get();
    return FileProvider.getUriForFile(mainActivity, "com.myapp.fileprovider", file);
}

这是在我的 AndroidManifest.xml 中:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.myapp.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths" />
</provider>

标签: androidandroid-intent

解决方案


推荐阅读