2017-02-21 42 views
0

Я могу настроить приложение для Android для запуска в указанное время с помощью Android AlarmManager. Он работает хорошо, я использовал this руководство и this форум для деталей (используйте переводчик Google).Как передать логическое (или целое) намерение и прочитать его (чтобы обнаружить, что моя активность была запущена из Android AlarmManager)?

Так что я создаю DEX-файл из кода Java (из XE7 вы можете просто attach JAR без создания dex (!)). Для того, чтобы обнаружить, если Мое приложение было начато с AlarmManager я решил поставить булево вар намерению, используя this Java руководство от StackOverflow, так что я добавил в код Java строку:

TestLauncher.putExtra("StartedFromAM", true); 

Полный Java-код, который будет скомпилировано jar (или dex):

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); 
TestLauncher.putExtra("StartedFromAM", true); 
       context.startActivity(TestLauncher);   
     } 
    } 

Так что теперь в теории мое намерение имеет аргумент StartedFromAM.

Он компилируется в файл dex, проблема в том, что я не могу прочитать это логическое значение из кода Delphi - он всегда = 0 (false).

Я попытался это:

ShowMessage(SharedActivity.getIntent.getBooleanExtra(StringToJString('StartedFromAM'), false).ToString); 

ShowMessage(MainActivity.getIntent.getBooleanExtra(StringToJString('StartedFromAM'), false).ToString); 

Update 1

Благодаря г Blong я уже получил правильное решение о том, как определить, что моя деятельность была начата с Android AlarmManager, это обновление только о PutExtra в Java Code и чтении дополнительной ценности от намерения от Delphi. Вы можете пропустить его, если хотите.

Теперь я знаю, что могу подключать файлы JAR (у меня есть Berlin upd 2), без создания dex. Итак, я создал новый файл jar - полный код Java, который я показал выше. Затем я создал новый проект, и установки сигнализации с этим кодом

procedure SetAlarmWakeUpAdnroid(aSeconds: integer); 

     function getTimeAfterInSecs(Seconds: Integer): Int64; 
     var 
     Calendar: JCalendar; 
     begin 
     Calendar := TJCalendar.JavaClass.getInstance; 
     Calendar.add(TJCalendar.JavaClass.SECOND, Seconds); 
     Result := Calendar.getTimeInMillis; 
     end; 

    var 
     Intent: JIntent; 
     PendingIntent: JPendingIntent; 
     vRes: boolean; 
    begin 
     Intent := TJIntent.Create; 
     Intent.setClassName(TAndroidHelper.Context, StringToJString('com.embarcadero.firemonkey.FMXNativeActivity')); 

     PendingIntent := TJPendingIntent.JavaClass.getActivity(TAndroidHelper.Context, 1, Intent, 0); 

     TAndroidHelper.AlarmManager.&set(TJAlarmManager.JavaClass.RTC_WAKEUP, getTimeAfterInSecs(30), 
     PendingIntent); 
    end; 

    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
     SetAlarmWakeUpAdnroid(30); 
    end; 

Затем я добавил OnFormCreate событие

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    ShowMessage('StartedFromAM =' + TAndroidHelper.Activity.getIntent.getBooleanExtra(StringToJString('StartedFromAM'), false).ToString); 
    ShowMessage('EXTRA_ALARM_COUNT = ' + TAndroidHelper.Activity.getIntent.getIntExtra(TJIntent.JavaClass.EXTRA_ALARM_COUNT, 0).ToString); 
end; 

Когда менеджер Alarm начал мое приложение, я получил EXTRA_ALARM_COUNT = 1 и StartedFromAM = 0.

ответ

1

Есть несколько вещей, чтобы ответить в ответ на этот вопрос:

1) Принцип работы прекрасен. Если код Java был правильно составлен и правильно связаны, а затем, когда ваша деятельность вызывается AlarmManager через ваш BroadcastReceiver, код, как это будет работать, как вы ожидаете:

uses 
    Androidapi.Helpers, 
    Androidapi.JNI.GraphicsContentViewText; 
... 
var 
    Intent: JIntent; 
... 
    Intent := TAndroidHelper.Activity.getIntent; 
    if Intent.getBooleanExtra(StringToJString('StartedFromAM'), False) then 
    lblInfo.Text := 'Started by Alarm Manager through Broadcast Receiver'; 

2) Существует потенциал Гоча с Включение Delphi файлов Java .jar. В отсутствие каких-либо дополнительных доказательств я предполагаю, что вы попали в эту ситуацию, когда ваш код выглядит жизнеспособным, но, похоже, не работает.

При работе с файлом .jar, который включен в проект Android в Delphi, если вы измените или перестройте файл .jar, у Delphi есть острая тенденция не заметить, что он был обновлен, и поэтому все еще ссылки в вашем изначально добавлена ​​версия .jar.

Чтобы преодолеть это, вы можете очистить проект (щелкните правой кнопкой мыши по имени проекта в дереве управления Менеджером проекта и выберите «Очистить»). Если вы хотите быть совершенно определенно уверен, что вы обратились к проблеме, вы должны:

  1. чистого проект (обеспечение каталог Android выхода проекта получает удален)
  2. удалить файл .jar из Android проекта, библиотеки список
  3. закрыть проект в Delphi
  4. восстановить ваш файл .jar
  5. возобновить проект в Delphi
  6. повторно добавить файл .jar в Android проекта, список библиотек

Я сам попал в эту проблему, глядя на этот сценарий диспетчера аварий.

Примечание. Я обращаюсь к файлу .jar. Это то, что вы добавляете в свой проект от Delphi XE7 onwards. В XE6 you must create a merged classes.dex file из классов.dex Delphi и вашего .jar-файла и работать с этим, и поскольку вопрос относится к созданию файла DEX, может быть, проблема возникает в соответствии с предписанными шагами? Это гораздо более громоздкое упражнение, чем добавление к проекту .jar.

3) linked source article охватывает 2 варианта вызова приложения из AlarmManager. Вы посмотрели на подход, который поступает через широковещательный приемник, который вы реализовали на Java, - что добавило вам осложнений, чтобы создать его.

В другом подходе, указанном в этой статье, есть AlarmManager, непосредственно инициирующий вашу деятельность. Теперь вы можете сказать: «Ну, как я узнаю, была ли эта активность запущена с помощью сигнала тревоги, когда мой вещательный приемник не работает?» и ответ будет заключаться в том, что намерение активности автоматически будет содержать целое число, добавленное под номером EXTRA_ALARM_COUNT.

Это означает, что вы можете написать код, как это, например, в обработчике события OnCreate, и полностью избежать настраиваемого кода Java:

uses 
    Androidapi.Helpers, 
    Androidapi.JNI.GraphicsContentViewText; 
... 
var 
    Intent: JIntent; 
... 
    Intent := TAndroidHelper.Activity.getIntent; 
    if Intent.getIntExtra(TJIntent.JavaClass.EXTRA_ALARM_COUNT, 0) > 0 then 
    lblInfo.Text := 'Started by Alarm Manager through FMX Activity'; 

4) Вы заметите, что я использую TAndroidHelper.Activity вместо SharedActivity. Последний перешел к первому в Delphi 10 Seattle.

+0

Спасибо Блонгу! EXTRA_ALARM_COUNT работает хорошо. Я также попытался поместить Extra из Java Code снова как логическое и целое, с другими именами. Я также удалил этот файл dex из Delphi Deployment> очищенный проект> удаленная папка отладки>, а затем снова создал dex> сборку и развертывание проекта - и до сих пор не смог получить ее из намерения. Возможно, он не добавляет лишние поля или удаляет этот код. Btw Я получил свой класс.dex (от debug classes.dex) размером 2,5 мб (Delphi Berlin update 2). Еще раз спасибо за сообщение об EXTRA_ALARM_COUNT! – alitrun

+0

Ах да, вы создаете файл .dex. Это означает, что вы используете XE6 или, возможно, даже XE5, в крайнем случае. Я добавил примечание об этом, но я считаю, что это сильные разногласия. Я могу сказать, что у меня есть ваш код, работающий в Delphi 10.1 Berlin, с широковещательным приемником в отдельном файле .jar просто отлично - значения помещаются в намерение и проходят, как и ожидалось. Должна быть проблема в том, как вы получаете свой код в .dex или как на dex ссылается Delphi в вашем случае. У меня нет доступа к XE6, но я рад, что у вас есть способ прогресса. – blong

+0

Я могу подключить банку вместо DEX?Это новая информация для меня :) Я использую Delphi Berlin upd 2. И спасибо за Блонга снова, теперь я могу просто соединить банку! :) Btw Я обновил вопрос - я не могу читать boolean от намерения даже с jar на новом проекте с последним Delphi. Но вы можете пропустить этот вопрос, я уже получил ответ - это просто академический интерес. – alitrun

 Смежные вопросы

  • Нет связанных вопросов^_^