Keep sip registration in pjsua2 voip application even in deep sleep? - android

I have an android application with pjsua2 open source project.Its working fine both incoming and outgoing call.But when android goes in deep sleep sip registration not working.I am using service for registration.But its not reregistering..
accCfg.getRegConfig().setRetryIntervalSec(600);
accCfg.getRegConfig().setFirstRetryIntervalSec(15);
any help would be appreciated.

For when android goes in deep sleep android os kills almost all services and other background tasks. So for keeping sip registration I believe AlarmManager will be a very good option.Sample example will awake ur application in every 5 min..so re-register that time...
public void setAlarmManagerFroDeepSleep() {
int interval = 1000 * 60 * 5;
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
/* Repeating on every 5 minutes interval */
manager.setRepeating(AlarmManager.RTC_WAKEUP, interval,
interval, pendingIntent);
}
Here is sample AlarmReciever class..
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("Alerm Manager", "I'm running");
if(Connectivity.isConnected(context)) {
try {
//make re-register here....
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

Related

Do action after some time when your app is not active / running

I have some sensitive data that I load on the device in my application. And it can be reused between sessions / multiple uses of the app and be cleared when not in use / open / active.
So the app is not active / running. There is a notification showing that the sensitive information is still in memory.
But I want to give the user an option of clearing this data after a set amount of time.
So my question is how do I run some code after a set number of minutes?
You can schedule an alarm using the AlarmManager and run your code from the BroadcastReceiver/Service. The alarm will trigger weather your app is dead or alive. (If it's dead it will be awaken)
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
You can use this method to register a one time alarm. So if you want the alarm to trigger in 5 mins, the delayMillis value should be 5 * 1000 * 60
void registerOneTimeAlarm(PendingIntent pendingIntent, long delayMillis) {
int SDK_INT = Build.VERSION.SDK_INT;
long timeInMillis = System.currentTimeMillis() + delayMillis;
if (SDK_INT < Build.VERSION_CODES.KITKAT) {
alarmManager.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
} else if (SDK_INT < Build.VERSION_CODES.M) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
} else {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
}
}
Let's say you will use a receiver, it will look like this:
public class AlarmReceiver
extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Your code here
}
}
And don't forget to add it in the Manifest:
<receiver android:name="your.package.AlarmReceiver"/>
IMPORTANT
Registered alarms are cleared when the device reboots, you need to re-register the alarm after the device boots. (If this is what you really need)
You can try this
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Actions to be performed
}
}, TIME_OF_DELAY);

Run a JobService Constantly in Android-Even App is killed

I am just newbie to android,please help a little. i am trying to use JobService or com.firebase.jobdispatcher.JobService in my android application but as far as i studied i see that the JOB SERVICE runs on Main Thread and as long as application is running either in background or forground it keep doing its schedule work.
But the issue is i want to do Get users location lets say after every 30 minutes even if the application is removed from application tray. i am confused in following points
If i run a sticky service it does not give me scheduling
If i use Job Service it gives scheduling but terminates as application is
closed.
Is there any way to run a service which run even after application is killed and do schedule tasks as well?
you can use AlarmManager link
Create Your Server class :
public class MService extends IntentService {
public MyTestService() {
super("MService");
}
#Override
protected void onHandleIntent(Intent intent) {
// Your firebase task
}
}
then your broadcast
public class MReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent in = new Intent(context, MService.class);
context.startService(in);
}
}
finally
Intent intent = new Intent(getApplicationContext(), MReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, MReceiver.REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, AlarmManager.INTERVAL_HALF_HOUR, pIntent);

Alarm "onReceive" not being called

I'm trying to create an Alarm that will fix lost connections to Google Cloud Messaging that occur due to the heartbeat bug, found here How to avoid delay in Android GCM messages / change heartbeat
However, my alarm's onReceive class which I have being set to be called every 1 minute for testing is never being called. I've looked in several of the other questions pertaining to this topic, and all of them concentrate on spelling and declaring the receiver in the manifest, which I've checked several times.
Here is all the relevant code:
MainActivity.java
//Alarm created here
GCMHeartbeatAlarm gcmAlarm = new GCMHeartbeatAlarm();
gcmAlarm.setAlarm(this);
GCMHeartbeatAlarm.java
public class GCMHeartbeatAlarm extends BroadcastReceiver {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
#Override
public void onReceive(Context context, Intent intent) {
//The part which is supposedly going to fix the GCM connection dropped bug, needs to be called every 5 mins or so via alarm to keep
//GCM connection open
//Commented out for now
// context.sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT"));
// context.sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT"));
Log.i("GCMHeartbeat", "GCM Heartbeat Sent!");
}
public void setAlarm(Context context) {
alarmMgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, GCMHeartbeatAlarm.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
//Repeat every 1 minute
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME, System.currentTimeMillis(), 1000 * 60 * 1 , alarmIntent);
Log.i("GCMHeartbeat", "Alarm set!");
}
}
AndroidManifest.xml
<!-- GCM Heartbeat Alarm Receiver -->
<receiver
android:name="com.MyApp.app.GCMHeartbeatAlarm">
</receiver>
With this code, the "Alarm Set!" log is hit, but the log in onReceive is never hit.
Anything that could help me figure out what's going on would be greatly appreciated!
Got it to work eventually. I'm not quite sure why, but using System.currentTimeMillis() wasn't working for the triggerAtMillis value. Perhaps it was because the alarm was set for ELAPSED_REALTIME instead of currentTimeMillis(), so the first alarm was never triggered. Instead I used SystemClock.elapsedRealtime() + 60 * 1000 to trigger the alarm beginning 1 minute after it is set, and then the onReceive method started being called in 1 minute intervals.
The working code was:
public void setAlarm(Context context) {
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, GCMHeartbeatAlarm.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 60 * 1000, 60 * 1000, alarmIntent);
Log.e("GCMHeartbeat", "Alarm set!");
}

Android: setting an alarm clock from a broadcast receiver only works once

I'm making an android app to be used to help recover a lost phone. The app uses a Service that is constantly running and when a text message (SMS) is received by the phone, a BroadcastReceiver's (already registered in the service) onReceive() event is triggered. The functionality that I want is that the BroadcastReceiver be able to make the phone produce a loud noise even if the phone was on silent. The most logical way I can think of doing this is to use and alarm clock set one minute from the current time.
This is the code I'm currently using inside of the broadcast receiver:
Calendar c = Calendar.getInstance();
Intent alarmIntent = new Intent(AlarmClock.ACTION_SET_ALARM);
alarmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alarmIntent.putExtra(AlarmClock.EXTRA_MESSAGE, "Polo!");
alarmIntent.putExtra(AlarmClock.EXTRA_HOUR, c.get(Calendar.HOUR_OF_DAY));
alarmIntent.putExtra(AlarmClock.EXTRA_MINUTES, c.get(Calendar.MINUTE) + 1);
context.startActivity(alarmIntent);
Fortunately, this code works, but it only ever works once. But that I mean, the first time this code is run, the phone's flow is interrupted and the clock app is opened with a new alarm set. When you attempt to do this again, the clock app is opened, but no alarm is set. I have to restart my phone to get this to work again.
From what I can tell, the issue has to do with the clock app and I need to restart the clock app to get my service to work. This is a really sketchy solution, but I don't know what else to do.
Any recommendations?
The trick is to develop your own Alarm screen and re-set the alarm while onCreate.
Like that, your app will continuously ring up.
for that :
initialise a WakefulBroadcastReceiver
manifest.xml
<receiver android:name="com.mycompany.myapp.AlarmManagerBroadcastReceiver"></receiver>
AlarmManagerBroadcastReceiver.java
public class AlarmManagerBroadcastReceiver extends WakefulBroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Calendar c = Calendar.getInstance();
Intent alarmIntent = new Intent(context, MyAlarm.class);
alarmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alarmIntent.putExtra(AlarmClock.EXTRA_MESSAGE, "Polo!");
alarmIntent.putExtra(AlarmClock.EXTRA_HOUR, c.get(Calendar.HOUR_OF_DAY));
alarmIntent.putExtra(AlarmClock.EXTRA_MINUTES, c.get(Calendar.MINUTE) + 1);
context.startActivity(alarmIntent);
}
}
MyAlarm.java :
public class MyAlarm extends Activity{
#Override
public void onCreate(Bundle savedInstanceState){
// doing UI stuff
AlarmUtil.setAlarm(this);
}
}
AlarmUtil.java
public class AlarmUtil {
#SuppressLint("NewApi")
public static void setAlarm(Context context){
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
int requestCode = 1234;
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
am.setExact(AlarmManager.RTC_WAKEUP, 60 * 1000, pi);
}
else{
am.set(AlarmManager.RTC_WAKEUP, 60 * 1000, pi);
}
}
}

Modifying Alarms Which Trigger Services Based on Screen Status

I am currently starting a service using a Broadcast Receiver which fires 60 seconds after the device boots up. This broadcast receiver triggers an alarm so that my service runs every 60 seconds. Code for this is as follows:
public class ScheduleReceiver extends BroadcastReceiver {
// Restart service every 60 seconds
private static final long REPEAT_TIME = 1000 * 60;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, StartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 60 seconds after boot completed
cal.add(Calendar.SECOND, 60);
// Fetch every 60 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), REPEAT_TIME, pending);
}
}
The above starts the service as follows:
public class StartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, PhotoService.class);
context.startService(service);
}
}
I would like to somehow modify this so that my service runs every 60 seconds when the phone screen is on and every 20 minutes when off.
What is the best way to do this ? Can I modify the alarm dynamically when the screen is switched off/on ?
Thanks for any help,
Regards,
Fido
Okay I have found out how to do this so I thought I would put this here in case anyone else is ever curious. (More elegant solutions are always welcome):
First thing is that in my service I added the following to the OnCreate:
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScheduleReceiver();
registerReceiver(mReceiver, filter);
}
This is done so that my broadcast receiver can handle those events. Apparently you cannot register these via intent-filters in the xml.
This means that when the service is created it ensures that these additional system actions can be handled.
I then modified my broadcast receiver to be:
public class ScheduleReceiver extends BroadcastReceiver {
private static final int ALARM_ID = 909;
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, StartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, ALARM_ID, i,PendingIntent.FLAG_CANCEL_CURRENT);
service.cancel(pending);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 60); //Delay startup by one minute - This is useful to prevent over utilization of resources at boot
// Start alarm. Set a long repeat time if the screen is off and a short repeat time if the screen is on
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON) || intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60000, pending);
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 600000, pending);
}
}
}
From the above I cancel any current alarms with the same pending intent and then I set a new alarm whenever the screen if switched off/on.
This seems to be working for me. As always any improvements are very welcome.

Categories

Resources