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.
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);
}
}
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/
Here is my code
FloatingCircle is the service started by MainActivity.class
I want to call method Visibility() when i click on Dismiss button in notification
public class FloatingCircle extends Service {
public void onCreate () {
super.onCreate();
initializeView();
getScreenSize();
showFloat();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = "channel-id";
String channelName = "Channel Name";
int importance = NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= 26) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
notificationManager.createNotificationChannel(mChannel);
}
Intent intent = new Intent(getApplicationContext(), FloatingCircle.class **// What should be here could you suggest me**);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pIntent = PendingIntent.getService(this, 0, intent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.mipmap.ic_launcher)//R.mipmap.ic_launcher
.setContentTitle("Bubble Life")
.setContentText("Touch to On/Off")
.addAction(R.drawable.ic_action_name,
"Dismiss", pIntent)// Here Dismiss is Button shown in notification
.setDefaults(NotificationCompat.DEFAULT_ALL);
notificationManager.notify(0, mBuilder.build());
}
}
This method must be invoked when Dismiss Button is clicked
public void Visibility(()
{
//some code here
windowManager.removeViewImmediate(smallCircle);
Log.d("lol","Done Killing");
}
public void killbubble()
{
Visibility();
selfstop();
}
I have tried one thing that i have created another service and invoked Floatingclass method....
public class MethodCaller extends Service {
FloatingCircle floatingCircle=new FloatingCircle();
#Override
public void onCreate() {
super.onCreate();
Log.d("lol","yeah");
//Toast.makeText(getApplicationContext(),"lol",Toast.LENGTH_LONG).show();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
floatingCircle.killbubble();
stopSelf();
return flags;
}
}
I have succeed in it but this is giving me an error......
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void android.view.WindowManager.removeViewImmediate(android.view.View)' on a null object reference
at com.anam.floatimage.model.FloatingCircle.Visibility(FloatingCircle.java:547)
at com.anam.floatimage.model.FloatingCircle.killbubble(FloatingCircle.java:777)
at com.anam.floatimage.MethodCaller.onStartCommand(MethodCaller.java:36)
I have an arrayList in the MainActivity, and I'm using alarmManager to show notifications when the app is closed. I don't know how I can use that arraylist in the BroadcastReceiver "inside onReceive() method" and get data from that arraylist to show it in the Notifications. I also want to be able to remove the element from the arraylist that has already been shown in the notification.
anyway this my code, I hope you can help me !
-MainActivity :
NotificationManager mNotificationManager;
int NOTIFICATION_ID = 0;
private static final String ACTION_NOTIFY = "com.example.android.standup.ACTION_NOTIFY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent notifyIntent = new Intent(ACTION_NOTIFY);
final PendingIntent notifyPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
final AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
ToggleButton toggleButton = findViewById(R.id.alarmToggle);
toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
long triggerTime = SystemClock.elapsedRealtime()+10000;
long repeatInterval = 180000;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerTime, repeatInterval, notifyPendingIntent);
}else {
mNotificationManager.cancelAll();
alarmManager.cancel(notifyPendingIntent);
}
}
});
}
AlarmReceiver Class :
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent contentIntent = new Intent(context, MainActivity.class);
PendingIntent contentPendingIntent = PendingIntent.getActivity
(context, createID(), contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("Hello")
.setContentText("Notification Text")
.setContentIntent(contentPendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
notificationManager.notify(createID(), builder.build());
}
public int createID(){
Date now = new Date();
int id = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.US).format(now));
return id;
}
}
Thank you !
I created a method to send a notification to the user named sendNotification () using NotificationCompat.Builder and NotificationManager.
I need this notification to be posted at a fixed interval of 24 hours or even at a specific time, for example every day at 07:00 AM, which in this case would result in the same 24 hours, which may be adjusted by the user in the future.
It seems to me that with the public class AlarmManager it is possible to perform this procedure, but I am not sure if I have to create a service or if it would be the service itself.
How could this notification be done within this 24-hour ?
public void setLocalNotification(){
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = new Intent(this, LocalNotificationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 99, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Log.d("TAG ","LocalNotification Start");
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + AlarmManager.INTERVAL_DAY, AlarmManager.INTERVAL_DAY, pendingIntent);
}
public class LocalNotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TUS-NOTAS ", "LocalNotification Receiver");
Intent service1 = new Intent(context, ShowNotificationService.class);
context.startService(service1);
}
}
public class ShowNotificationService extends IntentService {
private static final int NOTIFICATION_ID = 1;
private PendingIntent pendingIntent;
private NotificationManager notificationManager;
private final static String TAG = "ShowNotification";
public ShowNotificationService()
{
super("ServiceNotification");
}
public ShowNotificationService(String name) {
super(name);
}
#Override
public void onCreate() {
super.onCreate();
Context context = this.getApplicationContext();
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, SplashActivity.class);
pendingIntent = PendingIntent.getActivity(context,99, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle(getResources().getString(R.string.app_name));
builder.setVibrate(new long[] { 200, 200});
builder.setSound(uri);
if (Global.getStringKey(getApplicationContext(), Definitions.LANGUAGE_VALUE).equals("en"))
{
builder.setStyle(new NotificationCompat.BigTextStyle().bigText("We miss you!"));
builder.setContentText("You have not added any notes recently.");
}else if (Global.getStringKey(getApplicationContext(),Definitions.LANGUAGE_VALUE).equals("es"))
{
builder.setStyle(new NotificationCompat.BigTextStyle().bigText("Te extrañamos!"));
builder.setContentText("No has agregado notas recientemente.");
}
builder.setAutoCancel(true);
builder.setSmallIcon(R.drawable.ic_logo_app);
builder.setContentIntent(pendingIntent);
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
Log.d("TUS-NOTAS"," LocalNotification Service");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
protected void onHandleIntent(Intent intent) {
}
}
0 0 7 1/1 * ? *
This is a cron statement made from http://www.cronmaker.com/. You can use this in a cron job that executes everyday at 7 am.