• 0
x11

BroadcastReceiver.OnReceive срабазывает 2 раза

Вопросы

Так и должно быть, что событие "BroadcastReceiver.OnReceive" срабатывает 2 раза подряд?

Код создания. Проверял: создается только один BroadcastReceiver.

procedure TDMSrv.CreateBroadcastReceiver;
begin
  BroadcastReceiver := TCSBroadcastReceiver.Create(nil);
  BroadcastReceiver.OnReceive := BroadcastReceiverOnReceive;
  BroadcastReceiver.RegisterReceive;
  BroadcastReceiver.Items.Clear;
  BroadcastReceiver.Add(PHONE_STATE);
  BroadcastReceiver.Add(NEW_OUTGOING_CALL);
  Log('CreateBroadcastReceiver');
end;

 

Сам код события:

procedure TDMSrv.BroadcastReceiverOnReceive(csContext: JContext; csIntent: JIntent);
begin
  log('BroadcastReceiverOnReceive');
  CheckPhoneCallState(csContext, csIntent);
end;

 

Ну и сама процедура обработки:

procedure TDMSrv.CheckPhoneCallState(Context: JContext; Intent: JIntent);
var
  telephonyService: JObject;
  telephonyManager: JTelephonyManager;
  state: JString;
  incomingCallNumber: string;
  outgoingCallNumber: string;
  outputResult: string;
begin
  Log('CheckPhoneCallState: ' + JStringToString(Intent.getAction));
  outputResult:= sLineBreak;

  telephonyService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
  telephonyManager := TJTelephonyManager.Wrap((telephonyService as ILocalObject).GetObjectID);

  if JStringToString(Intent.getAction).Equals(PHONE_STATE) then
  begin
    state := Intent.getStringExtra(TJTelephonyManager.JavaClass.EXTRA_STATE);

      if state.equals(TJTelephonyManager.JavaClass.EXTRA_STATE_IDLE) then
        outputResult:= outputResult + 'Phone is IDLE ' + sLineBreak
      else
        if state.equals(TJTelephonyManager.JavaClass.EXTRA_STATE_RINGING) then
        begin
          incomingCallNumber := JStringToString(Intent.getStringExtra(TJTelephonyManager.JavaClass.EXTRA_INCOMING_NUMBER));
          if incomingCallNumber.Equals('') then
            incomingCallNumber:= 'PRIVATE NUMBER';

          outputResult := outputResult + 'Phone is RINGING' + sLineBreak;
          outputResult := outputResult + 'Incoming call from ' + incomingCallNumber + sLineBreak;
          LaunchNotification(incomingCallNumber, 'Входящий вызов');
          InsertTel(incomingCallNumber, True);
        end
      else
        if state.equals(TJTelephonyManager.JavaClass.EXTRA_STATE_OFFHOOK) then
          outputResult:= outputResult + 'Phone is OFFHOOK' + sLineBreak;
  end
  else
    if JStringToString(Intent.getAction).Equals(NEW_OUTGOING_CALL) then
    begin
      outgoingCallNumber:= JStringToString(Intent.getStringExtra(TJIntent.JavaClass.EXTRA_PHONE_NUMBER));
      outputResult:= outputResult + 'Outgoing call to ' + outgoingCallNumber + sLineBreak;
      LaunchNotification(outgoingCallNumber, 'Исходящий вызов');
      InsertTel(outgoingCallNumber, False);
    end;

  Log(outputResult);
end;

 

Screenshot_1.png

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

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


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

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

  • 0

Что-то мне кажется, если подпись идет на два типа событий: "отслеживание входящего звонка" и "смена состояния телефона", то логично, что событие срабатывает два раза.

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


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

Проблема в том, что и код добавления записи в базу "InsertTel(incomingCallNumber, True);" тоже срабатывает дважды.

Да и обратите внимание, что срабатывает одно и то же событие дважды - PHONE_STATE

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

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


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

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


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

Пробовали регистрировать ресивер не программно, а через манифест файл?

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


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

Пробовали регистрировать ресивер не программно, а через манифест файл?

Пробовал когда-то. Но я не знаю, какую мою процедуру прописывать в манифест. Ведь мои процедуры работают внутри FMX и Android их не видит.

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


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

И еще убедитесь по логам, что вы не создали случайно два ресивера.


Проверял.

14 часа назад, x11 сказал:

Проверял: создается только один BroadcastReceiver.

 

ещё раз перепроверю

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


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 31.01.2018 в 23:41, Brovin Yaroslav сказал:

"отслеживание входящего звонка" и "смена состояния телефона", то логично, что событие срабатывает два раза.

Событие "android.intent.action.PHONE_STATE" - это и есть отслеживание входящего звонка, т.е. смена состояния телефона.  Других событий для отслеживания входящего звонка вроде бы нету. Если есть, подскажите решение. Спасибо.

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


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 31.01.2018 в 23:55, Brovin Yaroslav сказал:

И еще убедитесь по логам, что вы не создали случайно два ресивера.

http://blog.mmarvick.com/blog/lollipop-multiple-broadcastreceiver-call-state/

это проблема андроида

Screenshot_1.png

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


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

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

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

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

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

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

Войти

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

Войти


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

    • От tromani
      Собственно сабж, перенес из основной программы в сервис ничего не работает может чтото не так делаю подскажите
      смысл в том чтоб в сервисе обрабатывать входящие смс
      unit utMainsmsResolver; interface uses System.SysUtils, System.Classes, System.Android.Service, AndroidApi.JNI.GraphicsContentViewText, Androidapi.JNI.Os, Androidapi.JNI.App, CSBroadcastReceiver, Androidapi.JNI.JavaTypes, IdHTTP, IdCoderMIME,RR.HTTPwider, Androidapi.Jni, Androidapi.Helpers, Androidapi.JNI.Provider, Androidapi.JNI.Net, Androidapi.JNIBridge, Androidapi.JNI.Telephony; type TDM = class(TAndroidIntentService) function AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; procedure AndroidServiceDestroy(Sender: TObject); private { Private declarations } public { Public declarations } procedure CreateBroadcastReceiver; procedure BroadcastReceiverOnReceive(csContext: JContext; csIntent: JIntent); procedure CheckSmsInState(Context: JContext; Intent: JIntent); end; var DM: TDM; BroadcastReceiver: TCSBroadcastReceiver; implementation {%CLASSGROUP 'FMX.Controls.TControl'} {$R *.dfm} procedure TDM.CreateBroadcastReceiver; begin if not Assigned(BroadcastReceiver) then begin BroadcastReceiver:= TCSBroadcastReceiver.Create(nil); BroadcastReceiver.OnReceive:= BroadcastReceiverOnReceive; BroadcastReceiver.RegisterReceive; BroadcastReceiver.Add('android.provider.Telephony.SMS_RECEIVED',-1); end; end; procedure TDM.BroadcastReceiverOnReceive(csContext: JContext; csIntent: JIntent); begin CheckSmsInState(csContext, csIntent); end; procedure TDM.CheckSmsInState(Context: JContext; Intent: JIntent); begin // чтото делаем с смс end; procedure TDM.AndroidServiceDestroy(Sender: TObject); begin if Assigned(BroadcastReceiver) then FreeAndNil(BroadcastReceiver); end; function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; begin CreateBroadcastReceiver; Result:=TJService.JavaClass.START_STICKY; //CreateBroadcastReceiver; end; пробовал метод 
      CreateBroadcastReceiver
      вставлять и до и после start_sticky и в onCreate результат один ничего не происходит
      версия IDE - berlin
      повторюсь если в коде основной программы то все работает на ура
    • От ENERGY
      Привет.
      Для отправки смс используется SMSManager  и его функция.
      smsManager.sendTextMessage(smsTo, nil, StringToJString('Test SMS'), nil, nil); Описание ее на сайте developer.android.com . Для того чтобы узнать статус отправлена смс или нет, нужно указать предпоследний параметр 
      sentIntent PendingIntent: if not NULL this PendingIntent is broadcast when the message is successfully sent, or failed. The result code will be Activity.RESULT_OK for success, or one of these errors:
      RESULT_ERROR_GENERIC_FAILURE
      RESULT_ERROR_RADIO_OFF
      RESULT_ERROR_NULL_PDU. Я также нашел описание как добавить этот параметр на StackOverflow, но там не указаны детали. 
      Вот что пишет этот человек:  You have to createIntent objects first, THEN create PendingIntent objects to wrap those Intent objects, THEN pass the PendingIntent objects to sendTextMessage() and use a broadcastReceiver to receive the Intent objects.
       
      Итак я создаю интент, и оборачиваю его в PendingIntent по аналогии со статьей Андрея Ефимова: 
       // Создаём Интент
      Intent := TJIntent.Create; Intent.setClassName(TAndroidHelper.Context, StringToJString('com.TestReceiver.AlarmReceiver')); // Оборачиваем Интент в PendingIntent
      PendingIntent := TJPendingIntent.JavaClass.getBroadcast(TAndroidHelper.Context, 1, Intent, 0);
      И вставляю это PendingIntent в код sendTextMessage
       
      Когда вернутся код ошибки SMS, то насколько я понял сработает ява код, на который зарегистрирован прием: 
      package com.TestReceiver;   import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent;   public class AlarmReceiver extends BroadcastReceiver {     public void onReceive(Context context, Intent intent) {             Intent TestLauncher = new Intent();             TestLauncher.setClassName(context, "com.embarcadero.firemonkey.FMXNativeActivity");             TestLauncher.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);             context.startActivity(TestLauncher);     } }  
      Вопрос в следующем: 
      Как мне эту цифру с ошибкой  Activity.RESULT_OK (или RESULT_ERROR_GENERIC_FAILURE или любой другой) вытащить оттуда и передать в программу?
      Upd1:
      Это результат вызова из Java кода метода getResultCode().
      Можно ли getResultCode вызвать из Delphi, а не из Java кода?
       
       
       
    • От Pax Beach
      Из PlatformSDK (PlatformSDKs\android-sdk-windows\sources\android-23\android\support\v4\content\) портировал в Delphi класс TJLocalBroadcastManager.
      Это очень полезный класс, если вы не хотите рассылать сообщения по всей системе, а есть необходимость общаться только внутри приложения или между хост-приложением и сервисом.
      Во вложении сам класс, в своем приложении убедитесь, что в Target Platforms (Android) → Android → Libraries включена библиотека android-support-v4.dex.jar.
       
      Прилагаю пример, для изучения и использования в работе, который демонстрирует работу обычного BroadcastReceiver и LocalBroadcastReceiver.
      В примере демонстрируется работа сообщений в приложении и сервисе. Сначала делаем build проекта LBCRService, потом будет доступна возможность собрать LocalBCR.
      Собираю в Berlin 10.1, но на младших версиях тоже должно работать, по крайней мере в Seatlle.
       
      В реализации методов
      procedure RegisterReceiver(); procedure UnRegisterReceiver(); необходимо снять комментарий с соответствующих строчек, в зависимости от того, какой тип ресивера вы хотите использовать.
       
       
      Androidapi.JNI.LocalBroadcastManager.pas.zip
      LocalBroadCastReceiver.zip
    • От AliZairov
      Здравствуй. Проект BroadcastReceiver библиотека.

      BroadcastReceiver.zip
  • Последние посетители   0 пользователей онлайн

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