Перейти к содержанию
  • Регистрация
  • 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 есть стандартное действие для отправки изображений), в итоге код будет использоваться для файлов любого типа. 

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

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


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

Рекомендуемые сообщения

  • 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.

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


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

Здравствуйте, отцы и боги fm! Подскажите пожалуйста новичку..? Перерыл все, что мог, ответа не нашел. Тыкните пожалуйста носом, если есть какая-нибудь статья. Коротко о моей задаче. Приложение для андройда. Из забитого списка с БД формируется счет с использованием загруженного в TImage изображения (что-то вроде листа А4 с шапкой фирмы) и Canvas, накидывающего на него реквизиты, список товаров, сумму и прочее. С помощью ShowShareSheetAction1.Bitmap.Assign(IMG.Bitmap) отправляется клиенту. Проблема возникла, когда список товаров был больше, чем задумано. Ладно, через условия (if количество товаров > например, 60 then создаем динамический image и записываем остатки туда) можно перекидывать. Но, как отправить сразу эти 2 TImage? Пробовал

ShowShareSheetAction1.Bitmap.Assign(IMG.Bitmap);

ShowShareSheetAction1.Bitmap.Assign(IMG2.Bitmap);

Отправляет последнюю запись. Пробовал что-то вроде:

ShowShareSheetAction1.Bitmap.Assign(IMG1.Bitmap, IMG2.Bitmap); Выдает, естественно, ошибку.

Это как-нибудь вообще можно реализовать? Может, есть какая-нибудь альтернатива? Или, как в примерах выше, путем сохранения этих файлов в память и последующего присоединения?

Изменено пользователем Николай_1988

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


Ссылка на сообщение
Поделиться на другие сайты
  • 0
8 часов назад, Николай_1988 сказал:

Здравствуйте, отцы и боги fm! Подскажите пожалуйста новичку..? Перерыл все, что мог, ответа не нашел. Тыкните пожалуйста носом, если есть какая-нибудь статья. Коротко о моей задаче. Приложение для андройда. Из забитого списка с БД формируется счет с использованием загруженного в TImage изображения (что-то вроде листа А4 с шапкой фирмы) и Canvas, накидывающего на него реквизиты, список товаров, сумму и прочее. С помощью ShowShareSheetAction1.Bitmap.Assign(IMG.Bitmap) отправляется клиенту. Проблема возникла, когда список товаров был больше, чем задумано. Ладно, через условия (if количество товаров > например, 60 then создаем динамический image и записываем остатки туда) можно перекидывать. Но, как отправить сразу эти 2 TImage? Пробовал

ShowShareSheetAction1.Bitmap.Assign(IMG.Bitmap);

ShowShareSheetAction1.Bitmap.Assign(IMG2.Bitmap);

Отправляет последнюю запись. Пробовал что-то вроде:

ShowShareSheetAction1.Bitmap.Assign(IMG1.Bitmap, IMG2.Bitmap); Выдает, естественно, ошибку.

Это как-нибудь вообще можно реализовать? Может, есть какая-нибудь альтернатива? Или, как в примерах выше, путем сохранения этих файлов в память и последующего присоединения?

Я бы на вашем месте создавал не картинку, а к примеру PDF, там не будет проблем с несколькими страницами

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


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

    • От 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 пользователей онлайн

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

×
×
  • Создать...