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.
Related
I'm trying to fire a notification when the battery level is less the %10.
here is my notification class located at MainActivity.java
public void notify(View view) {
String title = "Warning! low battery";
String text = "Please plug your mobile device to a charger";
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_qs_battery_saver)
.setContentTitle(title)
.setContentText(text)
.setContentIntent(pendingIntent)
.build();
notificationManager.notify(notificationID++, notification);
}
I'm trying to fire it from the BatteryReceiver class:
package com.michal.ex2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.util.Log;
import android.view.View;
public class BatteryReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = (level * 100) / scale;
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean isPlugged;
isPlugged = plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB;
if ((percent == 10) && !isPlugged) {
Log.d("mylog", "low battery");
//notify();
synchronized(mActivity){
mActivity.notify();
}
}
}
}
First i tried calling calling notify from MainActivity, but the app crash with the error:
java.lang.IllegalMonitorStateException: object not locked by thread before notify()
I've searched for a solution and found that I need to lock the notify, so I tried calling it with synchronized():
synchronized(mActivity){
mActivity.notify();
but nothing happened. The battery receiver works alright(I'm getting the right log message) but notify() is not been called.
Maybe the function you'are calling is not the MainActivity.notify(View view) but the Object.notify(). Therefore nothing happens. Give an appropriate function argument.
mActivity.notify(null);
I am currently trying to set up the date picker and time picker to fire out a notification when the time is reached. I have created a method in MainActivity and this is being called from AlarmReceiver. Every time the timer reaches the set amount, the application is crashing and no errors are being shown in logcat.
I know it is something to do with this method being called from AlarmReceiver, i just don't know what the problems is. This method is also currently linked to a button which is working when pressed (buttonStopAlarm) fires a notification when pressed as wanted) so overall the method does work, it's just not working when being called from another class.
Any help would be greatly appreciated! Thank you!
AlarmReceiver
package servicealarmdemo.test2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
MainActivity main = new MainActivity();
#Override
public void onReceive(Context arg0, Intent arg1) {
Toast.makeText(arg0, "Alarm received!", Toast.LENGTH_LONG).show();
main.addNotification();
}
}
By doing this MainActivity main = new MainActivity(); you are just creating an instance of MainActivity but it will not have it's context mean this which is basically provided when Activity is started by the OS
so move you Notification code in your Receiver and use arg0 as context
public class AlarmReceiver extends BroadcastReceiver {
//MainActivity main = new MainActivity();
Context cxt;
#Override
public void onReceive(Context arg0, Intent arg1) {
Toast.makeText(arg0, "Alarm received!", Toast.LENGTH_LONG).show();
cxt = arg0;
//main.addNotification();
addNotification();
}
public void addNotification() {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(cxt)
.setSmallIcon(R.drawable.icon_transperent)
.setContentTitle("Achieve Alert!")
.setContentText("This is a reminder for your deadline!");
Intent notificationIntent = new Intent(cxt, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(cxt, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager)cxt.getSystemService(Context.NOTIFICATION_SERVICE);
builder.setVibrate(new long[] { 0, 1000, 1000, 1000, 1000 });
manager.notify(0, builder.build());
}
}
I'm trying to get the Major ID from an iBeacon as a string and pass it to an activity called "LoginActivity.java" so that I can then pass it to my PHP script via Volley POST along with login info username and password, the script will first check if the beacon value is NULL, if so return an error that a beacon is not in range so they cannot log in.
So far I've gotten the Major ID and converted it to a string but I'm getting an error when creating the intent "Cannot resolve constructor". I marked the line where I'm getting the error with <<<<ERROR below. (It's near the end).
package com.mcrlogs.pp.test;
/**
* Created by myuser on 15/01/2017.
*/
import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothClass;
import android.content.Context;
import android.content.Intent;
import com.estimote.sdk.Beacon;
import com.estimote.sdk.BeaconManager;
import com.estimote.sdk.Region;
import java.util.List;
import java.util.UUID;
public class BeaconChecker extends Application {
private BeaconManager beaconManager;
public void showNotification(String title, String message) {
Intent notifyIntent = new Intent(this, MainActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivities(this, 0,
new Intent[] { notifyIntent }, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.security)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.build();
notification.defaults |= Notification.DEFAULT_SOUND;
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notification);
}
#Override
public void onCreate() {
super.onCreate();
beaconManager = new BeaconManager(getApplicationContext());
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
beaconManager.startMonitoring(new Region(
"monitored region",
UUID.fromString("B9407F30-F5F8-466E-AFF9-25556B57FE6D"),
null, null));
}
});
beaconManager.setMonitoringListener(new BeaconManager.MonitoringListener() {
#Override
public void onEnteredRegion(Region region, List<Beacon> list) {
String iBeaconID = convertIBeaconIDToString(list.get(0).getMajor());
System.out.println(iBeaconID);
showNotification(
"MCR Beacon Detected!",
"Login enabled.");
}
private String convertIBeaconIDToString (int major) {
String iBeaconID = "";
iBeaconID = iBeaconID.concat(Integer.toString(major));
return iBeaconID;
Intent i = new Intent(this, LoginActivity.class); <<<<ERROR
i.putExtra("iBeaconID",iBeaconID);
}
#Override
public void onExitedRegion(Region region) {
// could add an "exit" notification too if you want (-:
}
});
}
}
Try changing:
Intent i = new Intent(this, LoginActivity.class);
To:
Intent i = new Intent(BeaconChecker.this, LoginActivity.class);
This clarifies that the this you refer to is the Application class that satisfies the requirements of the constructor for Intent.
I am learning how to build home screen widget in Android. This code is for an app widget to toggle RingerMode from NORMAL to SILENT and vice-versa.
This works fine but I need a full in-sight of logical flow (i.e which gets initiated when, goes where, does what, dies when) of all the intents in this.
Please help me understand this topic clearer.
package com.dummies.android.silentmodetoggle;
import android.app.Activity;
import android.app.IntentService;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.util.Log;
import android.widget.RemoteViews;
public class AppWidget extends AppWidgetProvider {
public static String tag ="SilentModeToggleWidget";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d(tag, "onReceive() first line");
if(intent.getAction()==null)
{
//Do Something
Log.d(tag, "before startService()");
context.startService(new Intent(context, ToggleService.class));
}
else{
super.onReceive(context, intent);
}
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// Do something in specified intervals
context.startService(new Intent(context, ToggleService.class));
}
public static class ToggleService extends IntentService{
public ToggleService(){
super("AppWidget$ToggleService");
Log.d(tag, "In ToggleService construcor");
}
#Override
protected void onHandleIntent(Intent arg0) {
Log.d(tag, "In ToggleService > onHandleIntent");
// TODO Auto-generated method stub
ComponentName cn = new ComponentName(this, AppWidget.class);
AppWidgetManager mgr = AppWidgetManager.getInstance(this);
mgr.updateAppWidget(cn, buildUpdate(this));
}
private RemoteViews buildUpdate(Context context){
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
AudioManager audioManager = (AudioManager)context.getSystemService(Activity.AUDIO_SERVICE);
if(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT){
updateViews.setImageViewResource(R.id.phoneState, R.drawable.phone_on);
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
else{
updateViews.setImageViewResource(R.id.phoneState, R.drawable.phone_silent);
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
Intent i = new Intent(this, AppWidget.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
updateViews.setOnClickPendingIntent(R.id.phoneState, pi);
return updateViews;
}
}
}
still not sure on what are u asking, but I'll try to answer, if not what u want, please explain in a different way.
Intent are usually started immediatly. You create an Intent can start it by calling startService or startActivity, so for example:
context.startService(new Intent(context, ToggleService.class));
on both times you wrote the above code, the service ToggleService is immediatly started.
PendingIntent on the other hand are saved to be started at later time, so for example
updateViews.setOnClickPendingIntent(R.id.phoneState, pi);
on the above line, the AppWidget Broadcast is started when the user clicks on R.id.phoneState in your HomeScreen AppWidget.
Each PendingIntent is stored in the system with a certain ID, this ID is the requestCode parameter (you used zero on your code)... that means, that if you create a different PendingIntent with the same ID it will override it, meaning a different action will be started when the user clicks on R.id.phoneState
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.