Android IntentService cannot start notification - java

here is my full code
Start notification work well in Service, but when i change service to IntentService, the notification doesn't show, here is my service:
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
Context ctx;
String channelId;
#Override
protected void onHandleIntent(Intent intent) {
ctx = getApplicationContext();
channelId = getPackageName() + " Channel";
createNotificationChannel();
startForeground(1, getNotification());
}
Notification getNotification() {
return new NotificationCompat.Builder(ctx, channelId)
.setContentTitle("Title")
.setContentText("Content")
.setSmallIcon(R.drawable.ic_android_black_24dp)
.build();
}
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String name = channelId + " Name";
String description = channelId + " Desc";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(channelId, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
}
I start service with following code:
startService(new Intent(this, MyIntentService.class))

I find the solution
IntentService cannot use startforeground since IntentService will stop after onHandleIntent, it cannot long-time foreground notification(see StartForeground for IntentService)
If I wanna use startForeground, use Service instead IntentSerivce
If I wanna use notification in IntentService, use NotificationManager#notify, see following code:
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
Context ctx;
String channelId;
#Override
protected void onHandleIntent(Intent intent) {
initNotification();
}
private void initNotification() {
ctx = getApplicationContext();
channelId = getPackageName() + " Channel";
createNotificationChannel();
// startForeground(1, getNotification());
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(1, getNotification());
}
Notification getNotification() {
return new NotificationCompat.Builder(ctx, channelId)
.setContentTitle("Title")
.setContentText("Content")
.setSmallIcon(R.drawable.ic_android_black_24dp)
.build();
}
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String name = channelId + " Name";
String description = channelId + " Desc";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(channelId, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
}

Related

Android 13 New notification appears after old one notification clear

Android 13 New notification appears after old one notification clear. When first notification show then new notification received on onMessageReceived method but it will display if i have old notifiction cleared form notification bar. otherwise it will not showing on notification bar.
My FirebaseMessageingService class as below
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
sendNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use WorkManager.
//scheduleJob();
} else {
// Handle message within 10 seconds
handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
#Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
sendRegistrationToServer(token);
}
private void handleNow() {
Log.d(TAG, "Short lived task is done.");
}
private void sendRegistrationToServer(String token) {
// TODO: Implement this method to send token to your app server.
}
private void sendNotification(String title,String messageBody) {
int uniqueCode=Prefs.getUniqueCode(getApplicationContext());
if(uniqueCode==1000){
uniqueCode=0;
}
Log.d("uniqueCode",uniqueCode+"");
Intent intent
= new Intent(this, LoginActivity.class);
// Assign channel ID
String channel_id = "Default";
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent
= PendingIntent.getActivity(
this, uniqueCode, intent,
PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
Prefs.setUniqueCode(getApplicationContext(),uniqueCode+1);
NotificationCompat.Builder builder
= new NotificationCompat
.Builder(getApplicationContext(),
channel_id)
.setSmallIcon(R.drawable.applogo)
.setAutoCancel(true)
.setVibrate(new long[]{1000, 1000, 1000,
1000, 1000})
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent);
builder = builder.setContentTitle(title)
.setContentText(messageBody)
.setSmallIcon(R.drawable.applogo)
.setStyle(new NotificationCompat.BigTextStyle().bigText(messageBody));
NotificationManager notificationManager
= (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel
= new NotificationChannel(
channel_id, "Default channel",
NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(
notificationChannel);
}
notificationManager.notify(0, builder.build());
}
}

Scheduling Notification in Android Studio not working, Alarmanager not working

I tried to schedule a notification, but when i run the app it doesn't show up after the 3s delay i set.
I followed this tutorial but it didn't work https://betterprogramming.pub/scheduled-notifications-in-android-2055356fb4f5.
public class NotificationsService {
private final Activity activity;
final int requestCode = 1;
#RequiresApi(api = Build.VERSION_CODES.S)
public NotificationsService(Activity activity)
{
this.activity = activity;
scheduleAlarm();
}
#RequiresApi(api = Build.VERSION_CODES.S)
public void scheduleAlarm()
{
Intent intent = new Intent(activity,AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(
activity,
requestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
AlarmManager manager = (AlarmManager) activity.getSystemService(ALARM_SERVICE);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+3000,pi);
Log.d("xxx","scheduled alarm");
}
public static class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
Log.d("xxx","creating notification");
String CHANNEL_ID = "Channel1";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.fish)
.setContentTitle("Dont forget to clean your fish tank.")
.setContentText("One week as passed, it is time for you to replace at least 25% of the water in the aquarium.")
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "My Fishy";// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
notificationManager.createNotificationChannel(mChannel);
notificationManager.notify(1,notificationBuilder.build());
}
}
}
}
`
I expect the notification to show up after 3s.

android service always running and notify user when needed

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/

How Change Service running notification title,image, ande description?

I want to change my Notification image, title, and description made in the service class given below.
if anyone knows how can I change the red border text title and desc so give your suggestions.
I want to change from service class are given below and also want to stick to this notification.
any idea about it?
My ServiceClass
public class NotificationService extends Service {
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
#RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground()
{
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel 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);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Thanks in advance.

Running an Alarm Service once a day on Oreo

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.

Categories

Resources