In general i have a service that sends an intent to my activity which is ALWAYS on every 6 sec and a BroadcastReceiver everytime on receive updates a timer.
I found by accident that after a while ( this is random ) that the particular receiver stops working.
OnPause i unregister it and onResume i register it again.
Also this happens randomly in any devices and android versions.
I found by researching on the web , that after onReceive the receiver is ready to killed by Android but mine keeps getting intents.
"Receiver Lifecycle
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.
"
FYI i have declare it like this inside my activity
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent intent) {
Log.i("Intent received", "+_ " + intent.getAction());
if (intent.getAction().equals(TEST)) {
//do sth
} else {
//do sth else
}
}
}
Thans a lot even for taking the time to read :).
I dont declare anythin to my manifest and as for my logcat i must be over my phone the moment it happens. The service is a simple send broadcast after one async task. The last test i made was ensuring that the code from the service was running by logging the beeing sent. And the service kept on.
I am away from my code write now but i think there will be no help because is very simple. Thnaks
Well i could still figure out but I find a solution to my problem
Timer now is in the activity and receiver is sending the event but after 10000 tries i want to trigger the END EVENT. Now the receiver since he didn't work i couldn't get it but now i Start an intent with extras for the same activity always with flags new_task and clear_top.
No matter if my receiver is working or not, since the service is ok i will start the specific Activity and pseudo-show the END EVENT.
PS:: This behavior isn't always trigger but sometimes. So now i am ok.
If i am not understood please comment and ask anything. Thanks
Related
In my android app, I have a Service that starts when the app goes in background. OnStartCommand begins long running task that analyzes and checks device and app status.
Now, I am preparing the app for Android O. First issue that i faced is Services, I rework them to JobServices.
Now I am facing another issue. When user removes my app from application stack JobService.OnTaskRemoved doesn't get called.
Before, when I used Service calling of Service.OnTaskRemoved worked fine for me.
Now I see only way. I need My old Service for handlingService.OnTaskRemoved and new JobServices for executing task.
Am I wrong? May be some one can give me good advice?
You are implementing the wrong concepts.., which creates problem.., To tackle it .. you are again implementing wrong things.. Please offload all...
In my android app, I have a Service that starts when the app goes in background..
The Problem ;
In android O there is no background execution allowed at all.. Even a single line of code is not guaranteed to execute..!!
And you want it to execute long running service..!!
The Solution;
The same service can be started whenever App is opened first time... On acquiring all runtime permissions. As :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
context.startForegroundService(new Intent(context, YourLongRunningService.class));
}
else
{
context.startService(new Intent(context, YourLongRunningService.class));
}
OnStartCommand begins long running task that analyzes and checks device and app status.
The Problem ;
OnStartCommand is not meant to be coded the long running procedures / statements of code..
Nor it is meant to be coded at all........
The Solution;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("RUNNER : ", "\nPERFORMING....");
return START_STICKY;
}
Above single line tells android to keep alive ALL THE TIME UNTIL DEVELOPER STOPS IT ON HIS OWN VIA CODE STOPSELF Even removed from background or from recents; It gets re-created automatically by android os
Then where should i write the code.... ??
Wait... its too early to code yet....!!! patience
begins long running task that analyzes and checks device and app status
Your question is un clear and in my brain there is a gradle error ... I can not resolve your symbols :
analyzes
checks device
app status
But i know that these your broadcasts definitely .. And you need to implement broadcast-receivers... to receive it...!!
I will implement Broadcast receivers... Its too easy...
The Problem ;
Wait... Android O do not allows you to implement many broadcast receivers from static receivers like we does... And even we are not allowed to call that receivers on specific intent-actions from manifest.xml
The Solution;
Implement runtime receivers in your above created service YourLongRunningService in onCreate like :
IntentFilter myFilter = new IntentFilter();
myFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
this.registerReceiver(mCallBroadcastReceiver, CallFilter);
CONNECTIVITY_CHANGE is an example and it would be your intent action / broadcast you want to listen for...!!
What is mCallBroadcastReceiver and all...
These are runtime registration of receivers... and needed to be unregistered from onDestroy like :
#Override
public void onDestroy()
{
this.unregisterReceiver(mCallBroadcastReceiver);
super.onDestroy();
}
No.... No... No.... I do not want to un-register it... I want it always working..
Our service is START_STICKY Even if it is destroyed; gets started automatically and registers mCallBroadcastReceiver in onCreate again..
Where is the receiver then....???
In this case mCallBroadcastReceiver is receiver defined in class area where we declares the variables and constants :
public class YourLongRunningService extends Service
{
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "1";
private BroadcastReceiver mCallBroadcastReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
// All your receiver code goes here...
}
};
// your constructor
// your onStartcommand
// your ondestroy
}
What notification Manager is doing here....???
In and above O you can not run foreground service without proper Ongoing task notification... It will go in your onCreate which will call Startforeground with the notification to start this service as a foreground service
What below android O...?
It works below Android O too... Just call with normal startservice its code it given on very start...!!
Where is my long running code goes then....???
From receiver receive broadcast you want and start a intentservice or a job or a alarm class or whatever you want...
I will make a simple class which takes context in constructor and defines a public method named LongRunningCode may be of one crore lines of code....
And on receiving broadcast in receiver , I will make a object of that class by passing context of receiver and will simply call LongRunningCode method with that object
Hope it helps
I'm developing an application for Android.
I use Samsung Galaxy S3 with original ROM Jelly Bean 4.3.
I have a problem with the receivers of incoming call and outgoing call.
Here is the code of IncomingCallReceiver:
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
if (Start.getMusicService().isPlaying()) {
pauseMusicService();
isMusicPlaying = true;
}
}
else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
if (isMusicPlaying){
restartMusicService();
isMusicPlaying = false;
}
}
}
However this is not the problem, this code works and also the outgoing call receiver works perfectly.
My problem is that when i exit the application this receivers still work.
It's happened that, days after the last time i opened the application, i received a phone call and the application crashed.
I think that it's happened because i write the code:
if (Start.getMusicService().isPlaying())
because Start (my first activity) doesn't exist.
I never register this receiver, they work without that i "call" them.
I don't know if i have to unregister and in case when i have to do it.
So, can anyone help me please?
Andrea
When declaring a BroadcastReceiver or other Intent receiver in your AndroidManifest it is always "on". Move the registration and deregistration to the beginning and end of the execution of your app, or other times in your app; then you will be able to control when its on at runtime.
Above answer is correct. If you want to register and/or unregister receiver yourself at you should register in onResume and unregister in onPause in case of activity. Look out this example http://sohailaziz05.blogspot.com/2012/05/broadcast-receiver-two-ways-to.html
I'm using a BroadcastReceiver in my Android app which simply contains the following piece of code:
public BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
GcmIntentService.isHandled = true;
Toast.makeText(context, "broadcast receiver test", Toast.LENGTH_SHORT).show();
}
}
I'm using this receiver to determine if my activity is running and carry out some updates in a ListView without having any notifications produced by GcmIntentService.
With the code being simple so far, only creating a toast message, I'm unable to catch the boolean value from GcmIntentService.isHandled as soon as the sendBroadcast is invoked.
Is it possible in any way to determine if the code for my receiver has finished running. I understand that sendBroadcast is an asynchronous call, and I'm making use of Thread.sleep(1000) so far to wait for the isHandled value, but it would be nice if there is a more reliable method on achieving this.
Any thoughts?
Your question can be divided to two parts:
1.How to know that if there is a receiver actually received the broadcast.
2.How should the receiver notify the service that message is been handled.
It seems difficult to achieve the first goal through standard Intent api, instead I suggest you may try the "observer pattern".
You may create a global Observable object in your Application and make your Activity implements Observer, register itself in onCreate() and unRegister in onDestory().Inside the Service you can check if there is an Activity running through countObservers() and then simply notify it.
I am able to stop my ServiceA(it is started using AlarmManager) when an IntentService is running by sending a broadcast from IntentService to broadcast receiver. I want to Start the same ServiceA again after my IntentService finished his work.
Ex-I have Service SrvA,IntentService IntSrvB and BroadcastReceiver MyBcr.When my IntSrvB running i am able to stop SrvA.My problem is How to Restart SrvA again when my IntSrvB finish his work.
Note-ServA is started using AlarmManager.
EDIT: Based on your code, you can pass your variables myIntent & myIntent2 into your IntentService class - you can then use them to recreate exact replicas of the pending intents used with the AlarmManager.
Please note that it looks like you set an Alarm for each intent that repeats once "NOW" and then at intervals after that. You then implicitly start the service again i.e. you start the service twice "NOW". That looks like a mistake - look at the docs for the AlarmManager.setRepeating() method.
Original answer below...
Put this into your IntentService:
#Override
protected void onHandleIntent(Intent intent)
{
try
{
// STOP SERVICE
// DO YOUR WORK HERE
}
finally
{
// START SERVICE
}
}
You already have the code to stop the service. You can take the "start service" code from your BroadcastReceiver and put it in the finally block.
I would not recommend overriding onDestroy() in general on Android.
NOTE: I don't think this is the best way to design your app, but I'm answering your question. Personally, I would have a method in my main Service that is able to disable & enable its functionality - and then call that method instead of starting & stopping the service.
I have a dynamically registered BroadcastReceiver on a Service. It gets AudioManager.RINGER_MODE_CHANGED_ACTION as IntentFilter. Every time I start the service I get the log message in onReceive() method. It works normally after that. I do not want it to receive once when service is started each time. Could you please tell me what I am missing here?
receiver=new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
Log.d("zil", "degisti");
}
};
IntentFilter filter=new IntentFilter(
AudioManager.RINGER_MODE_CHANGED_ACTION);
registerReceiver(receiver,filter);
The intent you are interested in, AudioManager.RINGER_MODE_CHANGED_ACTION, is "sticky". That means that the system always keeps the last broadcast sent and whenever a BroadcastReceiver is registered that is interested in that Intent, it receives it right away. This is a very useful feature but sometimes it isn't what you want ;-)
I assume that you are only interested in actual "change" events. In this case you need to ignore the "current" event and listen only for any events that happen in the future. Lucky for you, there is a solution:
In 'onReceive()' do the following:
if (isInitialStickyBroadcast()) {
// Ignore this one as we aren't interested in the current state
} else {
Log.d("zil", "degisti");
// Do whatever you want to do with the event here
}
unregisterReceiver(receiver);
this probably wont work because you created an Anonymous inner class implementation of BroadcastReciever. instead create a nested/private class that extends BroacastReceiver in the activity where you want your service started. Then dynamically register and unregister your receivers in the Activity lifecycle callbacks