• 0
Tovenar

Отправка файлов через намерение

Вопросы

Как правильно отправлять файлы через ACTION_SEND. То что пробовал и не смог заставить работать:

uses System.IOUtils, FMX.Helpers.Android,Androidapi.JNI.JavaTypes, Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText;     
procedure TMain.SendFileClick(Sender: TObject);    
var      
Intent: JIntent;    
begin      
Intent := TJIntent.Create;      
Intent.setAction(TJIntent.JavaClass.ACTION_SEND);      
Intent.setDataAndType(StrToJURI('file:' + TPath.Combine(TPath.GetSharedDownloadsPath, 'picture.png')), StringToJString ('image/png'));      
SharedActivity.startActivity(Intent);    
end;

или

var
Intent: JIntent;
begin
Intent := TJIntent.Create;
Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
Intent.setType(StringToJString('image/png'));
Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM , StringToJString('file:mnt/sdcard/pictures/1.png'));
SharedActivity.startActivity(Intent);

При чем с открытием(ACTION_VIEW) все в порядке:

var
  FileName, ExtFile: string;
  mime: JMimeTypeMap;
  ExtToMime: JString;
  Intent: JIntent;
  pathN:string;
begin
    FileName := Item.ItemData.Detail;
    try
      ExtFile := AnsiLowerCase(StringReplace(TPath.GetExtension(FileName), '.', '',[]));
      mime := TJMimeTypeMap.JavaClass.getSingleton();
      ExtToMime := mime.getMimeTypeFromExtension(StringToJString(ExtFile));


      Intent := TJIntent.Create;
      Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
      Intent.setDataAndType(StrToJURI('file:' + FileName), ExtToMime);
      SharedActivity.startActivity(Intent);
    except
      ShowMessage('Невозможно открыть файл!');
    end

end;

Хоть в моих примерах я и пытаюсь передать изображение (я в курсе, что в ActionList есть стандартное действие для отправки изображений), в итоге код будет использоваться для файлов любого типа. 

Как победить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 ответов на этот вопрос

  • 0

Путем поисков и мучений:

uses
  FMX.Helpers.Android,
  //  Androidapi.IOUtils,
  Androidapi.Helpers,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNIBridge,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.Net,
  Androidapi.JNI.Os;
...
var
  Intent  : JIntent;
  uri     : Jnet_Uri;
  j_file  : JFile;
  f_name  : string;
...  
begin
  // имя пересылаемого файла
  f_name := 'picture.png';
  // файл должен быть сохранен по пути: Androidapi.IOUtils.getExternalFilesDir
  // или тоже самое: GetPublicPath
  // К примеру:
  ...SaveToFile(TPath.Combine(TPath.GetPublicPath, f_name));
    
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString('....')); // тема, если нужно
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString('....'));    // текст сообщения, если нужно
  // прикрепляем файл
  j_file := SharedActivity.getExternalFilesDir(StringToJString(f_name));
  uri := TJnet_Uri.JavaClass.fromFile(j_file);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM,TJParcelable.Wrap((uri as ILocalObject).GetObjectID));
  Intent.setType(StringToJString('vnd.android.cursor.dir/email'));
  //
  SharedActivity.startActivity(Intent);
end;

Как приаттачить файл по любому другому пути не знаю.

Изменено пользователем Belov.V.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Путем поисков и мучений:

А вот у меня ваш код почему то не работает. При отправке файл вкладывается в сообщение

 

5857594.png

но до получателя письмо доходит без вложения. Кроме того, не получается программно добавить адрес получателя. Делаю так

Intent.putExtra( TJIntent.JavaClass.EXTRA_EMAIL, StringToJString( 'aaa@mail.ru' ) );

но поле "кому" остается пустым (на скрине это видно).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Заполнение поля "Кому:"

var
...
  JRecipient: TJavaObjectArray<JString>;
...
begin
  //
  JRecipient := TJavaObjectArray<JString>.Create(1);
  JRecipient.Items[0] := StringToJString('test@test.ru');
...
  Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, JRecipient);
...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Как вариант, почему нет присоединенного файла - проверьте сохранение файла именно по этому пути:

f_name := 'sample-temp.txt';
//f_path := TPath.Combine(Androidapi.IOUtils.getExternalFilesDir,f_name); // пусть именно такой
// или
f_path := TPath.Combine(TPath.GetSharedDocumentsPath, f_name);        // или тоже самое: GetPublicPath
...SaveToFile(TPath.Combine(TPath.GetSharedDocumentsPath, f_name));

// прикрепляем файл
j_file := SharedActivity.getExternalFilesDir(StringToJString(f_name));

 

В особенности заполнение j_file проверьте.
 
Тоже самое было, когда пробовал по другим путям файл отправки класть. Имя было, но не отправлялось.
 
Удачи!
 
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Заполнение поля "Кому:"

Спасибо, помогло!

 

по поводу пути, да, лежат именно в Androidapi.IOUtils.getExternalFilesDir. Буду разбираться.

Изменено пользователем estra

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

Заполнение поля "Кому:"

Спасибо, помогло!

 

по поводу пути, да, лежат именно в Androidapi.IOUtils.getExternalFilesDir. Буду разбираться.

 

 

Я такой вариант получал, когда j_file не верно записывал. См. выше

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Вот какая беда обнаружилась. Если прикреплять файл к письму руками, то размер файла определяется верно (на скрине слева), а если программно, то неверно (на скрине справа). Возможно проблема в этом, но почему так происходит, непонятно.
 
5866818.png
Belov.V, вы не могли бы выложить небольшой работающий примерчик, если не сложно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Вот пример. Соорудил, проверил, вроде работает.

 

Размер файла нормальный. Скриншеты на двух почтовых клиентах:

0_123121_f617be46_orig.png

 

0_123120_ecf605ab_orig.png

 

Upd: в RX небольшие изменения. См. второй пример. (для первого идут предупреждения, хотя тоже работает)

Sample-SendAttach.zip

Sample-SendAttach_RX.zip

Изменено пользователем Belov.V.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спасибо за пример, работает отлично. Осталось понять, почему у меня не работало. Если разберусь, отпишусь...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спасибо за пример, работает отлично. Осталось понять, почему у меня не работало. Если разберусь, отпишусь...

 

Проверьте вот это место в коде:

// прикрепляем файл

j_file := SharedActivity.getExternalFilesDir(StringToJString(f_name));

 

Обратите внимание, что там указано имя прикрепляемого файла без пути к нему. По описанию ситуации очень похоже на ошибку в этом месте.

Изменено пользователем Belov.V.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Обратите внимание, что там указано имя прикрепляемого файла без пути к нему. По описанию ситуации очень похоже на ошибку в этом месте.

Вы правы, ошибка оказалась именно в этом. Еще раз большое спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Подскажите где закралась ошибка. Процедура должна отправлять файл через намерение (файл текстовый). 

aFileName:='/storage/emulated/0/Download/test/тестовый файл для отправки.out.txt';

aComment:='Комментарий к файлу';

procedure ShareFile(aFileName, aComment : String);
var Intent    : JIntent;
    uri       : Jnet_Uri;
    AttachmentFile: JFile;
begin
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(aComment));
  AttachmentFile := TJFile.JavaClass.init(StringToJString(aFileName));
  Uri := TJnet_Uri.JavaClass.fromFile(AttachmentFile);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, TJParcelable.Wrap((Uri as ILocalObject).GetObjectID));
  Intent.setType(StringToJString('text/plain'));
  SharedActivity.startActivity(Intent);
end;

Наблюдаю следующее:

Gmail - все отлично, файл присоединён, комментарий в теме письма

DropBox - все отлично, файл передан

Google Drive - файл передан, но у него отрезано расширение (в папке лежит файл с именем "тестовый файл для отправки")

Yandex Disk - все работает

Облако Mail.ru  - предлагает создать текстовый файл ("Новый текстовый файл.txt"), в который записывает только две одинаковые строчки "Комментарий к файлу"

 

Уже весь мозг сломал. А заказчик требует работу через все эти системы.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

Подскажите где закралась ошибка. Процедура должна отправлять файл через намерение (файл текстовый). 

aFileName:='/storage/emulated/0/Download/test/тестовый файл для отправки.out.txt';

aComment:='Комментарий к файлу';

procedure ShareFile(aFileName, aComment : String);
var Intent    : JIntent;
    uri       : Jnet_Uri;
    AttachmentFile: JFile;
begin
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(aComment));
  AttachmentFile := TJFile.JavaClass.init(StringToJString(aFileName));
  Uri := TJnet_Uri.JavaClass.fromFile(AttachmentFile);
  Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, TJParcelable.Wrap((Uri as ILocalObject).GetObjectID));
  Intent.setType(StringToJString('text/plain'));
  SharedActivity.startActivity(Intent);
end;

Наблюдаю следующее:

Gmail - все отлично, файл присоединён, комментарий в теме письма

DropBox - все отлично, файл передан

Google Drive - файл передан, но у него отрезано расширение (в папке лежит файл с именем "тестовый файл для отправки")

Yandex Disk - все работает

Облако Mail.ru  - предлагает создать текстовый файл ("Новый текстовый файл.txt"), в который записывает только две одинаковые строчки "Комментарий к файлу"

 

Уже весь мозг сломал. А заказчик требует работу через все эти системы.

 

 

 

 

Goggle Drive в качестве имени ставит то, что указано в Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(aComment));

Т.е. прописывайте в это поле имя файла без пути,

 

Mail.ru не пробовал.

Изменено пользователем Belov.V.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От x11
      Хочу взять пример из этой темы:
      http://fire-monkey.ru/topic/1263-%D0%BE%D1%82%D0%BA%D1%80%D1%8B%D1%82%D0%B8%D0%B5-%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B8%D0%B7-image-%D0%B2-%D0%B3%D0%B0%D0%BB%D0%B5%D1%80%D0%B5%D0%B5/
      Но среда ругается на JIntent.
      Нажимаю Ctrl+Shift+A - пустота.
      Нажимаю F1 на Jintent - справка ничего не выдает.
      Смотрю пример из справки
      http://docwiki.embarcadero.com/CodeExamples/Berlin/en/FMX.Android_Intents_Sample
      Там тоже нет информации, что нужно подключить в USES.
      Ок, открыл сам пример из папки "C:\Users\Public\Documents\Embarcadero\Studio\18.0\Samples\Object Pascal\Mobile Snippets\AndroidIntents\ReceiveIntent"
      Среда подсказывает, что JInten живет в Androidapi.JNI.GraphicsContentViewText.
      Добавляю в свой модуль в USES Androidapi.JNI.GraphicsContentViewText, но мне среда выдает ошибку "Can not resolve Androidapi.JNI.GraphicsContentViewText"
    • От zonik
      Подскажите можно ли сделать Android активити, которое будет появляться в меню по намерению ACTION_SEND в неком приложении. При выборе моего активити, он должен будет запуститься и обработать полученный JIntent. Может есть у кого пример?
       
      Спасибо за внимание
    • От abwabw
      Хочу попробовать прикрутить к проекту для дроида googl-овское распознавание голоса. Нашёл пример реализации этой функции вот тут или тут.
      Помогите перевести на XE5 FM, вот этот кусок:
      package com.genisoft.inforino; import java.util.List; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.speech.RecognizerIntent; public class SpeechRecognitionHelper {     public static void run(Activity ownerActivity) {             startRecognitionActivity(ownerActivity);         }                 } private static void startRecognitionActivity(Activity ownerActivity) {      Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Голосовой поиск Inforino"); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);     intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "ru-RU"); ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);     }
    • От Kitty
      На планшете c Андроид 4.4.2 установлены root права. Из андроид маркета установлен MX плеер. В плеере установлена настройка, что он открывает на постоянной основе файлы mp4. Я пытаюсь из своей программы запустить на выполнение файл mp4. Для примера помещаю нужный мне файл mp4 в папку download. Код такой:
      //C++ Builder XE6 String VideoFileName = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetSharedDownloadsPath(), "file1.mp4"); if(FileExists(VideoFileName)) { system(("open " + AnsiString(VideoFileName)).c_str());//ничего не происходит ShowMessage(VideoFileName);// /mnt/internal_sd/Download/file1.mp4 } else { //сюда не попадаем ShowMessage(L"Не найден видео файл " + VideoFileName + L". Программа будет закрыта."); Application->Terminate(); } Ничего не происходит. Видео не воспроизводится. Как правильно?
    • От Alexey
      На платформе ios PDF открываются как обычные html страницы. Как открыть PDF в браузере на android?
    • От Brovin Yaroslav
      Чтобы добавить любое изображение в системную галерею изображений Андроида нужно:
      Получить универсальный URI к вашей картинке GetImageUri. Для этого сохраняем изображение (если изображение находится в памяти устройства, а не в файловой системе) в кэш приложения. Формируем намерение JIntent, что хотим добавить изображение. Задаем URI к картинке и делаем широковещательный запрос на все приложения, которые могут обработать наш запрос. // Сохранение изображения в кэш приложения и извлечение Url к этому файлу function GetImageUri(ABitmap: TBitmap): Jnet_Uri; var ImageFile: JFile; ImageUri: Jnet_Uri; FileNameTemp: JString; FileNameExt: JString; begin FileNameTemp := StringToJString('temp'); FileNameExt := StringToJString('.jpg'); try ImageFile := TJFile.JavaClass.createTempFile(FileNameTemp, FileNameExt); ImageUri := TJnet_Uri.JavaClass.fromFile(ImageFile); ABitmap.SaveToFile(JStringToString(ImageFile.getAbsolutePath)); finally Result := ImageUri; end; end; procedure AddPhotoToGallery(const APhoto: TBitmap); var Intent: JIntent; begin Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_MEDIA_SCANNER_SCAN_FILE); Intent.setData(GetImageUri(APhoto)); SharedActivity.sendBroadcast(Intent); end;
    • От la_coste
      Доброго времени суток, в процессе изучения Delphi XE5 возник такой вопрос:
      Возможно ли открыть к примеру HTML страницу из файловой системы устройства в браузере по умолчанию??
      Заранее спасибо)
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу