I want to call a service when a certain activity starts. So, here's the Service class:
public class UpdaterServiceManager extends Service {
private final int UPDATE_INTERVAL = 60 * 1000;
private Timer timer = new Timer();
private static final int NOTIFICATION_EX = 1;
private NotificationManager notificationManager;
public UpdaterServiceManager() {}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// Code to execute when the service is first created
}
#Override
public void onDestroy() {
if (timer != null) {
timer.cancel();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startid) {
notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
int icon = android.R.drawable.stat_notify_sync;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "My notification";
CharSequence contentText = "Hello World!";
Intent notificationIntent = new Intent(this, Main.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
notificationManager.notify(NOTIFICATION_EX, notification);
Toast.makeText(this, "Started!", Toast.LENGTH_LONG);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Check if there are updates here and notify if true
}
}, 0, UPDATE_INTERVAL);
return START_STICKY;
}
private void stopService() {
if (timer != null) timer.cancel();
}
}
And here is how I call it:
Intent serviceIntent = new Intent();
serviceIntent.setAction("cidadaos.cidade.data.UpdaterServiceManager");
startService(serviceIntent);
The problem is that nothing happens. The above code block is called at the end of the activity's onCreate. I already debugged and no exception is thrown.
Any idea?
Probably you don't have the service in your manifest, or it does not have an <intent-filter> that matches your action. Examining LogCat (via adb logcat, DDMS, or the DDMS perspective in Eclipse) should turn up some warnings that may help.
More likely, you should start the service via:
startService(new Intent(this, UpdaterServiceManager.class));
startService(new Intent(this, MyService.class));
Just writing this line was not sufficient for me. Service still did not work. Everything had worked only after registering service at manifest
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
...
<service
android:name=".MyService"
android:label="My Service" >
</service>
</application>
Java code for start service:
Start service from Activity:
startService(new Intent(MyActivity.this, MyService.class));
Start service from Fragment:
getActivity().startService(new Intent(getActivity(), MyService.class));
MyService.java:
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static String TAG = "MyService";
private Handler handler;
private Runnable runnable;
private final int runTime = 5000;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
handler.postDelayed(runnable, runTime);
}
};
handler.post(runnable);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
if (handler != null) {
handler.removeCallbacks(runnable);
}
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#SuppressWarnings("deprecation")
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG, "onStart");
}
}
Define this Service into Project's Manifest File:
Add below tag in Manifest file:
<service android:enabled="true" android:name="com.my.packagename.MyService" />
Done
I like to make it more dynamic
Class<?> serviceMonitor = MyService.class;
private void startMyService() { context.startService(new Intent(context, serviceMonitor)); }
private void stopMyService() { context.stopService(new Intent(context, serviceMonitor)); }
do not forget the Manifest
<service android:enabled="true" android:name=".MyService.class" />
Intent serviceIntent = new Intent(this,YourActivity.class);
startService(serviceIntent);
add service in manifist
<service android:enabled="true" android:name="YourActivity.class" />
for running service on oreo and greater devices use for ground service and show notification to user
or use geofencing service for location update in background
reference
http://stackoverflow.com/questions/tagged/google-play-services
Related
i have a probleme with BroadcastReceiver & Service in my application
.......
i have an
* activity ( MainActivity )
* service ( NotifyService )
* Receiver ( NotifyBroadcast )
service start from activity and then the receiver start from service
everything is good when my app was open , but when i clear it (destroyed) ,receiver stop doing its job ( just a toast message )
here is my code :
MainActivity ..
if( !NotifyService.ServiceIsRun){
NotifyService.ServiceIsRun=true;
startService(new Intent(this, NotifyService.class));
}
NotifyService ..
public class NotifyService extends Service {
public static boolean ServiceIsRun=false;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timer t = new Timer();
if(ServiceIsRun){
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.e("broadService", "hello from Service"+i +"new :"+lastnew +"article :"+lastarticle);
i++;
Intent intent = new Intent( "com.latestBabiaNews" );
sendBroadcast(intent);
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
20000);
}
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
NotifyBroadcast ..
public class NotifyBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final Bundle bundle = intent.getExtras();
if (intent.getAction().equalsIgnoreCase("com.latestBabiaNews")){
Toast.makeText(context,"hello from Broadcast",Toast.LENGTH_SHORT).show();
}
}
}
And in my Manifest ..
<service android:name=".NotifyService"></service>
<receiver android:name=".NotifyBroadcast">
<intent-filter>
<action android:name="com.latestBabiaNews"></action>
</intent-filter>
</receiver>
..........
finally i can show the Toast message when app was app was opened , but when i clear it i can't show anything !
To prevent service kill use it as foreground service. To perform it as foreground use this (inside Service class):
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
fg();
}
private void fg() {
Intent intent = launchIntent(this);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle(getResources().getString(R.string.app_alias))
.setContentText(getResources().getString(R.string.app_alias))
.setContentIntent(pIntent);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setSmallIcon(someicon);
} else {
mBuilder.setSmallIcon(someicon);
mBuilder.setColor(somecolo);
}
noti = mBuilder.build();
noti.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
startForeground(_.ID, noti);
}
to stop, this:
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
stopForeground(true);
}
EDIT
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
public class MyBroadCast extends WakefulBroadcastReceiver {
public static final String INTENT_FILTER = "ru.ps.vm.BRTattva";
#Override
public void onReceive(Context ctx, Intent intent) {
Toast.makeText(context,"hello from Broadcast",Toast.LENGTH_SHORT).show();
}
}
To start use this:
public static void startbyalarm(Context ctx, long nexttime, boolean autoStart, SharedPreferences settings) {
AlarmManager am = (AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);
Intent intent = new Intent(MyBroadcastReceiver.INTENT_FILTER);
if (autoStart)
intent.putExtra(_.AUTOLOADSERVICE,true);
PendingIntent pi = PendingIntent.getBroadcast(ctx, _.intentalarmindex, intent, PendingIntent.FLAG_CANCEL_CURRENT);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion < android.os.Build.VERSION_CODES.KITKAT){
am.set(AlarmManager.RTC_WAKEUP, nexttime, pi);
} else {
if (currentapiVersion < android.os.Build.VERSION_CODES.M) {
am.setExact(AlarmManager.RTC_WAKEUP, nexttime, pi);
} else {
am.setExactAndAllowWhileIdle(wakeup?AlarmManager.RTC_WAKEUP:AlarmManager.RTC, nexttime, pi);
}
}
//or use repeating:
//am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 5 , pi);
}
I'm new to services and BroadcastReceiver so maybe this question is newbie, but I didn't found the solution for my question after a long search on the web.
I need to run a CountDownTimer inside service, so the time keep moving even the application was finished.
In my code I based on THIS EXAMPLE.
My code works fine, but after the application is finished the CountDownTimer stopped(The service doesn't destroyed, just the timer).
I tried to implement it in different ways, but nothing works for me.
This is the part of my code that relevant:
AlarmReciver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent background = new Intent(context, BackgroundService.class);
Bundle bundle = intent.getExtras();
background.putExtra("time", bundle.getInt("time"));
context.startService(background);
}
}
BackgroundService :
public class BackgroundService extends Service {
private final static String TAG = "BroadcastService";
private CountDownTimer cdt = null;
private Bundle bundle;
private boolean isRunning;
private Context context;
private int timeInMili;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
this.context = this;
this.isRunning = false;
}
#Override
public void onDestroy() {
//cdt.cancel();
Log.i(TAG, "Timer cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
bundle = intent.getExtras();
timeInMili = bundle.getInt("time");
if(!this.isRunning) {
this.isRunning = true;
}
cdt = new CountDownTimer(timeInMili, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
stopSelf();
}
};
cdt.start();
return START_STICKY;
}
}
MainActivity (extends FragmentActivity):
public void StartBackgroundAlarm(int timeInMili)
{
Intent alarm = new Intent(this, AlarmReceiver.class);
alarm.putExtra("time", timeInMili);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarm, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), pendingIntent);
}
MANIFEST :
<service android:enabled="true" android:name= "com.MES.yo.servicemanager.BackgroundService" />
<receiver android:name="com.MES.yo.servicemanager.AlarmReceiver"></receiver>
I have a service to show notification at a specific time and one broadcastreceiver for starting this service. When the app is started, the service is started and shows notification and shows the service in app running on the device, but sometimes in the running app service is a Restarting and the message does not display.
my service code is:
public class NotificationService extends Service {
private boolean flag=false;
public static NotificationCompat.Builder mBuilder;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timer timer=new Timer();
final Context context=getApplicationContext();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if(CheckTime()){
//Intent intent = new Intent(context, NotificationReciver.class);
//sendBroadcast(intent);
showNotification();
}
}
},0,(1000*60));
return START_NOT_STICKY;
}
private boolean CheckTime(){
final Context context=getBaseContext();
Calendar calendar=Calendar.getInstance();
int hour=calendar.get(Calendar.HOUR_OF_DAY);
int minute=calendar.get(Calendar.MINUTE);
if(hour==16 && minute==11){
return true;
}else {
return false;
}
}
private void showNotification() {
Context context=getApplicationContext();
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent intent=new Intent(context, QuestionActivity.class);
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,intent,0);
mBuilder = new NotificationCompat.Builder(context).
setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Feelinger")
.setContentText("How are you feeling today?")
.setSound(alarmSound)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setVibrate(new long[]{300, 200, 200, 200});
android.app.NotificationManager mNotificationManager = (android.app.NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(100, mBuilder.build());
}
and BroadcastReceiver code is:
public class NotificationManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context,NotificationService.class));
}
How to solve this problem?
Write inside service
#Override
public int onStartCommand (Intent intent, int flags, int startId)
{
return START_NOT_STICKY;
}
I need to be able to start chronometer, then close activity, after that through notifications, back to that activity, and see the right time in chronometer.
What I've Done
A part of my Activity:
public void doClick(View target)
{
switch(target.getId())
{
case R.id.buttonStart:
{
Mchronometer.setBase(SystemClock.elapsedRealtime());
Mchronometer.start();
Intent intent = new Intent(RecentActivity.this, ChronometerService.class);
intent.putExtra("task_name",task_name);
intent.putExtra("task_id",task_id);
intent.putExtra("ellapsedTime",Mchronometer.getBase());
Log.d("base",""+Mchronometer.getBase());
startService(intent);
break;
}
case R.id.buttonStop:
{
stopService(new Intent(RecentActivity.this, ChronometerService.class));
Mchronometer.stop();
Mchronometer.setBase(SystemClock.elapsedRealtime());
break;
}
case R.id.button3:
{
break;
}
}
}
A part of my Service:
public class ChronometerService extends Service {
private ThreadGroup myThreads = new ThreadGroup("ServiceWorker");
private NotificationManager notificationMgr;
private int task_id;
private long ellapsedTime;
#Override
public void onCreate() {
super.onCreate();
notificationMgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
String task_name =intent.getExtras().getString("task_name");
task_id =intent.getExtras().getInt("task_id");
ellapsedTime = intent.getExtras().getLong("ellapsedTime");
Log.d("servicebase",""+ellapsedTime);
displayNotificationMessage(task_name);
new Thread(myThreads, new ServiceWorker(),"ChronometerService").start();
return START_STICKY;
}
private class ServiceWorker implements Runnable {
public void run() {
}
}
#Override
public void onDestroy()
{
myThreads.interrupt();
notificationMgr.cancelAll();
super.onDestroy();
}
public IBinder onBind(Intent intent) {
return null;
}
public void displayNotificationMessage(String message){
Notification notification = new Notification(R.drawable.emo_im_winking,message,System.currentTimeMillis());
notification.flags = Notification.FLAG_NO_CLEAR;
Intent intent = new Intent(this, RecentActivity.class);
intent.putExtra("task_id", task_id);
intent.putExtra("ellapsedTime",ellapsedTime);
Log.d("servicebase1",""+Long.toString(ellapsedTime));
PendingIntent contentintent = PendingIntent.getActivity(this,0,intent,0);
notification.setLatestEventInfo(this,"ChronometerService",message,contentintent);
notificationMgr.notify(0, notification);
}
}
I tried to send a message from activity to a service, which contains elapsed information.
If I started it first on my device (after system load) it's works right, but when I launch it again. The activity receives wrong message. It receives the time of the first service launched on the device.
As you can see I also send one more variable, and activity reads it correctly.
I've found a solution to my question.
It's simple.
It's needed to use flag(PendingIntent.FLAG_UPDATE_CURRENT)
PendingIntent contentintent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
And it's work fine.
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);