I am using a foreground service in my application I need to stop this service from a button that is present on the notification itself without opening the activity.
My current code
This is my activity from where I am starting the service.
serviceIntent = new Intent(getApplicationContext(),BackgroundService.class);
serviceIntent.putExtra("ip",ipAdd);
serviceIntent.putExtra("token",token);
serviceIntent.putExtra("port",portNo);
serviceIntent.putExtra("resource",resourceId);
serviceIntent.putExtra("userName",username);
startService(serviceIntent);
ClosingBackGroundService.getMainActivityContext(MainActivity.this);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stopService(serviceIntent);
}
});
I am using a class to show the button on the notification and trying to close the activity
public class ClosingBackGroundService extends BroadcastReceiver {
static Context mainActContext;
public static void getMainActivityContext(Context context){
mainActContext = context;
}
#Override
public void onReceive(Context context, Intent intent) {
mainActContext.stopService(MainActivity.serviceIntent);
Log.i("Service","closed");
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(broadcastReceiver, filter);
Intent notificationIntent = new Intent(this,LoginActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
Intent closingIntent = new Intent(this,ClosingBackGroundService.class);
PendingIntent actionIntent = PendingIntent.getBroadcast(this,0,closingIntent,PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this,CHANNEL_ID)
.setOngoing(true)
.setSmallIcon(R.drawable.logo)
.addAction(R.mipmap.ic_launcher,"Close Services",actionIntent)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setContentText("Processes Running In BackGround").build();
ipAdd = intent.getStringExtra("ip");
port = intent.getStringExtra("port");
token = intent.getStringExtra("token");
resourceId = intent.getIntExtra("resource",0);
username = intent.getStringExtra("userName");
runnableForGps.run();
runnableForSendingGpsData.run();
runnableForBluetooth.run();
runnableForsendingBTData.run();
startForeground(1,notification);
return START_STICKY;
}
When I press the button the notification disappears but the process keeps on working.
You don't need to create BroadCast to stop Service. Try this
private static final String ACTION_STOP_LISTEN = "action_stop_listen";
Intent intent = new Intent(this, ClosingBackGroundService.class);
intent.setAction(ACTION_STOP_LISTEN);
PendingIntent actionIntent = PendingIntent.getService(this, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
addAction(R.mipmap.ic_launcher,"Close Services",actionIntent)
In onStartCommand check your Intent action
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && ACTION_STOP_LISTEN.equals(intent.getAction())) {
stopForeground(true);
stopSelf();
return START_NOT_STICKY;
}
// your code
}
Related
I am making an app that reads data being sent via Bluetooth in one activity which then is redirected to a foreground service which sends an intent to another activity where the data will be processed. I know I am missing something in the code for the broadcast receiver on the activity code.
If anyone can give me advice or help me with the data being able to be processed. There are no crashes so far. I am new in coding in android studio and any help would be great!
*** This is the code for the Foreground Service ***
public class ForegroundService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
#Override
public void onCreate(){
super.onCreate();
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//super.onStartCommand(intent, flags, startId);
String input = intent.getStringExtra("inputExtra");
Log.i("Tag", input);
sendData(input);
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent)
{
return null;
}
private void sendData(String input){
Log.i("Tag", "inside sendData");
Intent intent = new Intent();
intent.setAction("com.example.Pillwoah.sendbroadcast");
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.putExtra("inputExtra", input);
sendBroadcast(intent);
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID, "Foreground Service Channel", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
*** This is the code for the activity ***
public class MainActivity5 extends AppCompatActivity {
protected static final String TAG = "TAG";
TextView dataText;
BroadcastReceiver receiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
Log.i(TAG, "data sending");
configureReceiver();
}
class DataBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String message = "Broadcast intent detected " + intent.getAction();
Log.i(TAG, message);
}
}
private void configureReceiver(){
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.Pillwoah.sendbroadcast");
receiver = new DataBroadcastReceiver();
registerReceiver(receiver, filter);
}
}
Need to update TextView of a clock widget every second or every time the minute changes ..
I am calling the service from onReceive of my AppWidgetProvider :
private String action = "clock.beautiful.best.com.mmclock.TheService";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
//UseThis
Log.e("h","R");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main_widget);
// Create a fresh intent
Intent serviceIntent = new Intent(context, TheService.class);
serviceIntent.setAction(action);
context.startService(serviceIntent);
ComponentName componentName = new ComponentName(context, TheService.class);
AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);
}
What should i do to check for update in time and if there is a then update the 'time' TextView..
Service :
public class TheService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.e("Service","created");
}
#Override
public void onDestroy() {
Log.e("Service","Destroy");
}
public void changeYexy (){
RemoteViews remoteViews = new RemoteViews(TheService.this.getPackageName(), R.layout.main_widget);
remoteViews.setTextViewText(R.id.dateTextView,"T");
}
#Override
public void onStart(Intent intent, int startid) {
Log.e("Service","start");
}
}
I don't want users to open the activity again and again to update , is there any way i can check and update the time from service or widget..
Any kind of is really really really appreciated
Instead of Using service you can use AlarmManager to update widget periodically
public class Alarm
{
public static void setAlarm(Context context, int interval)
{
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, yourWidget.class);
intent.setAction("WIDGET_UPDATE");
int[] ids = AppWidgetManager.getInstance(context)
.getAppWidgetIds(new ComponentName(context, yourWidget.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval * 1000, pi);
}
public void cancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
in this way the alram send a broadCast to widget with "WIDGET_UPDATE" as action after interval seconds.
Enable the alarm in onEnable method of your widget:
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
Alarm.setAlarm(context, 1);
}
In the onReceive method of yourWidget update yourWidget and set the alarm for next time
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if ("WIDGET_UPDATE".equals(intent.getAction())) {
int[] appWidgetIds = AppWidgetManager.getInstance(context)
.getAppWidgetIds(new ComponentName(context, yourWidget.class));
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//set alarm for the next time
Alarm.setAlarm(context, 1);
//update your widget here
onUpdate(context, appWidgetManager, appWidgetIds);
}
}
Note : although it is possile to use setRepeating instead of setExact but for me it does not work properly
I have used this cancelAlarm method from another reputable answer on stack, and it isn't getting the job done, and I am out of ideas of why this isn't working.
I have an activity where one button will start an alarm that will go off every given interval. I then have another button that will cancel that alarm. Here are the buttons first:
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setupAlarm(10);
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
cancelAlarm(ALARM_ID);
} catch(Exception e){
Toast.makeText(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT).show();
}
}
});
And here are my setupAlarm and cancelAlarm methods:
private void setupAlarm(int seconds) {
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent i = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, ALARM_ID, i, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar t = Calendar.getInstance();
t.setTimeInMillis(System.currentTimeMillis());
int interval = seconds*1000;
am.setRepeating(AlarmManager.RTC_WAKEUP, t.getTimeInMillis(), interval, pendingIntent);
MainActivity.this.finish();
}
private void cancelAlarm(int alarmId){
Intent i = new Intent(getBaseContext(), AlarmManager.class);
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, alarmId, i, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(sender);
sender.cancel();
}
I remembered to make another alarm manager with the same ID, and call alarmManager.cancel(sender); on the PendingIntent but it doesn't seem to do anything, because my service will start back up anyway.
AlarmReciever class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Context oAppContext = context.getApplicationContext();
if (oAppContext == null) {
oAppContext = context;
}
Intent serviceIntent = new Intent(oAppContext, MyService.class);
oAppContext.startService(serviceIntent);
}
}
MyService class:
public class MyService extends Service implements SensorEventListener{
private PowerManager.WakeLock wakeLock;
Sensor mSensor;
SensorManager mSensorManager;
String toastString = "";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate(){
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
PowerManager mgr = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wakeLock.acquire();
Toast.makeText(this, "onCreate Successful", Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startid) {
Toast.makeText(this, "onStart Successful", Toast.LENGTH_SHORT).show();
return Service.START_STICKY;
}
#Override
public void onSensorChanged(SensorEvent event) {
//record some data from the accelerometer
quit();
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void quit(){
mSensorManager.unregisterListener(MyService.this);
wakeLock.release();
this.stopSelf();
}
}
And I keep on getting the toasts from my MyService class telling me that my onCreate and onStart were successfully instantiated, even after calling my cancelAlarm method.
Use same PendingIntent that you used while creating Alarm. Use AlarmReceiver.class instead of AlarmManager.class in your Intent:
Intent i = new Intent(getBaseContext(), AlarmReceiver.class);
Update cancelAlarm() method as below:
private void cancelAlarm(int alarmId){
Intent i = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(MainActivity.this, alarmId, i, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(sender);
sender.cancel();
}
Hope this will help~
I have NotificationService class extends Service and I launch the service whit method, but I don't know how to stop the current Service, I read some guide and example but with stopService() method I can't stop my service. This is the code of my class, how I can stop?
public class NotificationService extends Service {
private final long TIME_WAKE_UP = 6000;//60 * 60 * 1000;
private long timeStart;
private Esercizio es;
#Override
public void onCreate() {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
Notification mNt = mBuilder.build();
startForeground(2, mNt);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
timeStart = intent.getExtras().getLong("timeStart");
es = (Esercizio) intent.getExtras().get("esercizio");
while(System.currentTimeMillis() < timeStart + TIME_WAKE_UP);
atWork();
stopForeground(true);
stopSelf();
return START_STICKY;
}
private void atWork() {
Intent intent = new Intent(this, TransitionArchive.class);
Bundle bundle = new Bundle();
bundle.putString("notificationService","");
bundle.putString("KEY_EXCERSIZE",es.getNameEx());
intent.putExtras(bundle);
NotificationCompat.Builder mBuilderOffline =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo_app_android)
.setContentTitle(es.getNameEx())
.setContentText("C'รจ un nuovo contenuto per te!")
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
1,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilderOffline.setContentIntent(pendingIntent);
//PendingIntent call the receive class
Notification note = mBuilderOffline.build();
note.defaults |= Notification.DEFAULT_SOUND;
note.defaults |= Notification.DEFAULT_VIBRATE;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, note);
}
public static void startNotificationService(Context mContext, Esercizio es) {
Intent mIntent = new Intent(mContext, NotificationService.class);
mIntent.putExtra("esercizio", es);
mIntent.putExtra("timeStart", System.currentTimeMillis());
startWakefulService(mContext, mIntent);
}
#Override
#Nullable
public IBinder onBind(Intent intent) {
return null;
}
Try like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
timeStart = intent.getExtras().getLong("timeStart");
es = (Esercizio) intent.getExtras().get("esercizio");
while(System.currentTimeMillis() < timeStart + TIME_WAKE_UP);
atWork();
stopForeground(true);
stopSelf();
return START_NOT_STICKY;
}
It may not be the best way, but I used a public static variable as a flag with an IntentService. If the flag is set, perform any necessary cleanup, stop threads, exit loops, and let it flow to stopSelf() and stopForeground() naturally (that you already have).
How to check if a service is running on Android?
I set an alarm and i want to disable the ongoing alarm using notification action button without opening the activity.
I have attached my whole code below.
When user set alarm it call the broadcast receiver and from them i call my ringtone service to start ringtone. and it will fire a notification. in that notification it will have a disable button. i have done all the resource i had found on internet. but
disable button on notification didn't work. where is my fault
onToggled button to start alarm from main activity
public void OnToggleClicked(View view) {
long time;
if (((ToggleButton) view).isChecked()) {
Toast.makeText(MainActivity.this, "ALARM ON", Toast.LENGTH_SHORT).show();
Calendar calendar = Calendar.getInstance();
if (Build.VERSION.SDK_INT >= 23) {
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getMinute());
} else {
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
}
intent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
// setRepeating() lets you specify a precise custom interval--in this case,
// 1 minutes.
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, pendingIntent);
} else {
alarmManager.cancel(pendingIntent);
Toast.makeText(MainActivity.this, "ALARM OFF", Toast.LENGTH_SHORT).show();
}
}
My broadcast receiver class
public class AlarmReceiver extends BroadcastReceiver {
public static Ringtone ringtone;
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm! Wake up! Wake up!", Toast.LENGTH_LONG).show();
// using service class
Intent i = new Intent(context, RingtonePlayingService.class);
context.startService(i);
createNotification(context);
}
public void createNotification(Context context) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setContentTitle("It is prayer time")
.setContentText("Prayer")
.setSmallIcon(R.mipmap.ic_launcher)
.setSubText("Tab to cancel the ringtone")
.setPriority(NotificationCompat.PRIORITY_HIGH);
//To add a dismiss button
Intent dismissIntent = new Intent(context, RingtonePlayingService.class);
dismissIntent.setAction(RingtonePlayingService.ACTION_DISMISS);
PendingIntent pendingIntent = PendingIntent.getService(context,
123, dismissIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action action = new NotificationCompat.Action
(android.R.drawable.ic_lock_idle_alarm, "DISMISS", pendingIntent);
builder.addAction(action);
// end of setting action button to notification
Intent intent1 = new Intent(context, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 123, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(NOTIFICATION_SERVICE);
Notification notification = builder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(123, notification);
}
My ringtoneplaying service class
public class RingtonePlayingService extends Service{
private static final String TAG = RingtonePlayingService.class.getSimpleName();
private static final String URI_BASE = RingtonePlayingService.class.getName() + ".";
public static final String ACTION_DISMISS = URI_BASE + "ACTION_DISMISS";
private Ringtone ringtone;
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG, "onStartCommand");
if(intent == null) {
Log.d(TAG, "The intent is null.");
return START_REDELIVER_INTENT;
}
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null) {
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
ringtone = RingtoneManager.getRingtone(this, alarmUri);
ringtone.play();
String action = intent.getAction();
if(ACTION_DISMISS.equals(action))
dismissRingtone();
return START_NOT_STICKY;
}
public void dismissRingtone() {
Intent i = new Intent(this, RingtonePlayingService.class);
stopService(i);
}
#Override
public void onDestroy() {
ringtone.stop();
}
That was my fault
When i click on disable on notification it again call the receiver class that's why ringtone keeps playing. So i keep some modifying and it works fine.
public class RingtonePlayingService extends Service {
private static final String TAG = RingtonePlayingService.class.getSimpleName();
private static final String URI_BASE = RingtonePlayingService.class.getName() + ".";
public static final String ACTION_DISMISS = URI_BASE + "ACTION_DISMISS";
private Ringtone ringtone;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
if (intent == null) {
Log.d(TAG, "The intent is null.");
return START_REDELIVER_INTENT;
}
String action = intent.getAction();
if (ACTION_DISMISS.equals(action))
dismissRingtone();
else {
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null) {
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
ringtone = RingtoneManager.getRingtone(this, alarmUri);
ringtone.play();
}
return START_NOT_STICKY;
}
public void dismissRingtone() {
// stop the alarm rigntone
Intent i = new Intent(this, RingtonePlayingService.class);
stopService(i);
// also dismiss the alarm to ring again or trigger again
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
aManager.cancel(pendingIntent);
// Canceling the current notification
NotificationManager notificationManager =
(NotificationManager)getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
notificationManager.cancel(321);
}
#Override
public void onDestroy() {
ringtone.stop();
}}