Einzelnen Beitrag anzeigen

Rollo62

Registriert seit: 15. Mär 2007
3.915 Beiträge
 
Delphi 12 Athens
 
#1

[Fmx, Android] ShowshareSheet Image -> Gmail verweigert Zugriff

  Alt 30. Mai 2016, 15:22
Hallo zusammen,

wenn man ein Bild per ShowShareSheet an GMail übergibt kommt eine kurze Fehlermeldung
"Der Zugriff auf den Anhang wurde verweigert", und das Bild wird nicht angenommen.
Im gleichen ShareSheet funktioniert es mit anderen Apps ohne Probleme.

Der Grund sollte sein das Gmail seit 5.0 nur noch Bilder aus dem Externen Speicher akzeptiert.
Siehe hier und hier.

Dummerweise nimmt der shareSheetManager das Bild und speichert es unter einem Temporären PNG ab, zum Versenden.

Delphi-Quellcode:
procedure TSharingManagerAndroid.AddImage(var AIntent: JIntent; const AImage: TBitmap);
var
  ImageFile: JFile;
  ImageUri: Jnet_Uri;
  FileNameTemp: JString;
  ArrayList: JArrayList;
begin
  Assert(AIntent <> nil);
  Assert(AImage <> nil);

  // Save image into shared file 'attachment.png'
  FileNameTemp := StringToJString('attachment.png');
  TAndroidHelper.Activity.openFileOutput(FileNameTemp, TJContext.JavaClass.MODE_WORLD_READABLE);
  ImageFile := TAndroidHelper.Activity.getFileStreamPath(FileNameTemp);
  ImageUri := TJnet_Uri.JavaClass.fromFile(ImageFile);
  AImage.SaveToFile(JStringToString(ImageFile.getAbsolutePath));

  if FDataType = TSharingDataType.Image then
    AIntent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, TJParcelable.Wrap((ImageUri as ILocalObject).GetObjectID))
  else
  begin
    // If we use ACTION_SEND_MULTIPLE action of Intent, we should put image throught Parcelable Array List.
    // Because in this case other application read EXTRA_STREAM like a ArrayList<Uri>
    ArrayList := TJArrayList.Create;
    ArrayList.add(ImageUri);
    AIntent.putParcelableArrayListExtra(TJIntent.JavaClass.EXTRA_STREAM, ArrayList);
  end;
end;
Der Hinweis aus StartActivityForResult ist interessant, aber in der ShareSheetLibrary wird das schon gemacht.

Delphi-Quellcode:
procedure TSharingManagerAndroid.Share(const AControl: TControl; const AText: string; const AImage: TBitmap);

  function DefineDataTypes: TSharingDataType;
  var
    DataType: TSharingDataType;
  begin
    DataType := TSharingDataType.None;
    if not AText.IsEmpty and (AImage <> nil) and not AImage.IsEmpty then
      DataType := TSharingDataType.Any
    else if not AText.IsEmpty then
      DataType := TSharingDataType.Text
    else if (AImage <> nil) and not AImage.IsEmpty then
      DataType := TSharingDataType.Image;

    Result := DataType;
  end;

var
  Intent: JIntent;
  IntentChooser: JIntent;
  ChooserCaption: string;
begin
  FDataType := DefineDataTypes;
  if FDataType <> TSharingDataType.None then
    try
      Intent := CreateSharingIntent(FDataType);
      case FDataType of
        TSharingDataType.Image: AddImage(Intent, AImage);
        TSharingDataType.Text: AddText(Intent, AText);
        TSharingDataType.Any:
          begin
            AddText(Intent, AText);
            AddImage(Intent, AImage);
          end;
      end;

      { Create chooser of activity }
      ChooserCaption := GetChooserCaption(FDataType);
      IntentChooser := TJIntent.JavaClass.createChooser(Intent, StrToJCharSequence(ChooserCaption));
      TAndroidHelper.Activity.startActivityForResult(IntentChooser, 0);
    finally
      FDataType := TSharingDataType.None;
    end;
end;
Ich vermute mal ich müsste jetzt auch für FMX.MediaLibrary.Android einen Hack schreiben, oder gibt es einen
"sanfteren" Weg um das hinzubekommen ?
Gibt es noch andere Apps die so ein Verhalten zeigen ?

Rollo
  Mit Zitat antworten Zitat