Как имитировать выбор деятельности / поделиться меню? - PullRequest
0 голосов
/ 02 июля 2018

Я попытался создать собственный Chooser Activity, чтобы заменить общий доступ для Android к ... popup.

Я посмотрел на ChooserActivity расширяет ResolverActivity и попытался скопировать код. В моем манифесте у меня есть

<intent-filter>
    <action android:name="android.intent.action.CHOOSER" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

И в onCreate я делаю

Intent intent = getIntent();
Parcelable parcelable = intent.getParcelableExtra("android.intent.extra.INTENT");

Intent shareIntent = (Intent) parcelable;
shareIntent.setComponent(new ComponentName(packageName, activityName));
startActivity(shareIntent);
finish();

Это работает, за исключением общих папок, к которым прикреплены файлы. Там я получаю этот сбой:

java.lang.SecurityException: UID 10098 does not have permission to content://com.android.chrome.FileProvider/images/screenshot/15305419271134395322470190280016.jpg [user 0]
    at android.os.Parcel.readException(Parcel.java:1942)
    at android.os.Parcel.readException(Parcel.java:1888)
    at android.app.IActivityManager$Stub$Proxy.startActivity(IActivityManager.java:4365)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1610)
    at android.app.Activity.startActivityForResult(Activity.java:4472)
    at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
    at android.app.Activity.startActivityForResult(Activity.java:4430)
    at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:741)
    at android.app.Activity.startActivity(Activity.java:4791)
    at android.app.Activity.startActivity(Activity.java:4759)

Кажется, что моя деятельность не может выполнить первоначальное намерение, потому что у него нет разрешения на эти файлы. Что можно сделать, чтобы это исправить? Есть ли способ получить разрешение? Ведь андроид как-то тоже это делает.

Я попробовал несколько исправлений, но пока ничего не получалось. Если я не могу заставить его работать, я бы хотел вызвать обычное меню общего доступа из android, чтобы справиться с этим, но я тоже не могу заставить это работать.

addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

Не работает, так как эти флаги уже существуют в намерении. Удаление их, с другой стороны, приведет к тому, что общий ресурс будет работать, но файлы не будут переданы, он будет пустым.

startActivity(Intent.createChooser(shareIntent, "test");

Будет выбрасывать то же исключение.

startActivity(Intent.createChooser(intent, "test"));

Я пытался вызвать меню общего доступа для Android, выбрав первоначальное назначение, но оно просто дает мне окно, которое позволяет мне выбрать приложение.

intent.setComponent(null);
startActivity(Intent.createChooser(intent, "test"));

С другой стороны, это сработало, и я смог выбрать меню общего доступа для Android, но ничего не произошло, когда я попытался поделиться. Приложение будет работать так, как будто ничего не получено.

intent.setComponent(new ComponentName("android", "com.android.internal.app.ChooserActivity"));
startActivity(intent);

Делает именно то, что я хотел, открыть обычное меню обмена Android. Но остается одна проблема: независимо от доли, она ничего не делает. Я выбираю что-то, и это все, оно закрывается. Ничего больше. Почему это происходит? Я в основном запускаю то же самое намерение, что и старое приложение, и перенаправляю его на Android. Почему это больше не работает? Что я могу сделать?

Я читал, что права root могут быть необходимы для его работы, но, возможно, есть еще обходной путь? Или хотя бы способ вернуть исходное намерение обратно в меню общего доступа Android, не нарушая его?

При совместном использовании из некоторых приложений это работает, например, из галерей приложений. Все приложения, которые не вызывают проблем, используют URI, начиная с содержимого: //media/...

Кроме того, из моих исследований кажется, что это может иметь какое-то отношение к FileProvider, но кажется, что это должно быть сделано в приложении, которым я делюсь, а не в моем приложении, поэтому я не могу сделай что-нибудь с этим.

Также обратите внимание, что я НЕ создаю намерение общего ресурса, а получаю и отправляю его в другое приложение.

Вот этот трекер от google

1 Ответ

0 голосов
/ 13 июля 2018

Я думаю, вам нужен FileProvider в вашем приложении. В Lollipop произошла смена файлов. Для начала вы создаете провайдера в AndroidManifest.xml

Шаг 1:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.mydomain.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

Шаг 2 : Создать и определить file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="image" path="image/"/>
    <external-path name="externalPath" path="external/path"/>
    <cache-path name="cachePath" path="./" />
</paths>

Зависит от того, куда вы поместите файл для совместного использования, вы должны поместить их в правильный атрибут, files-path, external-path, cache-path. Проверьте здесь для получения дополнительной информации.

Шаг 3 : Код обмена.

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
    File imagePath = new File(Context.getFilesDir(), "images");
    File newFile = new File(imagePath, "default_image.jpg");
    Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
    intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
}else{
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
}

startActivity(intent);   
...