I have a service which captures the location of a user and updates database using retrofit. I want to stop the service automatically at 8 pm everyday if its running and also update the database that the user has punched out at 8 pm.
I want the service to start the manually but want the service to stop automatically if it is not stopped manually.
Here is my service class
public class LiveLocationService extends Service {
private static final String TAG = LiveLocationService.class.getSimpleName();
Retrofit retrofitClient;
CompositeDisposable compositeDisposable = new CompositeDisposable();
MyService myService;
String empCode, year, month, date;
FusedLocationProviderClient client;
LocationCallback locationCallback;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
retrofitClient = RetrofitClient.getInstance();
myService = retrofitClient.create(MyService.class);
empCode = intent.getStringExtra("empCode");
year = intent.getStringExtra("year");
month = intent.getStringExtra("month");
date = intent.getStringExtra("date");
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onCreate() {
super.onCreate();
if (isOnline()) {
buildNotification();
requestLocationUpdates();
} else {
Log.e("MSER", "Please connect to the internet.");
}
}
private void buildNotification() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = "com.deepankmehta.managementservices";
String channelName = "My Background Service";
NotificationChannel chan = null;
chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.mser)
.setContentTitle("xxxx")
.setContentText("xxxx is tracking your location.")
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentIntent(intent)
.build();
startForeground(2, notification);
} else {
PendingIntent broadcastIntent = PendingIntent.getActivity(
this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
// Create the persistent notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText("xxxx is tracking your location.")
.setOngoing(true)
.setContentIntent(broadcastIntent)
.setSmallIcon(R.drawable.mser);
startForeground(1, builder.build());
}
}
private void requestLocationUpdates() {
if (isOnline()) {
LocationRequest request = new LocationRequest();
request.setInterval(10000);
request.setFastestInterval(5000);
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
client = LocationServices.getFusedLocationProviderClient(this);
int permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (permission == PackageManager.PERMISSION_GRANTED) {
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
Location location = locationResult.getLastLocation();
if (location != null) {
Log.d(TAG, "location update " + location);
double lat = location.getLatitude();
double lon = location.getLongitude();
final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
compositeDisposable.add(myService.userLocation(empCode, year, month, date, time, lat, lon)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer< String >() {
#Override
public void accept(String s) throws Exception {
Log.e("data", s);
if (s.equals("\"done\"")) {
Log.e("status", "location punched");
}
}
}));
} else {
Log.d("MSER", "location update, no location found. ");
}
}
};
client.requestLocationUpdates(request, locationCallback, null);
} else {
Log.e("MSER", "Please enable location.");
}
} else {
Log.e("MSER", "Please connect to the internet.");
}
}
#Override
public void onDestroy() {
super.onDestroy();
client.removeLocationUpdates(locationCallback);
stopForeground(true);
stopSelf();
}
protected boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
}
Here is home activity class start service and stop service methods. These methods are called when the user clicks on punch in and punch out buttons respectively.
private void startTrackerService() {
final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
final String year = date.substring(0, 4);
final String month = date.substring(5, 7);
final String dateToday = date.substring(8, 10);
Intent intent = new Intent(this, LiveLocationService.class);
intent.putExtra("empCode", empCode);
intent.putExtra("year", year);
intent.putExtra("month", month);
intent.putExtra("date", dateToday);
startService(intent);
}
private void stopTrackerService() {
stopService(new Intent(this, LiveLocationService.class));
}
You can use AlarmManager to schedule this kind of the task,
Register AlaramManger at specific time and check whether service is running, if it is running then stop service.
Here is the example of registering AlaramManager at specific time
AlarmManager alarmManager = (AlarmManager) getActivityContext()
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivityContext(), AutoStopReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivityContext(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
stopServieTime, pendingIntent);
Here is the Receiver Class,
public class AutoStopReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//TODO Stop service from here
}
Register receiver in AndroidMenifest.xml
<receiver android:name=".AutoStopReceiver" />
Related
i am facing issue to start a service from fragment on a button click.
below is overview of Service class
public class FtpServiceDownload1 extends Service {
IBinder mBinder = new LocalBinder();
static String LOG_TAG = "Background Service 001";
private Handler customHandler = new Handler();
private Handler checkServiceHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
private long startTime = 0L;
public boolean isFtpConnected(){
if(ftpHelperObj!=null){
return ftpHelperObj.ftp.isConnected();
}
return false;
}
public FtpHelperObject ftpHelperObj;
//#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.e(LOG_TAG,"binded called");
return mBinder;
}
public class LocalBinder extends Binder {
public FtpServiceDownload1 getServerInstance() {
return FtpServiceDownload1.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TO DO WORK
return(START_NOT_STICKY);
}
String NOTIFICATION_CHANNEL_ID = "com.form.lasertrac.ftpquery";
String channelName = "My Background Service";
static Notification notification = null;
static NotificationChannel notificationChannel = null;
static NotificationManager notificationManager = null;
static NotificationCompat.Builder notificationBuilder = null;
int id = 1;
private void startMyOwnForeground(){
notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert notificationManager != null;
notificationManager.createNotificationChannel(notificationChannel);
notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher_lasertrac)
.setContentTitle("FTP Query in background.")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(id, notification);
}
void notifyNotification(String msg){
notificationBuilder.setContentText("FTP Check "+msg);
notificationBuilder.setContentTitle("FTP Check Service ");
Date d = Calendar.getInstance().getTime();
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(FunctionsHelper.onlyForTimeFormatterView.format(d)+" "+msg));
Notification notification = notificationBuilder.getNotification();
notification.flags = Notification.FLAG_ONGOING_EVENT;
notificationManager.notify(id, notification);
}
}
and below code in my fragment to start service
btn_service_load_data.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent mIntent2 = new Intent(getContext(), FtpServiceDownload1.class);
getContext().bindService(mIntent2, mConnectionFtpQuery, getContext().BIND_AUTO_CREATE);
getContext().startService(mIntent2);
}
});
FtpServiceDownload1 mServiceFtpQueryService ;
boolean mBoundedFtpQuery ;
ServiceConnection mConnectionFtpQuery = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(getContext(), "Ftp Query Service is disconnected", Toast.LENGTH_LONG).show();
mBoundedFtpQuery = false;
mServiceFtpQueryService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(getContext(), "Ftp Query service started", Toast.LENGTH_LONG).show();
mBoundedFtpQuery = true;
FtpServiceDownload1.LocalBinder mLocalBinder = (FtpServiceDownload1.LocalBinder) service;
mServiceFtpQueryService = mLocalBinder.getServerInstance();
}
};
my purpose is to start some service for particular work and stop it after work done.
when i click to start service, my application hangs and doesn't respond, if i call this service from my MainActivity class like below, it works
#Override
protected void onStart() {
super.onStart();
Intent mIntent2 = new Intent(this, FtpServiceDownload1.class);
bindService(mIntent2, mConnectionFtpQuery, BIND_AUTO_CREATE);
startService(mIntent2);
}
I am trying to call BroadcastReceiver from intent service but it is never called:
public class IntentServiceTest extends IntentService {
public IntentServiceTest() {
super("IntentServiceTest");
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(#Nullable Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
while (true) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Brodcast brodcast;
brodcast = new Brodcast();
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(brodcast, intentFilter);
}
}
}
Here is my BroadcastReceiver:
public class Brodcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "BroadcastReceiver", Toast.LENGTH_SHORT).show();
String NOTIFICATION_CHANNEL_ID = "100";
String channelName = "My back";
NotificationChannel channel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
channel.setLightColor(Color.BLUE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(channel);
}
BluetoothAdapter bluetoothAdapter;
ArrayList<String> arrayList;
BluetoothDevice device;
NotificationManagerCompat notificationManagerCompat;
notificationManagerCompat = NotificationManagerCompat.from(context);
arrayList = new ArrayList<>();
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.startDiscovery();
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (!arrayList.contains(device.getName())) {
arrayList.add(device.getName());
if (arrayList.size() >= 0) {
Toast.makeText(context, "s", Toast.LENGTH_SHORT).show();
}
}
Intent i = new Intent(context, MainActivity3.class);
i.putExtra("noti", NOTIFICATION_CHANNEL_ID);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder n = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
Notification notification = n.setOngoing(true)
.setSmallIcon(R.drawable.ss)
.setContentTitle(arrayList.size() + device.getName())
.addAction(R.drawable.as, "Action", pendingIntent)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("App running"))
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
notificationManagerCompat.notify(1 , notification);
}
}
}
I need to call broadcast every 20 min; can anyone help me?
I need a service to make a notification whenever the user is in a moving car.
I use ActivityRecognition to find out when the user is in a car.the issue is I need my service to run even when the app is destroyed or removed by the user.
I tried running the service on a different process but after a few minutes the service stops working.I also tried using foreground service but I had the same issue with that to.
this is my service class.
public class SpeedCheckerService extends Service {
private final String CHANNEL_ID = "my_channel";
private static SpeedCheckerService speedCheckerService;
private ActivityRecognitionClient mActivityRecognitionClient;
private boolean started = false;
Date lastNotification;
CountDownTimer countDownTimer;
Intent intent;
#Override
public void onCreate() {
createNotificationChannel();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
this.intent=intent;
countDownTimer = new CountDownTimer(99999999,1000 * 60 * 1) {
#Override
public void onTick(long l) {
recognizeActivity();
}
#Override
public void onFinish() {
countDownTimer.start();
}
}.start();
return START_STICKY;
}
String detectedActivitiesToJson(ArrayList<DetectedActivity> detectedActivitiesList) {
Type type = new TypeToken<ArrayList<DetectedActivity>>() {}.getType();
System.out.println(detectedActivitiesList.toString());
if ((detectedActivitiesList.size()>=1)&&(detectedActivitiesList.get(0).getType() == DetectedActivity.STILL) && (detectedActivitiesList.get(0).getConfidence()) >= 60){
if(lastNotification!=null){
Calendar calendar = Calendar.getInstance();
calendar.setTime(lastNotification);
calendar.add(Calendar.MINUTE,5);
Date newDate = calendar.getTime();
calendar.clear();
System.out.println(lastNotification.toString());
System.out.println(newDate.toString());
if(newDate.after(calendar.getTime()) == true)
return null;
}
speedCheckerService.makeNotification();
lastNotification = Calendar.getInstance().getTime();
}
return new Gson().toJson(detectedActivitiesList, type);
}
public void makeNotification() {
createNotificationChannel();
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("title")
.setContentText("text")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.mapbox_logo_icon)
.setColor(Color.parseColor("#00ff00"))
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(70, builder.build());
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "guardian";
String description = "alerting user";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
public void recognizeActivity() {
if((mActivityRecognitionClient==null)&&(!started))
{
mActivityRecognitionClient = new ActivityRecognitionClient(this);
mActivityRecognitionClient.requestActivityUpdates(0, PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
started = true;
}
speedCheckerService =this;
if(ActivityRecognitionResult.hasResult(intent))
{
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
ArrayList<DetectedActivity> detectedActivities = (ArrayList) result.getProbableActivities();
detectedActivitiesToJson(detectedActivities);
}
}
}
I would greatly appreciate if you can help me with my problem
Use foreground service instead of normal service and do the below changes
public class SampleService extends Service {
private NotificationManager mNotificationManager;
/**
* The identifier for the notification displayed for the foreground service.
*/
private static final int NOTIFICATION_ID = 1231234;
static void startService(Context context, String message) {
Intent startIntent = new Intent(context, SampleService.class);
startIntent.putExtra("inputExtra", message);
ContextCompat.startForegroundService(context, startIntent);
}
static void stopService(Context context) {
Intent stopIntent = new Intent(context, SampleService.class);
context.stopService(stopIntent);
}
private void createNotificationChannel() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
CharSequence name = "Sample Notification";
// Create the channel for the notification
NotificationChannel mChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name,
NotificationManager.IMPORTANCE_DEFAULT);
mChannel.setSound(null, null);
// Set the Notification Channel for the Notification Manager.
notificationManager.createNotificationChannel(mChannel);
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("Service", "onCreate");
createNotificationChannel();
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service", "onStartCommand");
startForeground(NOTIFICATION_ID, getNotification(message);
**// This is important, When your service got killed it will try to restart //the service. But some android vendor phones are restricted this autostart**
return START_REDELIVER_INTENT;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Service", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("Service", "onTaskRemoved");
super.onTaskRemoved(rootIntent);
}
private Notification getNotification(String contentMessage) {
String title = getString(R.string.notification_title,
DateFormat.getDateTimeInstance().format(new Date()));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
NOTIFICATION_CHANNEL_ID).setContentTitle(title).setContentText(contentMessage)
.setSmallIcon(R.drawable.notification)
.setOngoing(true)
.setPriority(Notification.PRIORITY_MAX)
.setTicker(contentMessage)
.setAutoCancel(false)
.setWhen(System.currentTimeMillis());
return builder.build();
}
/**
* Returns true if this is a foreground service.
*
* #param context The {#link Context}.
*/
public boolean serviceIsRunningInForeground(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
Integer.MAX_VALUE)) {
if (getClass().getName().equals(service.service.getClassName())){
if (service.foreground){
return true;
}
}
}
return false;
}
}
You should use Foreground Service if you want service running even your app is in background or closed
https://androidwave.com/foreground-service-android-example/
I've created a service which consult notes if they are in recicle bin, it have to run once a day but with handler I think it will drain too much battery, So I need you help How can I do a task once a day without drain battery or other thing that's not a handler ?
When the app is launched the NotesApplication is created and start the NotesService class, it should be executing all day but it will drain battery, so I need to execute once a day
NotesApplication
public class NotesApplication extends Application {
String TAG = "NotesApplication";
Intent intent;
#Override
public void onCreate() {
// TODO: Implement this method
super.onCreate();
Log.d(TAG, "Application created");
intent = new Intent(getApplicationContext(), NotesService.class);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
Log.d(TAG, "Foreground service started");
getApplicationContext().startForegroundService(intent);
}else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O){
Log.d(TAG, "Service started");
getApplicationContext().startService(intent);
}
}
Notes Service
public class NotesService extends Service {
ArrayList<Notes> listNotas;
String TAG = "NotesService";
SQLiteHelperConnection conn;
#Override
public void onCreate()
{
// TODO: Implement this method
super.onCreate();
Log.d(TAG, "Notes service created");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
final NotificationManager mNotific= (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence name = "Axco";
String description = "Service";
int importance = NotificationManager.IMPORTANCE_MIN;
final String ChannelID="Service Channel";
NotificationChannel mChannel = new NotificationChannel(ChannelID, name, importance);
mChannel.setDescription(description);
mChannel.setLightColor(ThemeClass.getColor());
mChannel.canShowBadge();
mChannel.setShowBadge(true);
mNotific.createNotificationChannel(mChannel);
final int code = 101;
String body= "Service Running";
Notification notification = new Notification.Builder(this, ChannelID)
.setContentTitle(getPackageName())
.setContentText(body)
.setBadgeIconType(R.drawable.ic_launcher)
.setNumber(1)
.setSmallIcon(R.drawable.ic_launcher)
.setAutoCancel(true)
.build();
startForeground(code, notification);
}
conn = new SQLiteHelperConnection(this, "db_notas.db", null, 1);
listNotas = new ArrayList<Notes>();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// TODO: Implement this method
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
final NotificationManager mNotific= (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence name = "Axco";
String description = "Service";
int importance = NotificationManager.IMPORTANCE_MIN;
final String ChannelID="Service Channel";
NotificationChannel mChannel = new NotificationChannel(ChannelID, name, importance);
mChannel.setDescription(description);
mChannel.setLightColor(ThemeClass.getColor());
mChannel.canShowBadge();
mChannel.setShowBadge(true);
mNotific.createNotificationChannel(mChannel);
final int code = 101;
String body= "Service Running";
Notification notification = new Notification.Builder(this, ChannelID)
.setContentTitle(getPackageName())
.setContentText(body)
.setBadgeIconType(R.drawable.ic_launcher)
.setNumber(1)
.setSmallIcon(R.drawable.ic_launcher)
.setAutoCancel(true)
.build();
startForeground(code, notification);
}
final Handler handler = new Handler();
Runnable runnable = new Runnable(){
#Override
public void run()
{
// TODO: Implement this method
Log.d(TAG, "Service running");
listNotas.clear();
consult();
check();
handler.postDelayed(this, 15000);
}
};
handler.post(runnable);
return Service.START_STICKY;
}
private void consult(){
Log.d(TAG, "Consulting...");
SQLiteDatabase db = conn.getReadableDatabase();
Notes notas = null;
Cursor cursor = db.rawQuery("SELECT * FROM "+Utilities.TABLA_NOTA, null);
while (cursor.moveToNext()) {
notas = new Notes();
notas.setId(cursor.getString(0));
notas.setLastModified(cursor.getString(5));
notas.setLastModifiedDate(cursor.getString(7));
boolean a = Boolean.valueOf(cursor.getString(4));
if(a){
listNotas.add(notas);
}
}
}
private void check(){
//Do something
}
private void deleteNote(int position){
SQLiteDatabase db = conn.getWritableDatabase();
String[] parametros = {listNotas.get(position).getId()};
db.delete(Utilities.TABLA_NOTA, Utilities.ID+"=?", parametros);
listNotas.remove(position);
}
#Override
public IBinder onBind(Intent p1){
// TODO: Implement this method
return null;
}
Using Alarm Manager is efficient.
See implementation
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i= new Intent(context, AlarmManagerBroadcastReceiver.class);
//intent.putExtra(something you want to put);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// check if it is more than 11 am. if so set alarm for next day
if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY)) {
calendar.add(Calendar.DAY_OF_YEAR, 1);
}
// everyday at 11 am
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pi);
// alarm set
Finally create a broadcast receiver to do the work you want.
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();
}}