What I want:-
- To make a app which gives notification on given time by user.
- It should also run on background.
- I can save the time hour and minute 24hr format on SharedPreferences database so that I can overwrite the time again.
- Else part, how to not give the notification?
But what I got
I made this, But I am facing several issues:-
- I am able to make notification but only when my app is on running state.
- Not able to store in variables Xhours and Xminute into SharedPrefrences DB.
- My broadcast receiver class and notification class is working fine but not able to get the notification when the app is not running. visit this :> link to see a screenshot
Please Help, Thanks.
My settings_aztro.java activity
public void TimePickerDialog() {
TimeTv_settings.setOnClickListener(new View.OnClickListener() {
@SuppressWarnings("deprecation")
@Override
public void onClick(View v) {
showDialog(DIALOG_ID);
}
});
}
@SuppressWarnings("deprecation")
@Override
protected Dialog onCreateDialog(int id) {
if (id == DIALOG_ID) {
return new TimePickerDialog(settings_aztro.this, mTimePickerListener, Xhour, Xminute, false);
} else {
Toast.makeText(this, "Unable to locate time picker", Toast.LENGTH_SHORT).show();
return null;
}
}
protected TimePickerDialog.OnTimeSetListener mTimePickerListener = new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute)
{
// This will give 24hr value for the notification
Xhour = hourOfDay;
Xminute = minute;
// This will show the 12 hour time on the TextView
YHour = hourOfDay;
Yminute = minute;
if (YHour == 0) {
YHour += 12;
format = "AM";
} else if (YHour == 12) {
format = "PM";
} else if (YHour > 12) {
YHour -= 12;
format = "PM";
} else {
format = "AM";
}
SharedPreferences sharedPreferences = getSharedPreferences("timeinfo", Context.MODE_ENABLE_WRITE_AHEAD_LOGGING);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("keyHour",Xhour);
editor.putInt("keyMinute",Xminute);
editor.commit();
TimeTv_settings.setText(YHour + ":" + Yminute + " " + format);
if(NotifyMe==true)
{
SharedPreferences xsharedPreferences = getSharedPreferences("timeinfo", Context.MODE_ENABLE_WRITE_AHEAD_LOGGING);
savedHour = xsharedPreferences.getInt("keyHour", Integer.parseInt(""));
savedMinute = xsharedPreferences.getInt("keyMinute",Integer.parseInt(""));
Toast.makeText(settings_aztro.this, "YHour: "+YHour+"Ymin: "+Yminute+" "+format+"\tNotify: "+NotifyMe, Toast.LENGTH_SHORT).show();
generateCustomNotification();
}
else
{
NotifyMe = false;
}
}
};
public void generateCustomNotification()
{
CustomCalendar.set(Calendar.HOUR_OF_DAY,savedHour);
CustomCalendar.set(Calendar.MINUTE,savedMinute);
CustomCalendar.set(Calendar.SECOND,0);
Intent CallReciverIntent = new Intent(settings_aztro.this,NotificationBReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(settings_aztro.this,0,CallReciverIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) settings_aztro.this.getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,CustomCalendar.getTimeInMillis(),pIntent);
Log.d("samay","Hour-> "+Xhour+" Minute-> "+Xminute+"Time in milis -> "+CustomCalendar.getTimeInMillis());
}
public void saveNotificationTime()
{
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.About_settingsTv2:
Toast.makeText(this, "C", Toast.LENGTH_SHORT).show();
generateCustomNotification();
Log.d("Timeqq","Hour-> "+Xhour+" Minute-> "+Xminute);
Xhour = 0;Xminute=0;
break;
case R.id.FacebookSignin_settings:
Log.d("newtime","hour= "+Xhour+" minute= "+Xminute+"Time in milis -> "+CustomCalendar.getTimeInMillis()+"Notify "+NotifyMe);
Log.d("newtime","hour= "+savedHour+" minute= "+savedMinute+"Time in milis -> "+CustomCalendar.getTimeInMillis()+"Notify "+NotifyMe);
break;
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(switch_settings.isChecked())
{
NotifyMe = true;
TimeRLayout.setVisibility(View.VISIBLE);
Toast.makeText(this, "On", Toast.LENGTH_SHORT).show();
Toast.makeText(this, "Hr -> "+Xhour+"Min -> "+Xminute, Toast.LENGTH_SHORT).show();
Log.d("Waqt","Hour-> "+Xhour+" Minute-> "+Xminute);
}
else if(!switch_settings.isChecked())
{
NotifyMe = false;
Toast.makeText(this, "Off", Toast.LENGTH_SHORT).show();
if(NotifyMe==false)
{
TimeRLayout.setVisibility(View.GONE);
}
else
{
}
}
}
My Receiver class
public class NotificationBReceiver extends BroadcastReceiver
{
int MID = 98;
@Override
public void onReceive(Context context, Intent intent)
{
long when = System.currentTimeMillis();
NotificationManager nManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent notificationIntent = new Intent(context, list_of_signs.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 10,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder NotificationBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.aztro2)
.setSound(defaultSoundUri)
.setContentTitle("Hello! Check Your Today's Horoscope.")
.setAutoCancel(true)
.setWhen(when)
.setContentIntent(pendingIntent)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
nManager.notify(MID, NotificationBuilder.build());
MID++;;
Manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_main_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/NoActionBar">
<activity android:name=".list_of_signs">
<!--list_of_signs-->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
<activity android:name=".AllSignsData.class_aquarius"/>
<activity android:name=".AllSignsData.class_aries"/>
<activity android:name=".AllSignsData.class_cancer"/>
<activity android:name=".AllSignsData.class_gemini"/>
<activity android:name=".AllSignsData.class_capricorn"/>
<activity android:name=".AllSignsData.class_leo"/>
<activity android:name=".AllSignsData.class_libra"/>
<activity android:name=".AllSignsData.class_pisces"/>
<activity android:name=".AllSignsData.class_sagittarius"/>
<activity android:name=".AllSignsData.class_scorpio"/>
<activity android:name=".AllSignsData.class_taurus"/>
<activity android:name=".AllSignsData.class_virgo"/>
<activity android:name=".settings_aztro"/>
<receiver android:name=".NotificationBReceiver"/>
</application>
</manifest>
Ok, This is the pattern for Alarm Manager. In this implementation, no statically defined Broadcast Receiver is used /nor should it be used for scheduling tasks, according to Android O best practices, in short, FORGET ABOUT BROADCAST RECEIVER if you want background notification.
1) Create an intent service (ex.ReminderAlarmService) to post your notification. This service will be started with a pending intent used by the alarmManager. onHandleIntent should create the notification and show it: ex.
2) In the service, create an public util method to return "operation" pending intent to launch the above intent service, (also called deep-link intent) ex.
3) Create a util class to get an instance of the alarm manager, use it to set the time and the "operation" intent created with the method above. The operation intent launches the intent service, which does the whatever you have in onHandleIntent. ex.
Overall Design Flow: