I can't stop my service with stopService(). I have tryed everything but it doesn't work. I stop my service only when I uninstall app.
public class Refresh extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "NESTO!", Toast.LENGTH_LONG).show();
Toast.makeText(this, "Your location is: "+MyLocation(), Toast.LENGTH_LONG).show();
return START_NOT_STICKY;
}
#Override
public void onCreate() {
Intent myService = new Intent(this, Refresh.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0,myService, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), 20* 1000, pendingIntent);
super.onCreate();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
public LatLng MyLocation(){
LocationManager locationManager=(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
Location location=locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
return new LatLng(location.getLatitude(), location.getLongitude());
}
}
And this is methods in main activity:
public void startService(){
startService(new Intent(getBaseContext(), Refresh.class));
}
public void stopService(){
stopService(new Intent(getBaseContext(),Refresh.class));
}
And this is how I call methods start and stop service:
public void onClick(View V){
stopService();
}
I think the alarm manager you are using to start the service is restarting the service for you,You have to stop that alarm,Stop the alarm like this
Intent intent = new Intent(this, YourService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1253, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
pass the SAME ID FOR THE PENDING INTENT which you used while creating the pending intent
You kill the service, but the alarm is still set, you have to cancel the pending intent from the alarm manager in onDestroy
You have to cancel your AlarmManager, so service will not restart every 20sec.
After that you can use stopService() just please insert what service you want to stop.
Create a intent...
Intent intent = new Intent(getBaseContext(), Refresh .class);
When you want to start the service:
startService(intent);
When you want to stop the service:
stopService(intent);
and again, cancel your AlarmManager :) do it before you call stopService();
alarm.cancel(pendingIntent);
Alarm can restart the service. You should cancel it.
Related
Am Working on a timer based app where the notification shows up when the timer starts to run. I have set it as ongoing so that it cannot be cleared.
I have used cancelAll() method for some cases which works fine but when I force close the app, the notification still shows up and cannot be removed and tried to use the method in onDestroy() method still the problem prevails.
Here is my code and created the channel in another class :
public void sendNotif(){
Intent resultIntent = new Intent(this, TimerActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
not = new NotificationCompat.Builder(this,Notif.CHANNEL_ID)
.setSmallIcon(R.drawable.curved_shape)
.setContentTitle("Productivity Timer")
.setContentText("Your Timer is Running")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_PROGRESS)
.setOngoing(true)
.setContentIntent(pendingIntent)
.build();
notificationManager.notify(1,not);
}
I found this great solution once, I will retype it here
Since your application and the notification are handled in different threads, so killing your application won't kill the notification. The solution is to create a Service to kill notification, since services will restart themselves when the app is killed suddenly, you can use the automatic restart to kill the notification.
Create the service class
public class KillNotificationsService extends Service {
public class KillBinder extends Binder {
public final Service service;
public KillBinder(Service service) {
this.service = service;
}
}
public static int NOTIFICATION_ID = 666;
private NotificationManager mNM;
private final IBinder mBinder = new KillBinder(this);
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
#Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNM.cancel(NOTIFICATION_ID);
}
}
Add it to your manifest
<service android:name="KillNotificationsService"></service>
Always create the Service before fireing the notification, and use the static notificationid
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder binder) {
((KillBinder) binder).service.startService(new Intent(
MainActivity.this, KillNotificationsService.class));
Notification notification = new Notification(
R.drawable.ic_launcher, "Text",
System.currentTimeMillis());
Intent notificationIntent = new Intent(MainActivity.this,
Place.class);
PendingIntent contentIntent = PendingIntent.getActivity(
MainActivity.this, 0, notificationIntent, 0);
notification.setLatestEventInfo(getApplicationContext(),
"Text", "Text", contentIntent);
NotificationManager mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNM.notify(KillNotificationsService.NOTIFICATION_ID,
notification);
}
public void onServiceDisconnected(ComponentName className) {
}
};
bindService(new Intent(MainActivity.this,
KillNotificationsService.class), mConnection,
Context.BIND_AUTO_CREATE);
I am having trouble to stop the alarm from ringing even after I have pressed the stopAlarm button. thank you for any help.
This is my start alarm switch in MainActivity java class.
public void switchClicked (View view) {
if (((Switch) view).isChecked()) {
Log.d("MainActivity", "Alarm On");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getMinute());
Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
setAlarmText("ON");
} else {
alarmManager.cancel(pendingIntent);
setAlarmText("OFF");
Log.d("MainActivity", "Alarm Off");
}
}
public void setAlarmText(String alarmText) {
alarmTextView.setText(alarmText);
}
Here is my StopAlarm button in MainActivity java class.
public void stopAlarm(View view) {
setAlarmText("Alarm stopped");
Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getService(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(pendingIntent);
}
This is the AlarmReciver java class.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
MainActivity inst = MainActivity.instance();
inst.setAlarmText("Alarm! Wake up! Wake up!");
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null) {
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
ringtone.play();
}
}
The problem is in this line
pendingIntent = PendingIntent.getService(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
You are using getService() but you should use getBroadcast() instead.
Why?
getService() retrieves a PendingIntent that will start a service, but since you are using a BroadcastReceiver you should use getBroadcast() that retrieves a PendingIntent that will perform a broadcast.
I am starting to learn about the AlarmManager, and I want to fire a broadcast to fetch some info from a server. The documentation is clear about the intents and the alarms, but I cannot find anything on how the receiving end should look.
This is my alarm code:
AlarmManager aMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
aMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 10000,
AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);
and my AlarmReceiver is like this:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(MainActivity.TAG, "Received intent");
}
}
But nothing happens. I added a button to just fire the broadcast like this:
public void btnTrigger_onClick(View view) {
Intent i = new Intent(this, AlarmReceiver.class);
sendBroadcast(i);
}
and also nothing happens here.
I have used broadcasts before, but only with registerReceiver, but I do not want to process the broadcast in my Activity now.
Explicit broadcasts — ones where the Intent has the component name (i.e., class) — require a <receiver> element in the manifest in order to work.
I have a broadcast receiver. In which I'm trying to reset the alarms after reboot. I used IntentServices to setAlarms and create notifications. I'm using cursor to retrieve values of alarm timings and description and resetting it in onReceive in Broadcast receiver. I have to use loops to reset all alarms. But IntentService sets the alarm but shows wrong notification. I checked logs it has wrong data. I'll post the code. Please advise. Images are below. Stack Trace 1Stack trace 2
Notification on phone
BroadCastReceiver class
public class Receiver extends BroadcastReceiver {
public static String TAG=BroadcastReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
Log.i(Receiver.class.getSimpleName(),"Boot Completed");
Cursor cursor=context.getContentResolver().query(DatabaseContract.content_URI,null,null,null,null);
if(cursor.getCount()>0)
{
cursor.moveToFirst();
do{
ContentValues contentValues=new ContentValues();
contentValues.put(DatabaseContract.columns._ID,cursor.getInt(0));
contentValues.put(DatabaseContract.columns.description,cursor.getString(1));
contentValues.put(DatabaseContract.columns.isCompleted,cursor.getInt(2));
contentValues.put(DatabaseContract.columns.priority,cursor.getInt(3));
contentValues.put(DatabaseContract.columns.date,cursor.getLong(4));
Log.i(Receiver.class.getSimpleName(),"Content Values: "+contentValues.getAsString(DatabaseContract.columns.description));
AlarmScheduler alarmScheduler=new AlarmScheduler();
alarmScheduler.createAlarm(context,contentValues);
contentValues.clear();
}while ( cursor.moveToNext());
// AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Log.i(TAG,"Alarm reset after boot:" );
cursor.close();
}
/* Intent intent1=new Intent(context, MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);*/
}
}
AlarmScheduler Class
public class AlarmScheduler {
public static String TAG="Scheduler";//AlarmScheduler.class.getSimpleName();
public void createAlarm(Context mContext, ContentValues contentValues){
AlarmManager alarmManager=(AlarmManager) mContext.getSystemService(mContext.ALARM_SERVICE);
//NotificationManager manager=mContext.get
PendingIntent pendingIntent=ReminderAlarmService.getReminderPendingIntent(mContext,contentValues);
Log.i(TAG,"Description: "+contentValues.getAsString(DatabaseContract.columns.description)+" | Date: "+contentValues.getAsLong(DatabaseContract.columns.date));
alarmManager.setExact(AlarmManager.RTC_WAKEUP,contentValues.getAsLong(DatabaseContract.columns.date),pendingIntent);
Calendar calendar=Calendar.getInstance();
calendar.setTimeInMillis(contentValues.getAsLong(DatabaseContract.columns.date));
Log.i(AlarmScheduler.class.getSimpleName(),"Alarm set at"+ calendar.getTime());
}
}
IntentServiceClass
[public class ReminderAlarmService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* #param name Used to name the worker thread, important only for debugging.
*/
public static String TAG="Intent Service";//ReminderAlarmService.class.getSimpleName();
public static String CONTENTVALUES="ContentValues";
int notificationId=001;
public ReminderAlarmService() {
super(TAG);
}
static PendingIntent getReminderPendingIntent(Context context, ContentValues contentValues){
Intent intent=new Intent(context, ReminderAlarmService.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CONTENTVALUES,contentValues);
Log.i(TAG,"Description: "+contentValues.getAsString(DatabaseContract.columns.description));
PendingIntent pendingIntent=PendingIntent.getService(context,0,intent,0);
//
context.startService(intent);
return pendingIntent;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG,"Destroying");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Intent intent1=new Intent(ReminderAlarmService.this, MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent2=PendingIntent.getActivity(ReminderAlarmService.this,0,intent1,0);
ContentValues contentValues2=intent.getParcelableExtra(CONTENTVALUES);
// notificationId=contentValues2.getAsInteger(DatabaseContract.columns._ID);
Log.i(TAG,"Description: "+contentValues2.getAsString(DatabaseContract.columns.description)+" | Date: "+contentValues2.getAsLong(DatabaseContract.columns.date));
// Log.i(TAG,"Description: "+contentValues2.getAsString(DatabaseContract.columns.description));
NotificationCompat.Builder builder=new NotificationCompat.Builder(ReminderAlarmService.this,"none").setSmallIcon(android.support.v4.R.drawable.notification_icon_background).setAutoCancel(true).setContentTitle("Task Update").setContentText(contentValues2.getAsString(DatabaseContract.columns.description)).setContentIntent(pendingIntent2);
NotificationManager manager=(NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);
manager.notify(notificationId,builder.build());
}
}][1]
Fixed it. Below is the change I made. Its in IntentService class. Added a flag into PendingIntent. PendingIntent.FLAG_CANCEL_CURRENT.
static PendingIntent getReminderPendingIntent(Context context, ContentValues contentValues){
Intent intent=new Intent(context, ReminderAlarmService.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(CONTENTVALUES,contentValues);
Log.i(TAG,"Description: "+contentValues.getAsString(DatabaseContract.columns.description));
PendingIntent pendingIntent=PendingIntent.getService(context,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);
//
//context.startService(intent);
return pendingIntent;
}
can anyone help me with a normal alarm clock app that uses TimePicker to set the time ..and also uses intents,etc instead of normal comparisons.This is the code that i've done till now.But this is not working. The 'TimePicker' sets the time and on pressing the 'ToggleButton' a 'TextVew' shows that alarm is on .But when the alarmtime is reached,Alarm Ringing message is not shown.Please someone help me out.
this is the code of main activity
public class FullscreenActivity extends Activity implements OnClickListener {
TimePicker TimePickerForGettingTime;
TextView AlarmSet;
TextView AlarmOnOff;
ToggleButton ConfirmButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
TimePickerForGettingTime= (TimePicker)findViewById(R.id.TimePickerForGettingTime);
ConfirmButton = (ToggleButton) findViewById(R.id.ConfirmButton);
ConfirmButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v)
{ boolean on=((ToggleButton) v).isChecked() ;
AlarmOnOff=(TextView)findViewById(R.id.AlarmOnOff);
if(on)
{
AlarmOnOff.setText("Alarm on");
Calendar cal = Calendar.getInstance();
cal.set(TimePickerForGettingTime.getCurrentHour(),TimePickerForGettingTime.getCurrentMinute(),00);
setAlarm(cal);
}
else
{
AlarmOnOff.setText("Alarm off");
}
}
});
}
private void setAlarm(Calendar targetCal)
{
Intent alarmintent = new Intent(FullscreenActivity.this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(FullscreenActivity.this, 0, alarmintent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, targetCal.getTimeInMillis(), sender);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
this is the onbootreceiver class
public class OnBootReceiver extends BroadcastReceiver {
private static final int PERIOD=10000; // 10sec
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, AlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);
}
}
this is the alarmreceiver class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
NotificationManager manager = (NotificationManager)context.getSystemService(android.content.Context.NOTIFICATION_SERVICE);
Notification noti = new Notification(android.R.drawable.stat_notify_more, "Wake up alarm", System.currentTimeMillis());
noti.setLatestEventInfo(context, "My Alarm", "WAKE UP...!!!", sender);
noti.flags = Notification.FLAG_AUTO_CANCEL;
manager.notify(R.string.app_name, noti);
//intent to call the activity which shows on ringing
Intent myIntent = new Intent(context, FullscreenActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
//display that alarm is ringing
Toast.makeText(context, "Alarm Ringing...!!!", Toast.LENGTH_LONG).show();
}
}
Have you registered the alarm receiver in you manifest ?
You should have this in your manifest.
<application>
.
.
.
<receiver android:name=".AlarmReceiver" android:process=":remote" />
</application>
Also, I am not sure that is the right way to calendar set, but I could be wrong . I do it like this and it works fine for me
Calendar cal = Calendar.getInstance();
cal.set (Calendar.HOUR_OF_DAY, time_picker.getCurrentHour());
cal.set (Calendar.MINUTE, time_picker.getCurrentMinute());