Ich teile ein Bild, und dieser Code funktioniert für Geräte vor Android 6 ordnungsgemäß:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri uri = Uri.fromFile(new File(mFilename));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));
Ich bekomme jedoch den Toast-Fehler " kann keine leeren Dateien anhängen ", wenn ich versuche, mit Android 6 zu teilen.
Ich habe überprüft, dass die Datei vorhanden ist und nicht die Länge Null hat.
Hat jemand eine Lösung dafür?
Eine Einschränkung des Android 6.0-Laufzeitberechtigungssystems besteht darin, dass es Eckfälle geben wird, die Probleme verursachen. Sie haben Folgendes festgestellt: Versuchen Sie, eine Datei im externen Speicher für eine App freizugeben, für die keine Laufzeitberechtigungsprüfungen für diesen bestimmten UI-Pfad vorhanden sind.
Ich sage, dass dies ein "Eckfall" ist, da der Benutzer die App nicht zuvor verwendet und die erforderliche Berechtigung erteilt haben kann, damit dieser Fehler in der empfangenden App Auswirkungen auf den Benutzer hat. Entweder:
Der Benutzer hat diese App noch nie zuvor verwendet und versucht dennoch, Inhalte für ihn freizugeben, oder
Der Benutzer hat die Berechtigung über Einstellungen widerrufen, wusste jedoch nicht, dass diese Funktionalität beeinträchtigt würde
Beides sind Ereignisse mit niedriger Wahrscheinlichkeit.
Sie als Absender haben zwei Hauptoptionen:
Wechseln Sie statt der Verwendung von file://
Uri
-Werten zugunsten einer dateibedienenden ContentProvider
wie FileProvider
, sodass die Berechtigung nicht mehr benötigt wird
Nur mit dem Eckfall leben
Ich habe es gelöst, indem ich eine FileProvider
implementiert habe, wie von @CommonsWare vorgeschlagen
Sie müssen zuerst einen FileProvider konfigurieren:
fügen Sie zuerst den <provider>
zu Ihrem Dateiformat XML hinzu
<provider
Android:name="Android.support.v4.content.FileProvider"
Android:authorities="com.myfileprovider"
Android:exported="false"
Android:grantUriPermissions="true">
<meta-data
Android:name="Android.support.FILE_PROVIDER_PATHS"
Android:resource="@xml/file_provider_paths" />
</provider>
zweitens definieren Sie Ihre Dateipfade in einer separaten XML-Datei. Ich habe sie "file_provider_paths.xml" genannt.
<paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
<external-path name="share" path="/" />
</paths>
die vollständige Erklärung finden Sie auf dieser Dokumentationsseite
nachdem Sie Ihren Datei-Provider in XML eingerichtet haben, ist dies der Code zum Freigeben der Bilddatei:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri fileUri = FileProvider.getUriForFile(mContext, "com.myfileprovider", new File(mFilename));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));
Alternativ benötigen Sie keinen ContentProvider/FileProvider. Sie können einfach das Flag hinzufügen, das die Leseberechtigung für den gemeinsam genutzten URI gewährt. Insbesondere sollte share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
den Trick tun.
Eine andere Möglichkeit, dieses Problem zu umgehen, bestand darin, URI mit MediaScannerConnection
direkt nach dem Schreiben Ihrer Datei in das öffentliche Verzeichnis zu erstellen:
MediaScannerConnection.scanFile(context, new String[] {imageFile.toString()}, yourMimeType, new OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
//uri = "content://" style URI that is safe to attach to share intent
}
});
Dies kann eine kürzere Lösung für Ihre Bedürfnisse sein.