您好我正在制作一个习惯跟踪器应用程序,当用户创建一个新习惯时,我会调用sendNotification()
方法在用户指定的时间调用通知。我希望每天在用户指定的时间显示这些通知。
现在,当应用程序正在运行或应用程序最小化时会显示通知,但是当我关闭应用程序(而不是来自设置)时,会显示通知。
这是我的代码:
private void sendNotification(){
NotificationReceiver.setupAlarm(this, notificationCalendar);
}
public class NotificationReceiver extends WakefulBroadcastReceiver {
public NotificationReceiver() {
}
public static void setupAlarm(Context context, Calendar notificationCalendar) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = getStartPendingIntent(context);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, notificationCalendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
@Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = NotificationIntentService.createIntentStartNotificationService(context);
startWakefulService(context, serviceIntent);
}
private static PendingIntent getStartPendingIntent(Context context) {
Intent intent = new Intent(context, NotificationReceiver.class);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
public class NotificationIntentService extends IntentService {
private static final int NOTIFICATION_ID = 1;
public NotificationIntentService() {
super(NotificationIntentService.class.getSimpleName());
}
public static Intent createIntentStartNotificationService(Context context) {
return new Intent(context, NotificationIntentService.class);
}
@Override
protected void onHandleIntent(Intent intent) {
try{
processStartNotification();
}finally {
WakefulBroadcastReceiver.completeWakefulIntent(intent);
}
}
private void processStartNotification() {
// Do something. For example, fetch fresh data from backend to create a rich notification?
NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Habit Time")
.setContentText("Hey time for your habit")
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setSound(alarmSound)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
notificationManager.notify(NOTIFICATION_ID, mNotifyBuilder.build());
}
}
//Manifest file
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".notification.NotificationReceiver"/>
<service
android:name=".notification.NotificationIntentService"
android:enabled="true"
android:exported="false"/>
答案 0 :(得分:0)
在您为他们提供后台服务之前,通知不会显示。创建后台服务并从该服务发送广播,此服务将继续运行您的应用程序正在运行的天气。您可以查看this详细答案。
创建一个NotificationService类并像下面一样扩展它。
public class NotificationService extends Service{
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
/* send your notification from here, in timely manner */
}
}
开始来自您的活动
Intent i = new Intent("com.example.package.NotificationService");
startService(i);
编写此代码是为了给您一个想法。我没有测试它。
答案 1 :(得分:0)
尝试以下代码:它使用alarmanager在一天中的特定时间创建一个警报,并每天重复...
声明
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MM yyyy hh:mm a");
String time=""21 12 2016 8:10 AM"
cal_alarm = Calendar.getInstance();
cal_alarm.setTime(dateFormat.parse(time));
现在将日历对象设置为特定时间以进行警报
public void set_alarm() {
Calendar calNow = Calendar.getInstance();
long current_time = calNow.getTimeInMillis();
Log.d("ALARM CALENDER VALUES", cal_alarm.toString());
long alarm_time_in_millis = cal_alarm.getTimeInMillis();
//check if time is alreday passed or not
if (alarm_time_in_millis > current_time) {
new Alarm_task(getApplicationContext(), cal_alarm).run();
}
public class Alarm_task implements Runnable {
// The date selected for the alarm
private final Calendar cal;
// The android system alarm manager
private final AlarmManager am;
// Your context to retrieve the alarm manager from
private final Context context;
long alarm_time2;
int _id;
public Alarm_task(Context context, Calendar cal) {
this.context = context;
this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.cal = cal;
this._id = (int) System.currentTimeMillis();
alarm_time2 = cal.getTimeInMillis();
//Toast.makeText(getActivity(), alarm_time2 + " ", Toast.LENGTH_SHORT).show();
}
@Override
public void run() {
// Request to start are service when the alarm date is upon us
// We don't start an activity as we just want to pop up a notification into the system bar not a full activity
Intent i = new Intent("com.package_name");
i.setAction("com.package_name");
/** Creating a Pending Intent */
PendingIntent operation = PendingIntent.getActivity(getApplicationContext(), _id, i, PendingIntent.FLAG_UPDATE_CURRENT);
/** Converting the date and time in to milliseconds elapsed since epoch */
long alarm_time = cal.getTimeInMillis();
/** Setting an alarm, which invokes the operation at alart_time each day*/
am.setRepeating(AlarmManager.RTC_WAKEUP, alarm_time, AlarmManager.INTERVAL_DAY, operation);
}
}
设置闹钟
<activity
android:name=".Prereminder"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
//same as your alarm task
<action android:name="com.package_name" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
现在,在清单中定义一个显式活动,用于处理警报意图并在警报时间显示弹出对话框和通知
public class Prereminder extends FragmentActivity {
String msg = "Helloo";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
sendNotification();
/** Creating an Alert Dialog Window */
Reminder_alert alert = new Reminder_alert();
/** Opening the Alert Dialog Window */
alert.show(getSupportFragmentManager(), "Reminder_alert");
}
private void sendNotification() {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
//handle notification on click
Intent myintent = new Intent(this, Home_page.class);
myintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, myintent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo_small)
.setContentTitle("Alarm")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
现在在你的Prereminder.java
中 public class Reminder_alert extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
/** Turn Screen On and Unlock the keypad when this alert dialog is displayed */
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
/** Creating a alert dialog builder */
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
/** Setting title for the alert dialog */
builder.setTitle("ALARM ON");
/** Setting the content for the alert dialog */
builder.setMessage("WAKE UP NOW");
/** Defining an OK button event listener */
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
/** Creating the alert dialog window */
return builder.create();
}
/**
* The application should be exit, if the user presses the back button
*/
@Override
public void onDestroy() {
super.onDestroy();
getActivity().finish();
}
}
现在,您的Reminder_alert类在警报期间显示弹出对话框:
double sum(DoubleList* list) {
DoubleNode *next = NULL;
double sum = 0;
for (DoubleNode *n = list->first; n != NULL; n = next) {
sum += n->value;
}
return sum;
}
答案 2 :(得分:0)
1-以简单的方式首先使用此功能创建警报
private void createAlarm(Date start_alarm_date, String schedual_type ,String schedule_id){
AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, PushLocalNotification.AlarmReceiver.class);
intent.setAction("Your_Action_Name"); //this action you will use later
intent.putExtra("Extra", any_extra_you_want_add);// remove if you want add extra
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
// Set the alarm to start at specific date
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
// repeat it "daily":
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
2-创建IntentService并使接收器扩展 BroadcastReceiver
public class PushLocalNotification extends IntentService {
private NotificationManager mNotificationManager;
private String mScheduleID;
NotificationCompat.Builder builder;
public PushLocalNotification() {
super("pushLocalNotification");
}
@Override
protected void onHandleIntent(Intent intent) {
// call create local notification here
}
public static class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("Your_action_Name")) {
// call service here.
Intent sendIntent = new Intent(context, PushLocalNotification.class);
sendIntent.putExtra("Extra_name", intent.getStringExtra("Previos_extra_you_add_before"));
context.startService(sendIntent);
}
}
}
private void createNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//Create Intent to launch this Activity again if the notification is clicked.
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(this, 0, i,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(intent);
// Sets the ticker text
builder.setTicker(getResources().getString(R.string.custom_notification));
// Sets the small icon for the ticker
builder.setSmallIcon(R.drawable.ic_stat_custom);
// Cancel the notification when clicked
builder.setAutoCancel(true);
// Build the notification
Notification notification = builder.build();
// Inflate the notification layout as RemoteViews
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
// Set text on a TextView in the RemoteViews programmatically.
final String time = DateFormat.getTimeInstance().format(new Date()).toString();
final String text = getResources().getString(R.string.collapsed, time);
contentView.setTextViewText(R.id.textView, text);
/* Workaround: Need to set the content view here directly on the notification.
* NotificationCompatBuilder contains a bug that prevents this from working on platform
* versions HoneyComb.
* See https://code.google.com/p/android/issues/detail?id=30495
*/
notification.contentView = contentView;
// Add a big content view to the notification if supported.
// Support for expanded notifications was added in API level 16.
// (The normal contentView is shown when the notification is collapsed, when expanded the
// big content view set here is displayed.)
if (Build.VERSION.SDK_INT >= 16) {
// Inflate and set the layout for the expanded notification view
RemoteViews expandedView =
new RemoteViews(getPackageName(), R.layout.notification_expanded);
notification.bigContentView = expandedView;
}
// START_INCLUDE(notify)
// Use the NotificationManager to show the notification
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(0, notification);
}
}
3-最后一步不要忘记在清单文件中声明服务和接收者
<receiver
android:name=".PushLocalNotification$AlarmReceiver"
android:enabled="true">
<intent-filter>
<action android:name="Your_Action_name:)" />
</intent-filter>
</receiver>
<service android:name=".PushLocalNotification" />
耐心,玩得开心:)
答案 3 :(得分:0)
创建一个包含代码的方法,您可以在其中定义时间或要显示通知的时间。需要从希望用户请求通知的位置调用此方法。
public void getNotification () {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), Notification_receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
alarmManager.cancel(pendingIntent);
Calendar calendar = Calendar.getInstance();
Calendar now = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 16);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 00);
if (now.after(calendar)) {
Log.d("Hey","Added a day");
calendar.add(Calendar.DATE, 1);
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
创建一个Notification_receiver
类,它将在此处扩展广播接收器,您将定义您的 Channel ID ,因为它非常适合 API 25及更高版本这是Notification_receiver类:
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import androidx.core.app.NotificationCompat;
//Created By Prabhat Dwivedi
public class Notification_receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder;
PendingIntent pendingIntent;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("Your App Name",
"You app Package Name",
NotificationManager.IMPORTANCE_HIGH);
String channel_Id = channel.getId();
CharSequence channel_name = channel.getName();
Log.e("Notification_receiver", "channel_Id :" + channel_Id);
Log.e("channel_name", "channel_name :" + channel_name);
channel.setDescription("Make entry of today's spending now");
notificationManager.createNotificationChannel(channel);
}
builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.yourapp_logo)
.setChannelId("Your app Name is your Channel Id")
.setContentTitle("Your title")
.setContentText("Your Description")
.setAutoCancel(true);
//nder this you will find intent it is going to define after clicking notification which activity you want to redirect
Intent repeatingIntent = new Intent(context, HomePage.class);
pendingIntent = PendingIntent.getActivity(context, 100, repeatingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
notificationManager.notify(100, builder.build());
}
}
还请在AndroidManifest.xml
文件内添加通知接收器
<receiver android:name=".Notification_receiver"/>