Так случилось, что я столкнулся с почти такой же проблемой: мне нужно было поделиться видеофайлом. Проблема в том, что теперь есть способ поделиться внутренним файлом. Никогда. Вам либо нужен ContentProvider
, либо, поскольку с ним немного проще, это расширение FileProvider
.
Во-первых: вам нужно обновить вас AndroidManifest.xml
:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="my.package.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
Это нужно добавить в <application>
tag.
Затем вам нужен файл XML file_paths.xml
в подкаталоге Android res/xml/
Должно получиться что-то вроде этого:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="objects" path="objects/"/>
</paths>
И чтобы, наконец, запустить его, мне нужно было вызвать его так:
Uri uri = Uri.parse("content://my.package.fileprovider/" + fn);
Intent intent = new Intent(Intent.ACTION_VIEW, uri); // or parse uri each time
intent.setDataAndType(uri, "video/*"); // all video type == * - alternative: mp4, ...
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_GRANT_READ_URI_PERMISSION);
List<ResolveInfo> resInfoList = FXActivity.getInstance().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
FXActivity.getInstance().grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
FXActivity.getInstance().startActivity(intent);
Но что мне нужно было сделать, чтобы иметь возможность использовать его следующим образом: мне нужно было скопировать все активы в каталог личных файлов, потому что сам FileProvider
не имеет возможности доступа к вашим активам (я думаю, вы могли бы добиться этого с помощью пользовательского ContentProvider
, но я нашел способ сложным и не имел столько времени).
Дополнительные сведения см. в этом справочнике для разработчиков Android по FileProvider. .
Мое простое решение для этого выглядит так:
public boolean copyAssetsToStorage() throws NativeServiceException {
try {
String[] assets = getContext().getAssets().list(DIR_NAME);
if (assets == null || assets.length == 0) {
LOG.warning("No assets found in '" + DIR_NAME + "'!");
return false;
}
File filesDir = getContext().getFilesDir();
File targetDir = new File(filesDir, DIR_NAME);
if (!targetDir.isDirectory()) {
boolean b = targetDir.mkdir();
if (!b) {
LOG.warning("could not create private directory with the name '" + DIR_NAME + "'!");
return false;
}
}
for (String asset : assets) {
File targetFile = new File(targetDir, asset);
if (targetFile.isFile()) {
LOG.info("Asset " + asset + " already present. Nothing to do.");
continue;
} else {
LOG.info("Copying asset " + asset + " to private files.");
}
InputStream is = null;
OutputStream os = null;
try {
is = getContext().getAssets().open(DIR_NAME + "/" + asset);
os = new FileOutputStream(targetFile.getAbsolutePath());
byte[] buff = new byte[1024];
int len;
while ((len = is.read(buff)) > 0)
os.write(buff, 0, len);
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
continue;
}
if (os != null) {
os.flush();
os.close();
}
if (is != null)
is.close();
}
return true;
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
return false;
}
}
Как видите, я пока поддерживаю только плоскую иерархию...
По крайней мере, это помогло мне.
С уважением, Даниэль
ДОПОЛНИТЕЛЬНЫЙ ВОПРОС. Почему вы отправляете намерение, а не реализуете простой элемент управления аудиопроигрывателем JavaFX? Это то, что я делал до видео материала.
person
dzim
schedule
02.12.2016
Context.getFilesDir()
). Оттуда в мире Android есть сложные средства для обмена вашим контентом. Смотрите мой ответ ниже. - person dzim   schedule 02.12.2016