Diese Seite mit anderen teilen ...

Informationen zum Thema:
Forum:
WinDev Forum
Beiträge im Thema:
12
Erster Beitrag:
vor 2 Jahren, 11 Monaten
Letzter Beitrag:
vor 1 Jahr, 1 Monat
Beteiligte Autoren:
Danny Lauwers, Ruben Sanchez Peña, KenKnight, popoy, Popoy

[WM19] Android Alarmmanager and BroadcastReceiver do not work ?

Startbeitrag von Danny Lauwers am 19.11.2014 13:55

Hi all,

I am trying to use the Android Alarmmanager to set an Intent to check and if not running start my Windev Mobile application again so that it keeps running even when closed by user or Android system. Only when they logoff the application is actualy closed.

I have created the following Java code:


public static void JKeepAliveAlarm()
{
try {
AlarmManager alarm;
Calendar cal;
PendingIntent alarmIntent;

// Retrieve the current activity
Activity tmpActivity = getCurrentActivity();

// Retrieve the current Context
Context tmpContext = getApplicationContext();

cal = Calendar.getInstance();
alarm = (AlarmManager)tmpContext.getSystemService(tmpContext.ALARM_SERVICE);
Intent myIntent = new Intent(tmpContext,AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(tmpContext, 0, myIntent, 0);

// Start every 30 seconds
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, alarmIntent);

Toast.makeText(tmpContext, "Keep Alive Alarm SET", Toast.LENGTH_LONG).show();
}
catch(Exception e) {
e.printStackTrace();
}
}


I call this from the project code at startup. The toast is displayed so alarm is running.

The Receiverclass is defined as:


public class AlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

try {
Toast.makeText(context, "Alarm - Start", Toast.LENGTH_LONG).show();

// Try to start the app if not allready running
// TODO

Toast.makeText(context, "Alarm - End", Toast.LENGTH_LONG).show();
}
catch(Exception e) {
e.printStackTrace();
}
}
}


If the alarm would trigger I would see the toast on the screen. But nothing is executed, the receiver is not called ??!

I also added the Receiver to the Manifest:

[attachment 1247 ManifestPart.png]

I checked via the adb shell dumpsys alarm > dump.txt the status of the alarms and the alarm is created and is firing its event.

RTC_WAKEUP #0: Alarm{43854bb0 type 0 com.xxxx.yyyy}

type=0 when=+5s605ms repeatInterval=30000 count=1

operation=PendingIntent{432cadd0: PendingIntentRecord{430215c0 com.xxx.yyyy broadcastIntent}}

+1m38s35ms running, 101 wakeups, 101 alarms: com.xxx.yyyy

cmp={com.xxxx.yyyy/com.xxxx.yyyy.AlarmReceiver}

But my receiver is never called ? :confused:

I tried different names in the Manifest, but nothing seems to work.

I also use the alarmManager for updating the application by running an APK file after the program is closed, and this works fine.

I checked several Android sources on the internet and the basic configuration is in place. Being:

  • Create a class AlarmReceiver
  • Create a PendingIntent and setup this via the Alarmmanager
  • Change the Manifest to define the receiver


Does anybody has a working broadcast receiver in Windev Mobile 19 and can tell me what I am doing wrong ? Maybe there is something missing ?

Hope you can help me !
Thanks
Danny

Antworten:

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

Hi,

I got the anwser to my own question; after some hours of reseach and testing. :)

I’ve by chance found how to work with Broadcast receivers. The clue is to use the correct name in the definition of the receiver in the manifest.

When having this class


public static class AlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

try {
// Retrieve the current Context
Context tmpContext = getApplicationContext();

Toast.makeText(tmpContext, "test - Start", Toast.LENGTH_LONG).show();

// Stuff todo

Toast.makeText(context, "Awake CareApp - End", Toast.LENGTH_LONG).show();
}
catch(Exception e) {
e.printStackTrace();
}
}
}



And the alarm is triggerd by this


public static void JKeepAliveAlarm()
{
try {
AlarmManager alarm;
Calendar cal;
PendingIntent alarmIntent;

// Retrieve the current activity
Activity tmpActivity = getCurrentActivity();

// Retrieve the current Context
Context tmpContext = getApplicationContext();

cal = Calendar.getInstance();
alarm = (AlarmManager)tmpContext.getSystemService(tmpContext.ALARM_SERVICE);
Intent myIntent = new Intent(tmpContext,AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(tmpContext, 0, myIntent, 0);

// Start every 30 seconds
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, alarmIntent);

Toast.makeText(tmpContext, "Keep Alive Alarm SET", Toast.LENGTH_LONG).show();
}
catch(Exception e) {
e.printStackTrace();
}
}



The alarm is triggered every 30 seconds and firing the alarm intent.

When defining this in the manifest under the application node

[attachment 1270 manifest2.png]

Will link the alarm correctly to the code to execute.

The problem was that the name must be correct, you have to look inside the android folder where the code is generated and look inside the wdgen folder. And look for your class that contains the AlarmReciever.class code.
This wdgen folder is a deep subfolder of the "Android\Generation" folder under you project folder.

Then you have to build the .wdgen.GWDCPCOL_Java$AlarmReceiver string to match the correct location of your class and use this as the android:name of you receiver node.

!! This is not a Java thing, but a PCSoft Windev Mobile Android thing. Because Windev Mobile compiles the android application in a special way, you need to now the naming convention of PC-Soft in order to set your manifest correctly. I did not found any of this info in the help or on a forum, and this is crucial to get some native android functionality working within your WinDev Mobile Android application.

I have reported this to PC-Soft with the request to include this in the online help.

Once you have the name correct, the broadcast receiver is working. This opens up a lot of Android Native functionality because alot of things are working with broadcastreceivers.

Hope this may help some of you to natively extend there Windev Mobile Android application.
If you do find some interesting Native code that is working with WinDev Mobile Android applications todo some cool stuff, please do share this on the forum as well !

Have a nice day
Danny

von Danny Lauwers - am 10.12.2014 14:26

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

How do you Create The class Java AlarmReceiver in Windev Mobile ?


von Popoy - am 11.12.2014 23:27

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

Hi,

You make global procedures and create a function in it. I Call it "InitClasses", you make this a Java function not a W Language function. (This is in the front of the function header where you see WL or Java, you can click on this to change it.

See: http://doc.pcsoft.fr/en-US/?9000011&name=Entering_Java_code for more info

Then you make this function completely empty. Then start in the top with writing the needed import statements:

for example:

import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;


Depending on what android Java functionality you need you need to add the correct imports else you will get a Java compiler error when you create the APK file.

Then you can create classes below the import lines


public static class AlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

try {
// Retrieve the current Context
Context tmpContext = getApplicationContext();

//// Do your stuff here
}
catch(Exception e) {
e.printStackTrace();
}
}
}


Depending on the need it has to be static or not. It depends on what class your making etc... Static classes can be used directly without a need for an instance. Other classes need an instance first before you can use them. You have to call some Java code todo this.

If your application is still alive, you could call via CallWLProcedure a WLanguage function todo some stuff. But remember that the alarmReciever will also be run (depending on how you set the alarm) when your application is not running or is destroyed by the system. In that case calling a function from your program does not work. So you have to take care of exceptions and null pointers.

Hope this helps in creating the class.

Danny

von Danny Lauwers - am 12.12.2014 08:27

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

Hi,

I insert the imports

import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.widget.Toast;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;


But I have
Warning: Parentheses not found
with line

public static class AlarmReceiver extends BroadcastReceiver {

von popoy - am 12.12.2014 10:20

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

popoy,

This is "normal". Just ignore the warnings if no error occurs at compile time.

I have reported this behavior to PC-Soft

Danny

von Danny Lauwers - am 12.12.2014 15:00

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

Does anyone have a working example of working with the Intents. I got a small test app compiled and installed but anytime the phone rings, I get a message stating the "name_of_App" stopped working.

I'm using the static method of defining the Broadcast receiver in the xml file.

Any suggestions?

Thanks,
Ken

von KenKnight - am 10.02.2015 13:10

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

Hi Ken,

Could you gives some code to see if we can find the error. I am using intents and Alarmmanager and Broadcastreceivers without problems.

Danny

von Danny Lauwers - am 10.02.2015 14:38
Hi Danny,

Terribly sorry for the delayed response. The day after I posted the above message, my stink'n macbook OS crashed. Sadly I was unable to restore the images in their entirety, so I had to rebuild both mac and windows from scratch and then restore individual directories / files from the images. Complete PITA, but at least I'm now functional again.

I threw together a quick sample program that I'm testing all this with. It is located at http://www.windevtutorials.com/downloads/AndroidService.zip

If you have time to take a look at it I would greatly appreciate it.

Here's what I'm trying to accomplish: I just finished building a nice big workshop for building stuff with wood, metal and electronics (basically a hobby shop). Since I'm going to be spending a fair amount of time in there running loud equipment (table saws, lathes, welders) I built a 1ft by 2ft lighted sign that is driven by an Ardunio and bluetooth. The idea is that when my phone rings or gets an sms message, this light starts flashing and buzzing letting me know somebody is trying to get in touch with me.

Thanks for checking this out. Once I get this figured out I'll put the working example up here for other people.

Thanks,
Ken

von KenKnight - am 25.02.2015 13:12
Ken,

In order to receive the status of de telephone you have to implement the following function:


public static class PhoneStateMonitor extends PhoneStateListener {
Context context;

public PhoneStateMonitor(Context context) {
super();
// TODO Auto-generated constructor stub
this.context=context;

Toast.makeText(context, "Init PhoneStateMonitor",Toast.LENGTH_LONG).show();
}

//This Method Automatically called when changes is detected in Phone State

// Various states are - CALL_STATE_IDLE, CALL_STATE_OFFHOOK, and CALL_STATE_RINGING
// IDLE – when there is no incoming call
// OFFHOOK – when the line is busy
// RINGING – when call is incoming

public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
super.onCallStateChanged(state, incomingNumber);

Toast.makeText(context, "Phone State - "+state+" Incoming Number - "+incomingNumber, Toast.LENGTH_LONG).show();//Giving the Message that Phone State Changed
//Checking The phone state
switch(state)
{
case TelephonyManager.CALL_STATE_IDLE: //Phone is in Idle State
Toast.makeText(context, "Phone State is IDLE", Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_RINGING: //Phone is Ringing
Toast.makeText(context, "Phone State is RINGING", Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //Call is Received
Toast.makeText(context, "Call State is OFFHOOK",Toast.LENGTH_LONG).show();
break;
}
}
}


In the Code where the Toast messages are, you need to call WLanguage code via "callWLProcedure" (see details in the help) to be able to keep the status and act on it. Best is not to put long actions in the Listener.

This way you should be able to intercept the telephone calls and display the info on you big display. You can lookup the number that is called in the Android addressbook, and if found you could also display the name.

When writing Java code, be sure to check the needed Android permission because they are not detected automatically like in WLangauge. If you search for "Android PhoneStateListener" you will find extra information about this.

Also look at the Android docs: http://developer.android.com/reference/android/telephony/PhoneStateListener.html

For handeling the SMS messages you could use the WinDev Mobile SMS functions.

http://doc.pcsoft.fr/en-US/?3068004&name=sms_functions

Or you have to write some extra Java code to intercept the broadcast intent of the SMS

http://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html#SMS_RECEIVED_ACTION
An Eclipse example is here: http://androidexample.com/Incomming_SMS_Broadcast_Receiver_-_Android_Example/index.php?view=article_discription&aid=62&aaid=87

Hope this helps you on your way !
In case you don't get it working, let me know and I'll try to help some more.

Success
Danny

von Danny Lauwers - am 25.02.2015 22:01

Re: [WM19] Android Alarmmanager and BroadcastReceiver do not work ? [SOLVED]

Danny, thank you for your sample code. It's perfect for understand this question and it was very useful for my last work :)

Thank you very much.


Rubén

von Ruben Sanchez Peña - am 13.09.2016 12:29
Hi.

I'm using the codr from this thread to program an allert to tun a global procedude from tha application. This works fine. The alert is fired. Then i want call to a WL procedure with callWLProcedure to run the work.

The problem is when i use CallWLProcedure. The app hang in this line.

How i can call then my global procedure from onReceive?

Thank you

Rubén

/////// Procedure to Alert program
public static void ProgramarAlerta(int nHora, int nMinuto, String sProcedureProgrammingOK, String sProcedureProgrammingError, String sProcedureAlertOK, String sProcedureAlertError)
{
// Se inicializan los nombres de los procedimientos
ProcedureProgrammingOK = sProcedureProgrammingOK;
ProcedureProgrammingError = sProcedureProgrammingError;
ProcedureAlertOK = sProcedureAlertOK;
ProcedureAlertError = sProcedureAlertError;

try {
AlarmManager alarm;
Calendar cal;
PendingIntent alarmIntent;

// Retrieve the current activity
Activity tmpActivity = getCurrentActivity();

// Retrieve the current Context
Context tmpContext = getApplicationContext();

cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.HOUR_OF_DAY, nHora);
cal.set(Calendar.MINUTE, nMinuto);

alarm = (AlarmManager)tmpContext.getSystemService(tmpContext.ALARM_SERVICE);
Intent myIntent = new Intent(tmpContext,AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(tmpContext, 0, myIntent, 0);

// Start every day
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);

Toast.makeText(tmpContext, "ProcedureProgrammingOK", Toast.LENGTH_LONG).show();
Log.d("boletinesoficiales","Llamando a " + ProcedureProgrammingOK + " en " + Long.toString(cal.getTimeInMillis()));
callWLProcedure(ProcedureProgrammingOK,Long.toString(cal.getTimeInMillis()));
}
catch(Exception e) {
//e.printStackTrace();
Log.e("boletinesoficiales","Error programando la alerta");
Log.e("boletinesoficiales",ProcedureProgrammingError);
callWLProcedure(ProcedureProgrammingError,"");
}
}

///// Class and procedure to receive the broadcast alert

import android.content.*;
import android.app.PendingIntent;
import android.app.AlarmManager;
import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Log;

// Nombre de los procedimientos a llamar
static String ProcedureProgrammingOK; // Programacion OK
static String ProcedureProgrammingError; // Programacion Error
static String ProcedureAlertOK; // Ejecucion de la alerta
static String ProcedureAlertError; // Error de ejecucion


public static class AlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

try {
// Retrieve the current Context
Context tmpContext = getApplicationContext();

//Toast.makeText(tmpContext, "test - Start", Toast.LENGTH_LONG).show();

// Stuff todo

Toast.makeText(context, "ProcedureAlertOK", Toast.LENGTH_LONG).show();
Log.d("boletinesoficiales","Llamando a " + ProcedureAlertOK);

callWLProcedure(ProcedureAlertOK,"");

von Ruben Sanchez Peña - am 14.09.2016 17:04
Zur Information:
MySnip.de hat keinen Einfluss auf die Inhalte der Beiträge. Bitte kontaktieren Sie den Administrator des Forums bei Problemen oder Löschforderungen über die Kontaktseite.
Falls die Kontaktaufnahme mit dem Administrator des Forums fehlschlägt, kontaktieren Sie uns bitte über die in unserem Impressum angegebenen Daten.