I have included a NotifyService in my App to show particular Notification on a selected particular Date via a Date Picker...
The Problem is that the Latest Notification is only fired & not the Previous one...
I have also tried giving a Unique Notification Id but still it didn't work...
Heres the MainActivity -
public class MainActivity extends Activity {
private ScheduleClient scheduleClient;
private DatePicker picker;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scheduleClient = new ScheduleClient(this);
scheduleClient.doBindService();
picker = (DatePicker) findViewById(R.id.scheduleTimePicker);
}
public void onDateSelectedButtonClick(View v){
int id = MyApp.preferences.getInt("notif", 0);
id++;
MyApp.preferences.edit().putInt( "notif" , id).apply();
int day = picker.getDayOfMonth();
int month = picker.getMonth();
int year = picker.getYear();
Calendar c = Calendar.getInstance();
c.set(year, month, day);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
// Ask our service to set an alarm for that date, this activity talks to the client that talks to the service
scheduleClient.setAlarmForNotification(c);
Toast.makeText(this, "Notification set for: "+ day +"/"+ (month+1) +"/"+ year, Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop() {
if(scheduleClient != null)
scheduleClient.doUnbindService();
super.onStop();
}
}
ScheduleClient -
public class ScheduleClient {
private ScheduleService mBoundService;
private Context mContext;
private boolean mIsBound;
public ScheduleClient(Context context) {
mContext = context;
}
public void doBindService() {
mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((ScheduleService.ServiceBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
public void setAlarmForNotification(Calendar c){
mBoundService.setAlarm(c);
}
public void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
mContext.unbindService(mConnection);
mIsBound = false;
}
}
}
Schedule Service -
public class ScheduleService extends Service{
public class ServiceBinder extends Binder {
ScheduleService getService() {
return ScheduleService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ScheduleService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
private final IBinder mBinder = new ServiceBinder();
public void setAlarm(Calendar c) {
new AlarmTask(this, c).run();
}
}
AlarmTask -
public class AlarmTask implements Runnable{
private final Calendar date;
private final AlarmManager am;
private final Context context;
public AlarmTask(Context context, Calendar date) {
this.context = context;
this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.date = date;
}
#Override
public void run() {
Intent intent = new Intent(context, NotifyService.class);
intent.putExtra(NotifyService.INTENT_NOTIFY, true);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
// Sets an alarm - note this alarm will be lost if the phone is turned off and on again
am.set(AlarmManager.RTC, date.getTimeInMillis(), pendingIntent);
}
}
& Finally the NotifyService -
public class NotifyService extends Service {
/**
* Class for clients to access
*/
public class ServiceBinder extends Binder {
NotifyService getService() {
return NotifyService.this;
}
}
// Unique id to identify the notification.
public static final String INTENT_NOTIFY = "com.blundell.tut.service.INTENT_NOTIFY";
private NotificationManager mNM;
private Notification notif;
#Override
public void onCreate() {
Log.i("NotifyService", "onCreate()");
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
if(intent.getBooleanExtra(INTENT_NOTIFY, false))
showNotification();
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients
private final IBinder mBinder = new ServiceBinder();
/**
* Creates a notification and shows it in the OS drag-down status bar
*/
private void showNotification() {
CharSequence title = "Alarm!!";
int icon = R.drawable.ic_dialog_alert;
CharSequence text = "Your notification time is upon us.";
Notification.Builder notification = new Notification.Builder(NotifyService.this);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SecondActivity.class), 0);
int Notif = MyApp.preferences.getInt("notif", 1);
notification.setContentTitle(title)
.setContentText(text)
.setSmallIcon(icon)
.setContentIntent(contentIntent);
notif = notification.getNotification();
notif.flags |= Notification.FLAG_AUTO_CANCEL;
mNM.notify(Notif, notif);
stopSelf();
}}
So here, when I select a Day for e.g. 31/12/2017, set the Notif & then again set another to 1/1/2018 then the 1st one is removed I guess...
Any help will be appreciated :)
In your NotifyService class, the notify() method that belongs to NotificationManager object mNM needs to a different id for the notification otherwise it will replace existing notification. Read NotificationManager.notify() docs here
Related
I Will Try to give specific date statically but it can not genrate notification ,but i pick date from date picker then i will work normally.Here is my code.
MainActivity.java
public class MainActivity extends AppCompatActivity {
// This is a handle so that we can call methods on our service
private ScheduleClient scheduleClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scheduleClient = new ScheduleClient(this);
scheduleClient.doBindService();
}
public void onDateSelectedClickEvent(View v) {
// Get the date from our datepicker
int day = 1;
int month = 4;
int year = 2016;
// Create a new calendar set to the date chosen
// we set the time to midnight (i.e. the first minute of that day)
Calendar c = Calendar.getInstance();
c.set(year, month, day);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
// Ask our service to set an alarm for that date, this activity talks to
// the client that talks to the service
scheduleClient.setAlarmForNotification(c);
// Notify the user what they just did
Toast.makeText(
this,
"Notification set for: " + day + "/" + (month) + "/" + year,
Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop() {
// When our activity is stopped ensure we also stop the connection to the service
// this stops us leaking our activity into the system *bad*
if(scheduleClient != null)
scheduleClient.doUnbindService();
super.onStop();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
AlarmTask.java
public class AlarmTask implements Runnable {
private final Calendar date;
// The android system alarm manager
private final AlarmManager am;
// Your context to retrieve the alarm manager from
private final Context context;
public AlarmTask(Context context, Calendar date) {
this.context = context;
this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.date = date;
}
#Override
public void run() {
// Request to start are service when the alarm date is upon us
// We don't start an activity as we just want to pop up a notification into the system bar not a full activity
Intent intent = new Intent(context, NotifyService.class);
intent.putExtra(NotifyService.INTENT_NOTIFY, true);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
// Sets an alarm - note this alarm will be lost if the phone is turned off and on again
am.set(AlarmManager.RTC, date.getTimeInMillis(), pendingIntent);
}
}
ScheduleService.java
public class ScheduleService extends Service {
public class ServiceBinder extends Binder {
ScheduleService getService() {
return ScheduleService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ScheduleService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
private final IBinder mBinder = new ServiceBinder();
/**
* Show an alarm for a certain date when the alarm is called it will pop up a notification
*/
public void setAlarm(Calendar c) {
// This starts a new thread to set the alarm
// You want to push off your tasks onto a new thread to free up the UI to carry on responding
new AlarmTask(this, c).run();
}
}
NotifyService.java
public class NotifyService extends Service {
public class ServiceBinder extends Binder {
NotifyService getService() {
return NotifyService.this;
}
}
// Unique id to identify the notification.
private static final int NOTIFICATION = 123;
// Name of an intent extra we can use to identify if this service was started to create a notification
public static final String INTENT_NOTIFY = "com.blundell.tut.service.INTENT_NOTIFY";
// The system notification manager
private NotificationManager mNM;
#Override
public void onCreate() {
Log.i("NotifyService", "onCreate()");
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// If this service was started by out AlarmTask intent then we want to show our notification
if(intent.getBooleanExtra(INTENT_NOTIFY, false))
showNotification();
// We don't care if this service is stopped as we have already delivered our notification
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients
private final IBinder mBinder = new ServiceBinder();
/**
* Creates a notification and shows it in the OS drag-down status bar
*/
private void showNotification() {
// This is the 'title' of the notification
CharSequence title = "Alarm!!";
// This is the icon to use on the notification
int icon = R.drawable.ic_launcher;
// This is the scrolling text of the notification
CharSequence text = "Your notification time is upon us.";
// What time to show on the notification
long time = System.currentTimeMillis();
// Notification notification = new Notification(icon, text, time);
Notification notification;
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SecondActivity.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this);
notification = builder.setContentIntent(contentIntent)
.setSmallIcon(icon).setTicker(text).setWhen(time)
.setAutoCancel(true).setContentTitle(title)
.setContentText(text).build();
mNM.notify(NOTIFICATION, notification);
// The PendingIntent to launch our activity if the user selects this notification
// PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SecondActivity.class), 0);
// Set the info for the views that show in the notification panel.
//notification.setLatestEventInfo(this, title, text, contentIntent);
// Clear the notification when it is pressed
// notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Send the notification to the system.
//mNM.notify(NOTIFICATION, notification);
// Stop the service when we are finished
stopSelf();
}
}
ScheduleClient.java
public class ScheduleClient {
// The hook into our service
private ScheduleService mBoundService;
// The context to start the service in
private Context mContext;
// A flag if we are connected to the service or not
private boolean mIsBound;
public ScheduleClient(Context context) {
mContext = context;
}
/**
* Call this to connect your activity to your service
*/
public void doBindService() {
// Establish a connection with our service
mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
/**
* When you attempt to connect to the service, this connection will be called with the result.
* If we have successfully connected we instantiate our service object so that we can call methods on it.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with our service has been established,
// giving us the service object we can use to interact with our service.
mBoundService = ((ScheduleService.ServiceBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
/**
* Tell our service to set an alarm for the given date
* #param c a date to set the notification for
*/
public void setAlarmForNotification(Calendar c){
mBoundService.setAlarm(c);
}
/**
* When you have finished with the service call this method to stop it
* releasing your connection and resources
*/
public void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
mContext.unbindService(mConnection);
mIsBound = false;
}
}
}
SecondActivity.java
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sl);
}
}
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity" />
<service android:name=".ScheduleService" />
<service android:name=".NotifyService" />
</application>
Possible to reduce u r code Follow this tutorial for specific time notification and repeating time notification http://smartandroidians.blogspot.in/2010/04/alarmmanager-and-notification-in.html
I'm trying to create a Service that will run in the background and put a notification in the status bar every 10 sec (for testing only).
I reviewed many posts here but still was unable to find help.
For some reason, when I call the AlarmManager to run the Service, the application crushing.
Please advice.
This is the "Main Class" code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_screen);
MyAlarmManager.scheduleAlarms(this);
This is the AlarmManager code:
public class MyAlarmManager extends BroadcastReceiver {
private static final int PERIOD=1000*10; // 15 minutes
private static final int INITIAL_DELAY=500; // 5 seconds
#Override
public void onReceive(Context ctxt, Intent i) {
scheduleAlarms(ctxt);
}
static void scheduleAlarms(Context ctxt) {
AlarmManager mgr= (AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(ctxt, MyService.class);
PendingIntent pi=PendingIntent.getBroadcast(ctxt, 0, i, 0);
Log.i("My Log", "Alarm Manager Started ......... Alarm Manager Started");
mgr.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + INITIAL_DELAY, PERIOD, pi);
}
}
This is the "Service" code:
public class MyService extends Service {
private NotificationManager mNM;
private final IBinder mBinder = new LocalBinder();
private int NOTIFICATION = R.string.service_started;
public class LocalBinder extends Binder {
SecRssService getService() {
return SecRssService.this;
}
}
#Override
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Log.i("My Log", "Received onCreate Service !!!!!!!!!!!!!!!!!!!");
showNotification();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("My Log", "Received onStartCommand id " + startId + ": " + intent);
Toast.makeText(this, R.string.service_started, Toast.LENGTH_SHORT).show();
showNotification();
// This service will continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
#Override
public void onDestroy() {
// Cancel the persistent notification.
mNM.cancel(NOTIFICATION);
Toast.makeText(this, R.string.service_stopped, Toast.LENGTH_SHORT).show();
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private void showNotification() {
CharSequence text = getText(R.string.service_started);
Notification noti = new Notification.Builder(getBaseContext())
.setContentTitle(getText(R.string.noto))
.setContentText("Test Notification ON")
.setSmallIcon(R.drawable.ic_launcher)
.build();
}
}
This is my Log
08-02 11:09:48.872: E/AndroidRuntime(9550): Caused by: java.lang.ClassCastException: com.homeapps4u.sec_ticker_rss.MyService cannot be cast to android.content.BroadcastReceiver
08-02 11:09:48.872: E/AndroidRuntime(9550): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2400)
08-02 11:09:48.872: E/AndroidRuntime(9550): ... 10 more
Please advise my where I'm wrong.
Thanks a lot.
Thanks, I should have used:
PendingIntent pi=PendingIntent.getService(ctxt, 0, i, 0);
On MyAlarmManager.
The Service code here gets some items from an RSS Feed. And then generates a List of the Items. The method getItems() is the one that exposes what has been brought in.
public class RssService extends Service {
ThisBinder mBinder = new ThisBinder();
private List<Item> items;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Hid some code for brevity
Log.i("items", Arrays.deepToString(items.toArray()));
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
List<Item> getItems(){
return items;
}
class ThisBinder extends Binder{
RssService getService() {
return RssService.this;
}
}}
This BroadcastReceiver here starts the service every 15 minutes.
public class RssReciever extends BroadcastReceiver {
Long REPEAT_TIME = 15L * 60L * 1000L;
// Long REPEAT_TIME = 1000L;
RssService rssService;
IBinder binder;
private Context mContext;
#Override
public void onReceive(Context context, Intent intent) {
mContext = context;
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();
cal.add(Calendar.SECOND, 30);
service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), REPEAT_TIME, pending);
Toast.makeText(mContext, "Connected, total Items, " + rssService.getItems().size(), Toast.LENGTH_SHORT).show();
}
}
I need to use the RssService.getItems() method here so that I can generate a notification. So far I haven't been able to do this. I can't seem to find the proper way to get an instance of the service.
How can this be done?
Presently, I am working on app that works like "To Do Task List". I have successfully implemented the NotificationService and SchedularService in my application. Also I am getting the alerts(Notifications) at the time set for the tasks.
Here are my queries as below:
With this code will my alarms will be deleted after reboot ? If yes, how to overcome this.
I have kept the Priority feature for the tasks. But i want the mechanism such that if user selects priority "High" then he should receive notifications thrice, say, before 30 minutes, before 15 minutes and on the time set. How to achieve this ?
I want to set Phone's vibrate feature when Notifications are raised. How to achieve this ?
And i want to know about, what can be done for the deprecated methods and constructor in NotifyService.java. Thesse are deprecated in API level 11: Notification notification = new Notification(icon, text, time); and notification.setLatestEventInfo(this, title, text, contentIntent);. On developer.android.com, they have suggested to Use Notification.Builder instead. So how to make my app compatible with all the API levels.
Here's my snippet code for scheduling alarm:
...
scheduleClient.setAlarmForNotification(c, tmp_task_id);
...
Here's the class ScheduleClient.java:
public class ScheduleClient {
private ScheduleService mBoundService;
private Context mContext;
private boolean mIsBound;
public ScheduleClient(Context context)
{
mContext = context;
}
public void doBindService()
{
mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((ScheduleService.ServiceBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
public void setAlarmForNotification(Calendar c, int tmp_task_id){
mBoundService.setAlarm(c, tmp_task_id);
}
public void doUnbindService() {
if (mIsBound)
{
mContext.unbindService(mConnection);
mIsBound = false;
}
}
}
Here's the ScheduleService.java:
public class ScheduleService extends Service {
int task_id;
public class ServiceBinder extends Binder {
ScheduleService getService() {
return ScheduleService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new ServiceBinder();
public void setAlarm(Calendar c, int tmp_task_id) {
new AlarmTask(this, c, tmp_task_id).run();
}
}
Here's the AlarmTask.java:
public class AlarmTask implements Runnable{
private final Calendar date;
private final AlarmManager am;
private final Context context;
int task_id;
public AlarmTask(Context context, Calendar date, int tmp_task_id) {
this.context = context;
this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.date = date;
task_id = tmp_task_id;
}
#Override
public void run() {
Intent intent = new Intent(context, NotifyService.class);
intent.putExtra(NotifyService.INTENT_NOTIFY, true);
intent.putExtra("task_id", task_id);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
am.set(AlarmManager.RTC, date.getTimeInMillis(), pendingIntent);
}
}
Here's the NotifyService.java:
public class NotifyService extends Service {
public class ServiceBinder extends Binder
{
NotifyService getService()
{
return NotifyService.this;
}
}
int task_id;
private static final int NOTIFICATION = 123;
public static final String INTENT_NOTIFY = "com.todotaskmanager.service.INTENT_NOTIFY";
private NotificationManager mNM;
SQLiteDatabase database;
#Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String tmp_task_brief = null;
task_id = intent.getIntExtra("task_id", 0);
loadDatabase();
Cursor cursor = database.query("task_info", new String[]{"task_brief"}, "task_id=?", new String[]{task_id+""}, null, null, null);
while(cursor.moveToNext())
{
tmp_task_brief = cursor.getString(0);
}
cursor.close();
if(intent.getBooleanExtra(INTENT_NOTIFY, false))
showNotification(tmp_task_brief);
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new ServiceBinder();
private void showNotification(String tmp_task_brief) {
CharSequence title = "To Do Task Notification!!";
int icon = R.drawable.e7ca62cff1c58b6709941e51825e738f;
CharSequence text = tmp_task_brief;
long time = System.currentTimeMillis();
Notification notification = new Notification(icon, text, time);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TaskDetails.class), 0);
notification.setLatestEventInfo(this, title, text, contentIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
mNM.notify(NOTIFICATION, notification);
stopSelf();
}
void loadDatabase()
{
database = openOrCreateDatabase("ToDoDatabase.db",
SQLiteDatabase.OPEN_READWRITE, null);
}
}
With this code will my alarms will be deleted after reboot ? If yes, how to overcome this.
Yes alarm will get deleted, to overcome this, you need to use Android's Component called BroadcastReceiver as follows,
First, you need the permission in your manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Also, in your manifest, define your service and listen for the boot-completed action:
<receiver
android:name=".receiver.StartMyServiceAtBootReceiver"
android:enabled="true"
android:exported="true"
android:label="StartMyServiceAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Then you need to define the receiver that will get the BOOT_COMPLETED action and start your service.
public class StartMyServiceAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceIntent = new Intent("com.myapp.NotifyService");
context.startService(serviceIntent);
}
}
}
And now your service should be running when the phone starts up.
2 For Vibration
Again you need to define a permission in AndroidManifest.xml file as follows,
<uses-permission android:name="android.permission.VIBRATE"/>
Here is the code for vibration,
// Get instance of Vibrator from current Context
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 300 milliseconds
v.vibrate(300);
I have this service:
public class AAAService extends Service {
private Intent requestService;
private Intent calendarService;
private SharedPreferences servicePreferences;
private static final String REQUEST_DELAY = "request_interval";
private static final int REQUEST_DELAY_DEFAULT = 900000;
private static final String SERVICE = "service";
private static final String SOUND = "sound";
private static final String VIBRATE = "vibrate";
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
Log.i("daim", "AAAService has started ...");
requestService = new Intent(this, RequestService.class);
calendarService = new Intent(this, CalendarService.class);
servicePreferences = getSharedPreferences(SERVICE, MODE_PRIVATE);
long delay = Long.valueOf(servicePreferences.getInt(REQUEST_DELAY, REQUEST_DELAY_DEFAULT));
if(delay > 0){
startRequestService();
}
startCalendarService();
}
#Override
public void onDestroy(){
super.onDestroy();
Log.i("daim", "AAAService has stopped ...");
stopRequestService();
stopCalendarService();
}
public void startRequestService(){
startService(requestService);
}
public void stopRequestService(){
stopService(requestService);
}
public void startCalendarService(){
startService(calendarService);
}
public void stopCalendarService(){
stopService(calendarService);
}
}
And this two other Services:
public class RequestService extends AAAService
public class CalendarService extends AAAService
Both these has onCreate and onDestroy method, in order to start and stop the service.
The problem I'm facing here, is that when I start my AAAService from the an Activity it gets started, and yes it starts the other two services, but right after that it get stopped (onDestroy method), and I don't know why!
This is what I do from my Activity:
Intent service = new Intent(this, AAAService.class);
startService(service);
Any help is appreciated!
Thanks.
My two other services:
public class CalendarService extends AAAService{
private CalendarApi calendarApi;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i("daim", "CalendarService has started ...");
calendarApi = AAALifestyleApplication.calendarApi;
startService();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("daim", "CalendarService has stopped ...");
}
public void startService(){
Log.d("daim", "UPDATING EVENTS FROM CALENDAR SERVICE!!!");
ArrayList<Long> dates = new ArrayList<Long>();
dates.add(0L);
dates.add(System.currentTimeMillis() * 2);
calendarApi.getEventsFromDrupal(dates, this, null);
stopSelf();
}
}
public class RequestService extends AAAService implements RequestListener{
private Timer timer;
private CommonApi commonApi;
private NotificationManager nManager;
private Notification notification;
private PendingIntent pIntent;
private Intent intent;
private Context context;
private SharedPreferences sharedPref;
private long delay;
private boolean sound, vibrate;
private static final int INTERVAL_DEFAULT = 900000;
private static final String SERVICE_NAME = "service";
private static final String INTERVAL_KEY = "request_interval";
private static final String SOUND = "sound";
private static final String VIBRATE = "vibrate";
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i("daim", "RequestService has started ...");
sharedPref = getSharedPreferences(SERVICE_NAME, MODE_PRIVATE);
startService();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("daim", "RequestService has stopped ...");
if(timer != null){
timer.cancel();
}
}
public void startService(){
Log.d("daim", "UPDATING REQUESTS FROM REQUEST SERVICE!!!");
int intervalInteger = sharedPref.getInt(INTERVAL_KEY, INTERVAL_DEFAULT);
delay = Long.valueOf(intervalInteger);
sound = sharedPref.getBoolean(SOUND, true);
vibrate = sharedPref.getBoolean(VIBRATE, true);
Log.d("daim", "sound: " + sound);
Log.d("daim", "vibrate: " + vibrate);
Log.d("daim", "delay: " + delay);
commonApi = AAALifestyleApplication.commonApi;
timer = new Timer();
if(delay > 0){
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if(commonApi.isLoggedIn()){
commonApi.getRequests(RequestService.this, false);
}
}
}, 0, delay);
}
}
#Override
public void onRequestResult(ArrayList<Request> requests) {
for(Request r : requests){
if(!commonApi.hasRequest(r)){
sendNotification();
}
}
}
#Override
public void onAuthenticationError() {
// TODO Auto-generated method stub
}
#Override
public void onConnectionError() {
// TODO Auto-generated method stub
}
private void sendNotification(){
context = getApplicationContext();
nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notification = new Notification(R.drawable.icon, "You received new requests", System.currentTimeMillis());
intent = new Intent(getBaseContext(), RequestsActivity.class);
pIntent = PendingIntent.getActivity(getBaseContext(), 0, intent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
notification.setLatestEventInfo(context, "Request notification", "Click here to see your requests", pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
if(vibrate){
notification.defaults |= Notification.DEFAULT_VIBRATE;
}
if(sound){
notification.defaults |= Notification.DEFAULT_SOUND;
}
nManager.notify(0, notification);
}
}
In my CalendarService i had the method stopSelf(); which I thought stopped itself, but did also stop AAAService which will stop the RequestService as well. Problem solved!
Your service inheritance/polymorphism hierarchy mess up all your services creation lifecycle. Take CalendarService as an example, the first thing in CalendarService.onCreate() is calling its super.onCreate(), in the super service onCreate method(your AAAService.onCreate()) it start the concrete service (your CalendarService), so both your AAAService and CalendarService get recursively created many times.
If the only thing AAAService does is created its child service, You should drop your AAAService and directly create/start your CalendarService and RequestService in your Activity.
Alternatively, you can simply try break your inheritance/polymorphism and make all your services independent. it should fix your problem.
correct me if I'm wrong, but aren't you starting the CalendarService from AAAService 's onCreate? and that's why your CalendarService is started when you start AAAService