Call Service With AlarmManager - android

I have created one service which I want to call periodically through AlarmManager. I have written code for same, But it's not calling. If I call BroadcasrReciever through AlarmManager, then it's working fine.
Below is my Code,
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Intent alarmIntent = new Intent(this, LocationUpdateService1.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.setRepeating(AlarmManager.RTC_WAKEUP, 20000, 11000, pendingIntent);
}
My service class is,
public class LocationUpdateService1 extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "I created", Toast.LENGTH_LONG);
return null;
}
}
My manifiest file,
<service
android:name=".Services.LocationUpdateService1">
</service>
Do I have to create BroadcastReceiver class to call my service ?
What is wrong in my code ? and why it's not calling periodically ?

Make sure you don't use PendingIntent.getBroadcast, it wouldn't work. Using getService() instead, like this:
PendingIntent pendingIntent = PendingIntent.getService(this, 0, alarmIntent, 0);

Related

Alarm not triggering in android

I am new to android programming. What am i doing wrong? AlarmReceiver class not triggering...I want to trigger repeatedly the AlarmReceiver.class ...
I used the code from this page https://developer.android.com/training/scheduling/alarms#precision
OnCreate at MainActivity.java i have the following code
AlarmManager alarmManager = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this,AlarmReceiver.class);
//Check if the PendingIntent already exists
PendingIntent pendingIntent =
PendingIntent.getService(this, 6661, intent,
PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null && alarmManager != null) {
//cancel here if you want
}
//Run every 60 seconds!
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 60000,
60000, pendingIntent);
The AlarmReceiver.java class includes the following code...
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// For our recurring task, we'll just display a message
Log.i("logit","testing...");
}
}
Do you have an entry in your manifest for the receiver like that?
<receiver android:name=".AlarmReceiver"></receiver>

Starting IntentService periodically with AlarmManager - Losing Data at certain point

In my app, I want to send sensor data every ten seconds via POST to a webserver.
I am doing this with an activity who starts/stopps a AlarmMananger who is calling an IntentService.
Problem is: the target URL is generated in the Activity and doesn't arrive at the IntentService.
Activity:
public class MyActivity extends AppCompatActivity {
...
#Override
protected void onResume() {
super.onResume();
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager alarmManager=(AlarmManager) getSystemService(ALARM_SERVICE);
String targetURL = "www.google.de";
alarmIntent.putExtra("targetURL", targetURL);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10000, pendingIntent);
}
...
}
Broadcast-Receiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String targetURL = intent.getStringExtra("targetURL");
Intent newintent = new Intent(context, SendPostRequest_Service.class);
newintent.putExtra("targetURL", targetURL);
context.startService(newintent);
}
}
Intent Service:
public class SendPostRequest_Service extends IntentService implements SensorEventListener{
...
public SendPostRequest_Service() {
super(SendPostRequest_Service.class.getName());
}
#Override
protected void onHandleIntent(Intent intent) {
String targetURL = intent.getStringExtra("targetURL");
// Problem: targetURL = null
//read sensors, send POST-Request via okhttp <- working
}
...
}
Do you have any suggestions?
Put your code into a test project. Only way I was able to get it working was to change the order of when the extra is added to the intent. Update MyActivty with the below. It would appear to G. Blake Meike point that there's a copy of the intent being done.
#Override
protected void onResume() {
super.onResume();
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
String targetURL = "www.google.de";
alarmIntent.putExtra("targetURL", targetURL);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager alarmManager=(AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10000, pendingIntent);
}
You'll need to take a wake lock in your BroadcastReceiver and release it in your Service. Otherwise, the system may return to a sleep state before your Service gets a chance to run. The WakefulReceiver is particularly useful for this. If you'd like some more details, this article will help: http://hiqes.com/android-alarm-ins-outs/

IntentService won't start using AlarmManager

I know there is a lot of questions about this but I really don't know where is my mistake.
My service is registered in the AndroidManifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.app" >
...
<service android:name="com.example.android.app.ScheduledService">
</service>
</application>
</manifest>
My service extends IntentService
public class ScheduledService extends IntentService {
public ScheduledService() {
super("ScheduledService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(getClass().getSimpleName(), "I ran!");
}
}
My Activity starts the service
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(getClass().getSimpleName(), "Setting alarm!!");
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, com.example.android.app.ScheduledService.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() +
10 * 1000, pending);
}
}
I don't see any exception in the logs. Is there something else I should do to setup my alarm?
As in documentation, PendingIntent.getBroadcast() is used to retrieve a PendingIntent that will perform a broadcast, like calling Context.sendBroadcast().
You need to call PendingIntent.getService() instead, which will start IntentService:
PendingIntent pending = PendingIntent.getService(this, 0, alarmIntent, 0);
Look closely at the AlarmManager API and the PendingIntent. The AlarmManager.set() API is expecting a broadcast intent, which you are providing. However, you're trying to send a broadcast intent to a service, which cannot be done. Just create a BroadcastReceiver to catch the Intent and your BR should then start your service.
The API says:
typically comes from IntentSender.getBroadcast().
that means PendingIntent.getService can work too.
I tested it, and it works.

AlarmManager in Android

I have code which is to be run daily; for this I'm trying to use AlarmManager. This is my code for triggering alarms:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i = new Intent(this, AlarmReciever.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.cancel(pi); // cancel any existing alarms
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
AlarmManager.INTERVAL_DAY, pi);
}
This part of the code is calling AlarmReciever class as expected, but I want the code in the AlarmReciever class to be executed only once daily. It's being called multiple times. How do I restrict it?
This is the AlarmReciever class:
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("in alarm reciever class");
}
}
I'm trying to perform some business logic in the onReceive() method.
In the manifest.xml file:
<receiver android:name="com.xyz.reciever.AlarmReciever"></receiver>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
are declared.
I believe the code you should be using to set your alarm would be this:
Intent i = new Intent(this, AlarmReciever.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); // <- HERE!!
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.cancel(pi); // cancel any existing alarms
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
AlarmManager.INTERVAL_DAY, pi);
since your AlarmReciever is a BroadcastReceiver. Use PendingIntent.getBroadcast().
If you have much work to do in your receiver's onReceive() method, you might also delegate it to an IntentService. See this answer if you decide to do that.

Android alarm not working

I've been struggling with this for hours. I've also checked the documentation and several topics. I found this code in two topics, both guys said the code was working perfectly, but not on my computer. The first Toast appears, but the second one never. What is wrong?
public class HelloAndroid2 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (10 * 1000), pendingIntent);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
}
public final class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();
}
}
}
Actually you dont need to specify the action since you use the class AlarmReceiver.class in the intent.
In your AndroidManifest.xml, make sure you have a receiver definition within the <application> tags, something like:
<receiver android:name="AlarmReceiver">
Edit:
Ok there are 2 ways to use your broadcast receiver.
1) From the code you have provided, AlarmReceiver.java that will contains:
public final class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();
}
}
and HelloAndroid2.java:
public class HelloAndroid2 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (10 * 1000), pendingIntent);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
}
}
Like this, you can set your broadcast receiver to work with the AndroidManifest.xml and the tag <receiver ...>
2)2nd way. With this way, you can use just 1 file HelloWorld2.java:
In your activity, create your broadcast receiver and register it.
public class HelloWorld2 extends Activity {
private SharedPreferences prefs;
private String mName;
BroadcastReceiver alarmReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm worked", Toast.LENGTH_LONG).show();
}
};
public static final String ACTION_NAME = "com.helloworld.MYACTION";
private IntentFilter myFilter = new IntentFilter(ACTION_NAME);
#Override
protected void onPause() {
unregisterReceiver(alarmReceiver);
super.onPause();
}
#Override
protected void onResume() {
registerReceiver(alarmReceiver, myFilter);
super.onResume();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(alarmReceiver, myFilter);
Intent intent = new Intent(ACTION_NAME);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (10 * 1000), pendingIntent);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
}
I had the same problem until I found that I had put my Broadcast Receiver on a different package, not the general.
Simply changed:
<receiver android:name=".AndroidAlarmService" android:enabled="true" >
for:
<receiver android:name="com.MyCompany.MyPackage.AndroidAlarmService" android:enabled="true" >
If the answer above doesn't work for you then there is another way to not receive any callbacks when AlarmManager fires an expired alarm. You simply need to check this one out: by sending the wrong Intent on instantiation of PendingIntent. For example you wanted to receive a call onReceive on one of your receivers but you instantiated a PendingIntent via getActivity or getService, but what you actually meant is getReceiver.
When creating instance of PendingIntent, there are many ways to create it (getService, getActivity,getReceiver, getForegroundService:
if you want Activity the receiver of the intent then you:
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*);
if you want BroadcastReceiver the receiver of the intent:
PendingIntent.getReceiver(this, 0, intent, PendingIntent.FLAG_*);
if you want a foreground Service the receiver of the intent:
PendingIntent.getForegroundService(this, 0, intent, PendingIntent.FLAG_*);
if you want a Service the receiver of the intent:
PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_*);
Also, make sure you intents are pointing to the correct class. (e.g. creating intents for Activity, Service etc.). You will not receive any call if you pass wrongfully like this:
Intent intent = new Intent(this, MyReceiver.class); // You wanted receiver
// PendingIntent was created in such a way
// you wanted this to be received by an activity.
// you will not receive any call if you set it up like this.
PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*);
I also posted similar answer here.
HTH

Categories

Resources