使用最近的应用程序关闭应用程序时未显示的本地通知。

时间:2016-12-21 07:29:12

标签: java android android-activity android-notifications

您好我正在制作一个习惯跟踪器应用程序,当用户创建一个新习惯时,我会调用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"/>

4 个答案:

答案 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)

  1. 创建一个包含代码的方法,您可以在其中定义时间或要显示通知的时间。需要从希望用户请求通知的位置调用此方法。

    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);
    }
    
  2. 创建一个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());
        }
    }
    
  3. 还请在AndroidManifest.xml文件内添加通知接收器

    <receiver android:name=".Notification_receiver"/>
    
相关问题