Перейти к содержанию
Fire Monkey от А до Я
  • 0

"Общение" сервиса и приложения через intent


Rusland

Вопрос

Пишут про некие intent, с помощью которых можно наладить "общение" между сервисом и приложением.

Расскажите как это делается? Поделитесь кодом, чтобы в голове прояснилось :)

Ссылка на комментарий

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

  • -1
  • Модераторы

В стандартном примере все есть, в соседней теме выкладывал. Смотрим в книгу... Не надо плодить однотипные темы, внимательно изучайте материал

Ссылка на комментарий
  • 0

Если речь про AndroidNotificationServiceDemo, то действительно не вижу никаких intent там. Вижу в сервисе вызов Notification через NotificationCenter1 и чтение из этого Notification в OnReceiveLocalNotification и все. 

Ищу в коде этого приложения "JIntent" и не нахожу.

 

Из-за непонимания, я скорее всего и задаю не верно вопрос.

Изменено пользователем Rusland
Ссылка на комментарий
  • 3

Для ищущих ответа:

Есть стандартное demo Object Pascal\Mobile Snippets\AndroidIntents\AndroidIntentsGroup.groupproj, в котором показано как из одного приложения передавать данные другому. С помощью этого примера удалось передавать данные из сервиса в основное приложение.

В юните основного приложения пишем:

uses FMX.Platform, FMX.Platform.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net, Androidapi.JNI.Os, 
  Androidapi.Helpers, System.Messaging, Androidapi.JNI.GraphicsContentViewText;

  private
    { Private declarations }
    function HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean; 
    procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);  
    function HandleIntentAction(const Data: JIntent): Boolean;  

procedure TForm1.FormCreate(Sender: TObject);
var
  AppEventService: IFMXApplicationEventService;
begin
...
  if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then
    AppEventService.SetApplicationEventHandler(HandleAppEvent);

  // Register the type of intent action that we want to be able to receive.
  // Note: A corresponding <action> tag must also exist in the <intent-filter> section of AndroidManifest.template.xml.
  MainActivity.registerIntentAction(TJIntent.JavaClass.ACTION_VIEW);
  TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage);
end;


procedure TForm1.HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
  if M is TMessageReceivedNotification then
    HandleIntentAction(TMessageReceivedNotification(M).Value);
end;

function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
var
  StartupIntent: JIntent;
begin
  Result := False;
  if AAppEvent = TApplicationEvent.BecameActive then
  begin
    StartupIntent := MainActivity.getIntent;
    if StartupIntent <> nil then
      HandleIntentAction(StartupIntent);
  end;
end;

function TForm1.HandleIntentAction(const Data: JIntent): Boolean;
var
  Extras: JBundle;
begin
  Result := False;
  if Data <> nil then
  begin
    Memo1.ClearContent; // записываем в Memo пришедшее сообщение
    Extras := Data.getExtras;
    if Extras <> nil then
      Memo1.Text := JStringToString(Extras.getString(TJIntent.JavaClass.EXTRA_TEXT));
    Invalidate;
  end;
end;

в AndroidManifest.template.xml добавляем 

<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="text/pas" />

Отправка сообщения из сервиса делается так:

SendTextViaIntent('Hello from service');

procedure TAndroidServiceDM.SendTextViaIntent(const AText: string);
var
  Intent: JIntent;
begin
  Intent := TJIntent.Create;
  Intent.setType(StringToJString('text/pas'));
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK); // добавил такой флаг, без  него сервис затыкался
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(AText));
  if  TJContextWrapper.Wrap(System.JavaContext).getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
     TJContextWrapper.Wrap(System.JavaContext).startActivity(Intent); // заменил MainActivity на TJContextWrapper.Wrap(System.JavaContext), т.к. это сервис
end;
Работает исправно, хоть 100%-ую правильность кода не гарантирую  :)

Но как передать сообщение из основной программы обратно в сервис я пока не знаю. Также делать хендл внутри сервиса? 

Попытался просто добавить FMX.Platform, в результате получаю ошибку в FMX.Platform.Android вываливается ошибка об использовании Activity внутри сервиса.
Ссылка на комментарий
  • 0

Установил приложение на планшет Lenovo Tab2 c Android 5.0.2 и теперь при отправке сообщения и сервиса появляется диалог с предложением открыть в моей программе или ES проводник :)

На что заменить android:mimeType ="text/pas" чтобы гарантированно ни одна программа не могла бы получать сообщение?

PS. Похоже ES проводник реагирует на слово text. Нужно его просто заменить (и в коде и в манифесте должно быть одинаково)

PPS. Заметил странную вещь, если вызывать из сервиса так

TTask.Run(procedure
begin
  try
    // что-то делаю
  finally
    TThread.Synchronize(nil, procedure 
    begin 
      EndTime:='Код ответа'; SendTextViaIntent(EndTime); // сюда не заходит 
    end);
  end; 
end);

то интент не передается

Ссылка на комментарий
  • 0
Rusland
 
Спасибо большое, всё работает на ура. Вот только никак не могу добиться, чтоб сервис присылал сообщения втихую, не открывая приложения... Нет идей на эту тему?
Ссылка на комментарий
  • 0
  • Модераторы
12 часа назад, Adm123 сказал:

Форум я рыл, вроде, внимательно... Нельзя ли ссылку на тему?

Вы же читали сообщение Rusland, там написано где лежит пример...

Ссылка на комментарий
  • 0
6 минут назад, Andrey Efimov сказал:

Вы же читали сообщение Rusland, там написано где лежит пример...

Тут вышло недопонимание. Процитированный мной пост ZuBy вовсе не был обращен ко мне, но на тот момент почему-то отображался у меня последним. Видимо, форум после обновления не совсем "очнулся". Так что это не в счёт.

А пример из посла Rusland я, конечно, видел и передачи информации из сервиса в приложение добился. Проблема в другом - как сделать, чтоб приложение информацию принимало, но не вылезало рри этом на рабочий стол.

Ссылка на комментарий
  • 0
  • Модераторы

Ну, ситуация с кодом выше такая, есть флаг

FLAG_ACTIVITY_NEW_TASK

он то и вызывает Активность, нужно попробовать использовать другие флаги, список есть тут http://developer.android.com/reference/android/content/Intent.html

 

Ссылка на комментарий
  • 0

Intents — это намерения.

Intent Filter — это желание обслуживать намерения.

Принял (приложением) отправленный Intent — будь добр запуститься и обработать это намерение.

 

Не подходят для этой задачи startActivity, нужно использовать BroadcastReceiver и отправлять ему свой Intent:

procedure TMainScreen.SomeOneSaysMeWhatIamStupidAndIsentHim;
Begin
	TAndroidHelper.Context.sendBroadcast(Intent);
End;

procedure TMainScreen.FormActivate(Sender: TObject);
begin
  begin
    try
      TAndroidHelper.Context.registerReceiver(FReceiver, FIntentFilter);
    finally

    end;
  end;
end;

procedure TMainScreen.FormDeactivate(Sender: TObject);
begin
  try
    TAndroidHelper.Context.unregisterReceiver(FReceiver);
  finally

  end;
end;

 

Изменено пользователем Pax Beach
Ссылка на комментарий

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

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

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

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

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

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

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

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

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