I have a service that posts a notification, and what I am trying to do is kill that service when the notification is clicked. Here is my code:
#SuppressWarnings("deprecation")
#Override
public void onCreate() {
super.onCreate();
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification n = new Notification(R.drawable.ic_launcher,
getResources().getString(R.string.notify_body),
System.currentTimeMillis());
n.setLatestEventInfo(getApplicationContext(),
getResources().getString(R.string.notify_title), getResources()
.getString(R.string.notify_body), PendingIntent
.getActivity(getApplicationContext(), 0, new Intent(
this, StopSelf.class), Intent.FLAG_ACTIVITY_NEW_TASK));
n.defaults = Notification.DEFAULT_ALL;
nm.notify(ID, n);
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
nm.cancel(ID);
}
public class StopSelf extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
stopService(new Intent(this, myService.class));
this.finish();
}
}
When I click the notification the statusbar is dismissed, but the notification is still there. Why isn't StopSelf killing the service and calling onDestroy?
Related
this code get request from server and do some thing. i want when app is closed get request and show it by notification. i can get message from firebase and show it but this is not something that i want
MyActivity
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
public class MyActivity extends ActionBarActivitiy implements AsyncTaskCompleteListener{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
.
.
.
}
private void displayFirebaseRegId() {
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
String regId = preferenceHelper.getSessionToken();
if (!TextUtils.isEmpty(regId))
}
private void subscribeToPushService() {
FirebaseMessaging.getInstance().subscribeToTopic("news");
String token = FirebaseInstanceId.getInstance().getToken();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
#Override
protected void onDestroy() {
}
#Override
public void onTaskCompleted(String response, int service) {
super.onTaskCompleted(response, service);
switch (service) {
case MyValues.Service.REQUEST_NEW:
// addNotification();
...
if (requestId == MyValues.NO_REQUEST) {
addNotification();
addNewFragment(new myFragment(), false,
MyValues.REQUEST_, true);
} else {
...
}
break;
}
}
ActionBarActivitiy
abstract public class ActionBarActivitiy extends AppCompatActivity implements OnClickListener , AsyncTaskCompleteListener
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
public void addNotification() {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(MyApplication.applicationContext)
.setSmallIcon(R.mipmap.ic_cl)
.setContentTitle("Notifications get request")
.setContentText("This is get request notification");
Intent notificationIntent = new Intent(MyApplication.applicationContext, MainActivity.class);
PendingIntent contentIntent =
PendingIntent.getActivity(MyApplication.applicationContext, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
builder.setSound(Uri.parse("android.resource://"
+ MyApplication.applicationContext.getPackageName() + "/" + R.raw.sfx_counter_loop));
// builder.setOngoing(true);
try {
builder.setWhen(System.currentTimeMillis());
builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
builder.setLights(Color.RED, 3000, 3000);
}catch (Exception e){
}
// Add as notification
NotificationManager manager = (NotificationManager)
MyApplication.applicationContext.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, builder.build());
}
#Override
public void onTaskCompleted(String response, int service) {
}
....
}
interface AsyncTaskCompleteListener
public interface AsyncTaskCompleteListener
{
void onTaskCompleted(String response, int service);
}
You can use A service, An alarm manager to do so.
Schedule a timer tat will run the service. The service will fetch the data and then show the notification. You can also use IntentService for that so as to free up your main thread.
Edit
Here is an link for alarm manager :
https://developer.android.com/training/scheduling/alarms.html
and IntentService :
https://developer.android.com/training/run-background-service/create-service.html
Also, to call certain task before your app gets close, call your method in onStop right before calling super.
My Scenario is to show Greeting notification to my users even they are not using the app. Below code is working fine if the open is opened or minimized. But, I want to show the notification in morning even though the user did not open the application.
Main Activity:
public class MainActivity extends Activity {
private PendingIntent pendingIntent;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 18);
calendar.set(Calendar.MINUTE, 40);
calendar.set(Calendar.SECOND, 0);
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
} //end onCreate
}
My Receiver Class:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
/*Intent service1 = new Intent(context, MyAlarmService.class);
context.startService(service1);*/
try{
Utils.generateNotification(context);
}catch(Exception e){
e.printStackTrace();
}
}
}
Utils Class:
public class Utils {
public static NotificationManager mManager;
#SuppressWarnings("static-access")
public static void generateNotification(Context context){
mManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Intent intent1 = new Intent(context,MainActivity.class);
Notification notification = new Notification(R.drawable.ic_launcher,"This is a test message!", System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(context,0, intent1,PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, "AlarmManagerDemo", "This is a test message!", pendingNotificationIntent);
mManager.notify(0, notification);
}
}
My Alarm Service:
public class MyAlarmService extends Service {
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
// TODO Auto-generated method stub
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
}
#Override
public void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
}
}
Next Activity:
public class NextActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
A few things you need to do here. If the user force closes the app, you need to ensure that you start your service with START_STICKY so that the service restarts when the app is force closed.
In order to get the Service to start when the user has rebooted their phone, you will need your BroadcastReceiver to receive BOOT_COMPLETED which will then start the service.
Your service will then set the Alarm as per normal. You will need to store the time of the alarm you want to set somewhere. I use SharedPrefs (PreferenceManager.getDefaultSharedPreferences(getApplicationContext());) but I'm sure there are better methods.
I create a service and put it in the foreground with a notification. In the service I have a timer that just prints "SERVICE STILL RUNNING" to let me know the service is still alive. When I close the app, the OnDestroy() of the service is called but the timmer keeps printing "SERVICE STILL RUNNING" why is that? I put the service in the foreground by calling showNotification(). If I don't call showNotification() and close the app the service gets destroyed and the timmer stops printing "SERVICE STILL RUNNING". How can I have the service in the foreground and kill it correctly when the app is closed. The memory monitor continues to show the memory usage even after the app is closed. If I dont put the service in the foreground and close the app, the memory monitor stops.This problem only happens and android 6.0.
MainActivity:
public class MainActivity extends Activity {
Intent service;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
service = new Intent(MainActivity.this, MyService.class);
// starting Client service
service.setAction("START");
startService(service);
}
#Override
protected void onDestroy() {
super.onDestroy();
service.setAction("STOP");
stopService(service);
}
}
Service:
public class MyService extends Service {
Timer timer;
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
if(intent !=null)
{
if(intent.getAction().equals("START"))
{
showNotification();
} else if(intent.getAction().equals("STOP"))
{
stopForeground(true);
stopSelf();
}
}else
{
//stopForeground(true);
//stopSelf();
}
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run()
{
Log.d("","SERVICE STILL RUNNING");
}
},1*1000,5*1000);
}
private void showNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction("new");
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Title")
.setTicker("Test")
.setContentText("testing")
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true).build();
startForeground(101, notification);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("","SERVICE HAS BEEN DESTROYED!!!");
}
}
Try adding this on you Service's onDestroy
#Override
public void onDestroy() {
super.onDestroy();
timer.cancel();
timer = null;
stopForeground(true);//Add this. Since stopping a service in started in foreground is different from normal services.
Log.d("","SERVICE HAS BEEN DESTROYED!!!");
}
EDIT
On your Activity's onDestroy method
#Override
protected void onDestroy() {
super.onDestroy();
service.setAction("STOP");
service.executeStopForeground();
stopService(service);
}
Then add this method on your service:
public void executeStopForeground()
{
stopForeground(true);
}
Use inside your service code:
#Override
public void onDestroy() {
stopForeground(true);
super.onDestroy();
System.exit(0); //We terminate the app!
}
Hello friends I'm developing an Battery android application. which show battery level(%) on Status bar after closing application. I start an service class that run as background process and put some code.
Notificationservice.java
public void onCreate(){
super.onCreate();
IntentFilter filter= new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus= getApplicationContext().registerReceiver(null, filter);
int status= batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
batteryLevel= String.valueOf(status);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//make the toast message
Toast.makeText(this, "Service Started"+batteryLevel+"%", Toast.LENGTH_LONG).show();
//show the notification on status bar
NotificationManager nm=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent2= new Intent(this, MainActivity.class);
PendingIntent pendingIntent= PendingIntent.getActivity(getApplicationContext(), 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mbuilder= new
NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Battery Level: "+batteryLevel+"%")
.setContentText("Battery Level: "+batteryLevel+"%")
.setContentIntent(pendingIntent);
nm.notify(notificationID, mbuilder.build());
return START_STICKY;
}
#Override
public void onDestroy(){
super.onDestroy();
Toast.makeText(getApplicationContext(), "service Destroy", Toast.LENGTH_SHORT).show();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
In MainActivity.java
rotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1= (Button) findViewById(R.id.button1);
b2= (Button) findViewById(R.id.button2);
tv= (TextView) findViewById(R.id.textView1);
createListener();
}
private void createListener() {
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startService(new Intent(getBaseContext(), Notificationservice.class));
}
});
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stopService(new Intent(getBaseContext(), Notificationservice.class));
}
});
}
When I press run application run properly but when I press start Service button battery level shows on status bar but it doesn't change/update it remains same. friends please help, what should I do....???
you need to start the service or notification from broadcast receiver..just register a broadcast to get battery level..and from onreceive() method of receiver..call notification or start a service..
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);
}