I want to start service in BroadcastReceiver (BOOT_COMPLETED) and make Notification from it.
Like this:
public class AutoLoad extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
Intent i = new Intent(context, MyService.class);
i.putExtra("screen_state", false);
context.startService(i);
}
}
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Notification notification = new
NotificationCompat.Builder(getApplicationContext()).setContentTitle("New mail from ").setContentText("Text")
.setSmallIcon(android.R.drawable.btn_plus).build(); // addAction
NotificationManager nm = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(0, notification);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
But no notification I can see. Please help!
You will need an Activity and run it at least once in order to be able to register to BOOT_COMPLETED intents.
Related
I created an Android application to get all the call logs after the user ends the call. I used Broadcast Receiver to identify the changes then Run the service to get the information about the last call. But sometimes App is killed by the system after one or two days. I read the Broadcast Documentation, Android Service Documentation, and Android <OREO Restriction. Is there any way to keep the Call Broadcast Receiver all the time?
Is there any way to use work manager?
Is there any good approaches, please share here
Service class
public class CallReceiver extends BroadcastReceiver{
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, HammerService.class);
context.startForegroundService(startServiceIntent);
}
}
Service class
public class HammerService extends Service {
#Override
public void onCreate() {
super.onCreate();
IntentFilter ifilter = new IntentFilter();
ifilter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, ifilter);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Hammer Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
//stopSelf();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent intent) {
String action = intent.getAction();
if(action.equals("android.provider.Telephony.SMS_RECEIVED")){
//action for sms received
}
else if(action.equals(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED)){
runfirstTime(context,intent);
}
}
};
I am using a service to start the mediaplayer as soon as the notification is shown and then stop the service when the action button is pressed. The service starts fine. But the service doesn't stop on clicking the action button.
This is my notification builder
public NotificationCompat.Builder getReminderNotification(String title,String message,PendingIntent intent1){
return new NotificationCompat.Builder(getApplicationContext(),reminderChannelID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.drawable.ic_medicine)
.setColor(getResources().getColor(R.color.colorPrimary))
.setOngoing(true)
.addAction(R.drawable.ic_arrow_back,"OK",intent1);
}
public void cancelNotification() {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(1); // Notification ID to cancel
}
public void startMyService(){
startService(new Intent(this, TimerService.class));
}
public void stopMyService(){
stopService(new Intent(this,TimerService.class));
}
This is my reminder receiver:
public class ReminderReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationHelper notificationHelper = new NotificationHelper(context);
Intent newIntent = new Intent(context,DismissReminderReceiver.class);
newIntent.putExtra("action","stop");
PendingIntent intent1 = PendingIntent.getBroadcast(context,0,newIntent,0);
Bundle extras = intent.getExtras();
String title=extras.getString("title");
String message=extras.getString("message");
NotificationCompat.Builder builder = notificationHelper.getReminderNotification(title, message,intent1);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context.getApplicationContext(),TimerService.class));
}else {
notificationHelper.startMyService();
}
notificationHelper.getManager().notify(1, builder.build());
}}
This is my code to dismiss the notification
public class DismissReminderReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("Here");
Bundle extras = intent.getExtras();
String action = extras.getString("action");
System.out.println(action);
if (action.equals("stop")) {
NotificationHelper notificationHelper = new NotificationHelper(context);
notificationHelper.stopMyService();
notificationHelper.cancelNotification();
}
}}
And this is my service:
public class TimerService extends Service {
public Context context = this;
public Handler handler = null;
public Runnable runnable = null;
MediaPlayer mediaPlayer;public TimerService(){}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
System.out.println("Service Started");
mediaPlayer=MediaPlayer.create(context, Settings.System.DEFAULT_RINGTONE_URI);
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
mediaPlayer.start();
}
};
handler.postDelayed(runnable,0);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
mediaPlayer.stop();
}}
I also don't see where you register the receiver - if you're doing it in the manifest, make sure it's there with a matching action (and the receiver stanza is there to begin with).
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 have an activity with two buttons (ON and OFF): when I click the ON button a service starts. When I click the OFF botton the service stops. Now, my service does not have problems apart from when I kill the app from "Recent Apps" because in this circumstance the service restarts. I don't want that it restarts but I want that it continues working. The service is a START_STICKY.
This is my "service" code:
#Override
public void onCreate() {
// TODO Auto-generated method stub
myServiceReceiver = new MyServiceReceiver();
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// Display a notification about us starting. We put an icon in the status bar.
showNotification();
}
public class LocalBinder extends Binder {
SensorService getService() {
return SensorService.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
}
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
if (!running){
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MY_ACTION_FROMACTIVITY);
registerReceiver(myServiceReceiver, intentFilter);
running = true;
sensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_NORMAL);
}
//return super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onDestroy() {
Log.v(TAG,"destroy");
// TODO Auto-generated method stub
sensorManager.unregisterListener(this);
mNM.cancel(NOTIFICATION);
this.unregisterReceiver(myServiceReceiver);
super.onDestroy();
}
private void showNotification() {
CharSequence text = getText(R.string.activity);
Notification notification = new Notification(R.drawable.lifestyle, text, System.currentTimeMillis());
SharedPreferences flagNot = getSharedPreferences("flagNotification", 0);
final SharedPreferences.Editor editor = flagNot.edit();
editor.putBoolean("flagNotification",true);
editor.commit();
Intent notificationIntent = new Intent(this, ActivityTab.class);
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.app_name),text, contentIntent);
notification.flags |= Notification.FLAG_NO_CLEAR;
// Send the notification.
mNM.notify(NOTIFICATION, notification);
}
public void onAccuracyChanged(Sensor sensor,int accuracy){
}
public void onSensorChanged(SensorEvent event){
......
}
public class MyServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
int hostCmd = arg1.getIntExtra(CMD, 0);
if(hostCmd == CMD_STOP){
running = false;
stopSelf();
}
}
}
}
Can you help me,please?
Many thanks.
Implement startForeground in your service and send it a persistent notification.
private void startForeground() {
int ID = 1234;
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(getBaseContext());
builder.setContentIntent(pendIntent);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setTicker("CUSTOM MESSAGE");
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(false);
builder.setContentTitle("Test Service");
builder.setContentText("CUSTOM MESSAGE");
Notification notification = builder.build();
startForeground(ID, notification);
}
I am trying to capture the following two broadcasts (android.intent.action.SCREEN_ON & android.intent.action.SCREEN_OFF) from my running foreground service (code below).
Only "android.intent.action.SCREEN_ON" is getting captured.
if(intent.getAction().equals("android.intent.action.SCREEN_OFF")) in onReceive() never gets fired ... neither does myBroadcast_screenoff.
What am I doing wrong here?
(Basic question is how to capture two different intents from a single service)
public class ServiceDataSaver extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
BroadcastReceiver myBroadcast = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.intent.action.SCREEN_ON")) {
Log.v("datasaver", "Screen just turned on");
}
if(intent.getAction().equals("android.intent.action.SCREEN_OFF")) {
Log.v("datasaver", "Screen just turned off");
}
}
};
BroadcastReceiver myBroadcast_screenoff = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.intent.action.SCREEN_OFF")) {
Log.v("datasaver", "Screen just turned off");
}
}
};
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
IntentFilter filter = new IntentFilter("android.intent.action.SCREEN_ON");
filter.setPriority(999);
registerReceiver(myBroadcast, filter);
IntentFilter filter_screenoff = new IntentFilter("android.intent.action.SCREEN_ON");
filter_screenoff.setPriority(999);
registerReceiver(myBroadcast_screenoff, filter_screenoff);
}
#Override
public void onDestroy() {
super.onDestroy();
// Do not forget to unregister the receiver!!!
//this.unregisterReceiver);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
//return super.onStartCommand(intent, flags, startId);
makeServiceForeground(intent);
return START_NOT_STICKY;
}
public void makeServiceForeground(Intent receivedIntent) {
final int myID = 1234;
// The intent to launch when the user clicks the expanded notification
Intent returningintent = new Intent(this, MainActivitySlidingLayer.class);
receivedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0,
returningintent, 0);
// This constructor is deprecated. Use Notification.Builder instead
Notification notice = new Notification(R.drawable.ic_launcher,
"Facebook is Blocked", System.currentTimeMillis());
// This method is deprecated. Use Notification.Builder instead.
notice.setLatestEventInfo(this, "Facebook is blocked",
"Click here to unblock it ...", pendIntent);
notice.flags |= Notification.FLAG_NO_CLEAR;
startForeground(myID, notice);
}
}
Probably just the typo. You're not registering for SCREEN_OFF intent.
In OnCreate()
IntentFilter filter_screenoff = new IntentFilter("android.intent.action.SCREEN_ON");
should be
IntentFilter filter_screenoff = new IntentFilter("android.intent.action.SCREEN_OFF");
and of course you'd better use the constants provided by Intent.ACTION_SCREEN_OFF and Intent.ACTION_SCREEN_ON anyway.