Time Sensitive Notifications - java

I am trying to build a simple app that sends notifications to the device but only on a specific day/time. I have been able to get the notification part to work but cant seem to get the day & time problem solved. Any ideas?
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class NotificationsActivity extends Activity {
int notificationID = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onClick(View view) {
displayNotification();
}
protected void displayNotification()
{
Intent i = new Intent(this, NotificationView.class);
i.putExtra("notificationID", notificationID);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, i, 0);
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Notification notif = new Notification(
R.drawable.ic_launcher,
"Reminder: Meeting starts in 5 minutes",
System.currentTimeMillis());
CharSequence from = "System Alarm";
CharSequence message = "Meeting with customer at 3pm...";
notif.setLatestEventInfo(this, from, message, pendingIntent);
notif.vibrate = new long[] { 100, 250, 100, 500};
nm.notify(notificationID, notif);
}
}

You need to use an AlarmManager to schedule these events. Then, from the callbacks, you show the notifications.
See for example Creating a Notification at a particular time through Alarm Manager
Be careful, as AlarManager will be cleared when the device reboots (you may need to re-register then on boot completed if necessary).

See this link Notification in Android Using AlarmManager, BoradCastReceiver & Services
It may be help you.

Related

Daily Notification in Android not working

I wanted my Application to send notification everyday to the user, following this link and doing everything as described. The app doesn't send notifications. The buildLocalNotification function is being triggered every 60 seconds, but no Notification is displayed. I kept an Interval of 2000 ms but android changed it to 60 Seconds.
Logcat Message: Suspiciously short interval 2000 millis; expanding to 60 seconds Every 60 seconds the notification function is triggered.
This is my
NotfBroadcastReceiver.class
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import androidx.core.app.NotificationCompat;
#SuppressWarnings("deprecation")
public class NotfBroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Get notification manager to manage/send notifications
//Intent to invoke app when click on notification.
//In this sample, we want to start/launch this sample app when user clicks on notification
Intent intentToRepeat = new Intent(context, SplashScreen.class);
//set flag to restart/relaunch the app
intentToRepeat.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//Pending intent to handle launch of Activity in intent above
PendingIntent pendingIntent =
PendingIntent.getActivity(context, NotificationHelper.ALARM_TYPE_ELAPSED, intentToRepeat, PendingIntent.FLAG_UPDATE_CURRENT);
//Build notification
Notification repeatedNotification = buildLocalNotification(context, pendingIntent).build();
//Send local notification
NotificationHelper.getNotificationManager(context).notify(NotificationHelper.ALARM_TYPE_ELAPSED, repeatedNotification);
}
public NotificationCompat.Builder buildLocalNotification(Context context, PendingIntent pendingIntent) {
NotificationCompat.Builder builder =
(NotificationCompat.Builder) new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setSmallIcon(android.R.drawable.arrow_up_float)
.setContentTitle("Workout Reminder")
.setAutoCancel(true);
Log.d("DEBUG", "buildLocalNotification: "+"Notification");
return builder;
}
This is my
AlarmBootReceiver.class
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AlarmBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
//only enabling one type of notifications for demo purposes
NotificationHelper.scheduleRepeatingElapsedNotification(context);
}
}
}
This is the code that turn notification on and off:
swnotf.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
{
if(b)
{
Log.d("DEBUG", "onCheckedChanged: "+ "ON");
CommonFunctions.setSwitchState(getContext(),"ON");
NotificationHelper.scheduleRepeatingElapsedNotification(getContext());
NotificationHelper.enableBootReceiver(getContext());
}
else
{
Log.d("DEBUG", "onCheckedChanged: "+"OFF");
CommonFunctions.setSwitchState(getContext(),"OFF");
NotificationHelper.cancelAlarmElapsed();
NotificationHelper.disableBootReceiver(getContext());
}
}
});
Please I have already spent THREE days trying other solutions and fixing this. I don't want to spend more time on this. Any help would be Appreciated.
Thank you.

Perform a task at a specific time

I am new to Android Studio. I have 0 Experience with Java and was still successful to send SMS using my app.
How to Send that SMS at a specific time. E.g; at 5 o'clock.
I have tried com.google.android.gms.gcm.ACTION_TASK_READY, etc but unable to get the permission to send SMS in my other task name MyTask.java
The code is used in mainactivity.java is
package com.example.ssss;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.telephony.SmsManager;
import com.google.android.gms.gcm.GcmNetworkManager;
import com.google.android.gms.gcm.PeriodicTask;
public class MainActivity extends AppCompatActivity {
int MY_PERMISSIONS_REQUEST_SEND_SMS = 1;
String SENT = "SMS_SEND";
String DELIVERED = "SMS_DELIVERED";
PendingIntent sentPI, deliveredPI;
BroadcastReceiver smsSentReceiver, smsDeliveredReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GcmNetworkManager networkManager=GcmNetworkManager.getInstance(this);
String s1 = "MY MSG";
String TellNO = "THE NUMBER";
sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
else
{
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(TellNO, null, s1, sentPI, deliveredPI);
}
}
}
Thanks
Use alarmmanager to schedual a call to a method which fetch no. from your database and send your desired message to that number.
From android docs:
AlarmManager:This class provides access to the system alarm services. These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.

Continue service even when app is cleared from recent apps or closed on Red MI Device

I am running a telemetry service in my app. This service is checking for changes in WiFi environment once a second and if changes are detected it notifies a remote db. I need this service to continue running even if the app is swiped from recent apps or closed.
I followed Continue Service even if application is cleared from Recent app and it seems to work on many devices except for Xiaomi. I've tried many things advised for this device:
enable auto-start.
disable battery optimization for that app.
Tried using a broadcast receiver to start the service
Tried using timer thread and scheduleExecutorservice instead of runnable. didn't make a difference.
This is my latest sample code :
package com.example.csi1;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;
public class MainService extends Service {
public Context context = this;
public Handler handler = null;
public static Runnable runnable = null;
public static int count = 0;
public int restart = 0;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Toast.makeText(this, "MainService onStartCommand", Toast.LENGTH_LONG).show();
Bundle extras = intent.getExtras();
count = 0;
handler = new Handler();
runnable = new Runnable(){
public void run() {
count = count+1;
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo;
wifiInfo = wifiManager.getConnectionInfo();
if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
String ssid = wifiInfo.getSSID();
Log.i("Service", "SSID:"+ssid);
Toast toast = Toast.makeText(context, "Service iter " + String.valueOf(count)+ " " + ssid, Toast.LENGTH_LONG );
toast.setGravity(Gravity.TOP|Gravity.RIGHT, 0, 0);
toast.show();
}
handler.postDelayed(runnable, 1000);
}
};
handler.postDelayed(runnable, 3000);
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Toast.makeText(this, "onTaskRemoved", Toast.LENGTH_LONG).show();
if (restart == 0) {
PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MainService.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
restart=1;
Toast.makeText(this, "Service restarted", Toast.LENGTH_LONG).show();
}
}
#Override
public void onDestroy(){
Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
if (restart == 0) {
PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MainService.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
restart=1;
Toast.makeText(this, "Service restarted", Toast.LENGTH_LONG).show();
}
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
it runs fine on Samsung device and google nexus emulator, but whenever i run it on Red mi and swipe the app from recent apps,app dies and service with it. Is there a solution for Red mi devices or this is some well known limitation ?
Xiaomi's MIUI and a couple of others are very aggressive on removing background services. As a user you are able to disable it following these steps (for xiaomi). But I am not aware of a solution to circumvent it as a developer.
So you're not doing anything wrong, some phones just don't like background services taking battery life. Similar discussion can be found here: "Protected Apps" setting on Huawei phones, and how to handle it. Their solution is basically having the user disable it by calling the optimization manager for each of the problematic devices

PendingIntent() is not public in PendingIntent; cannot be accessed from outside package

I know that this type of question asked but they are unable to solve my problem, Hence I am asking it again for having exact solution to my problem, I am using android studio 3.0.1 for creating simple notification application, when i run this application it shows me errors as show as follow:
Error:(40, 25) error: PendingIntent() is not public in PendingIntent; cannot be accessed from outside package
and my MainActivity.java as follow
package com.example.ram.notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
NotificationCompat.Builder notification;
private static final int uniqueID = 45612;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notification = new NotificationCompat.Builder(this);
notification.setAutoCancel(true);
}
public void ClickNotification(View view){
//build the notification
notification.setSmallIcon(R.drawable.myimage);
notification.setTicker("this is the ticker");
notification.setWhen(System.currentTimeMillis());
notification.setContentTitle("Here is the title");
notification.setContentText("I am the body of your notificattion");
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = new PendingIntent().getActivity(this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pendingIntent);
//build notification and issues it
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(uniqueID, notification.build());
}
}
Please help me what should i do?
Simply delete "new" keyword in 40 row
must be
pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

The constructor Intent is undefined

I have the content module loaded, the specific error I'm getting is: The constructor Intent(new View.OnClickListener(){}, Class<ContactWidget>) is undefined
Any ideas on this? I got this from the tutorial here: http://developer.android.com/guide/topics/ui/notifiers/notifications.html
package com.example.contactwidget;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ContactWidget extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button calc1 = (Button) findViewById(R.id.calc_button_1);
calc1.setOnClickListener(buttonListener);
setContentView(R.layout.main);
}
private static final int HELLO_ID = 1;
private OnClickListener buttonListener = new OnClickListener() {
public void onClick (View v) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.icon;
CharSequence ticketBrief = "Button Pressed Brief";
CharSequence ticketTitle = "Button pressed";
CharSequence ticketText = "You pressed button 1";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, ticketBrief, when);
Intent notificationIntent = new Intent(this, ContactWidget.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(getApplicationContext(), ticketTitle, ticketText, contentIntent);
mNotificationManager.notify(HELLO_ID, notification);
}
};
}
Change this:
new Intent(this, ContactWidget.class);
to
new Intent(ContactWidget.this, ContactWidget.class);
The error happens because, in that case, this is referencing the instance of OnClickListener, but the Intent's constructor expects a Context. The context you have to pass is the reference to the activity itself, thus you have to access it explicitly using ContactWidget.this.
The context passed in could be from a remote application host... apparently you need the app context from your app, the one with your class (your broadcast reciever for instance).
Intent intent = new Intent(context.getApplicationContext(), WidgetryBroadcastReceiver.class);
instead of
Intent intent = new Intent(context, WidgetryBroadcastReceiver.class);
go figure.
yeah that workerd for me aswell for the error in
Geocoder gc = new Geocoder(this, Locale.getDefault());

Categories