Android通知只显示一次

时间:2014-04-20 08:46:15

标签: android notifications alarmmanager

我有以下代码,其中有一个日期选择器和时间选择器

当我选择该日期和时间时,我想显示通知... 它是完美的工作,但当我再次通知意味着如果我pu6多次通知它将只显示我最后一个...

表示只有最后通知显示并非全部...

NotifyService.java

package com.blundell.tut.service;

import android.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.blundell.tut.ui.phone.SecondActivity;


public class NotifyService extends Service {

/**
 * Class for clients to access
 */
public class ServiceBinder extends Binder {
    NotifyService getService() {
        return NotifyService.this;
    }
}

// Unique id to identify the notification.
public static int NOTIFICATION = 123;
// Name of an intent extra we can use to identify if this service was started to create a notification  
public static final String INTENT_NOTIFY = "com.blundell.tut.service.INTENT_NOTIFY";
// The system notification manager
private NotificationManager mNM;

@Override
public void onCreate() {
    Log.i("NotifyService", "onCreate()");
    mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i("LocalService", "Received start id " + startId + ": " + intent);

    // If this service was started by out AlarmTask intent then we want to show our notification
    if(intent.getBooleanExtra(INTENT_NOTIFY, false))

        showNotification();

    // We don't care if this service is stopped as we have already delivered our notification
    return START_NOT_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

// This is the object that receives interactions from clients
private final IBinder mBinder = new ServiceBinder();

/**
 * Creates a notification and shows it in the OS drag-down status bar
 */
private void showNotification() {
    // This is the 'title' of the notification
    CharSequence title = "Alarm!!";
    // This is the icon to use on the notification
    int icon = R.drawable.ic_dialog_alert;
    // This is the scrolling text of the notification
    CharSequence text = "Your notification time is upon us.";       
    // What time to show on the notification
    long time = System.currentTimeMillis();

    Notification notification = new Notification(icon, text, time);

    // The PendingIntent to launch our activity if the user selects this notification
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SecondActivity.class), 0);

    // Set the info for the views that show in the notification panel.
    notification.setLatestEventInfo(this, title, text, contentIntent);

    // Clear the notification when it is pressed
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notification.defaults |= Notification.DEFAULT_SOUND;
    notification.defaults |= Notification.DEFAULT_VIBRATE;
    NOTIFICATION++;
    Toast.makeText(NotifyService.this, Integer.toString(NOTIFICATION), Toast.LENGTH_SHORT).show();
    mNM.notify(NOTIFICATION, notification);

    // Stop the service when we are finished
    stopSelf();
}
}

ScheduleClient.java

package com.blundell.tut.service;

import java.util.Calendar;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;

/**
 * This is our service client, it is the 'middle-man' between the
 * service and any activity that wants to connect to the service
 * 
 * @author paul.blundell
 */
public class ScheduleClient {

    // The hook into our service
    private ScheduleService mBoundService;
    // The context to start the service in
    private Context mContext;
    // A flag if we are connected to the service or not
    private boolean mIsBound;

    public ScheduleClient(Context context) {
        mContext = context;
    }

    /**
     * Call this to connect your activity to your service
     */
    public void doBindService() {
        // Establish a connection with our service
        mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    }

    /**
     * When you attempt to connect to the service, this connection will be called with the result.
     * If we have successfully connected we instantiate our service object so that we can call methods on it.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with our service has been established, 
            // giving us the service object we can use to interact with our service.
            mBoundService = ((ScheduleService.ServiceBinder) service).getService();
        }

        public void onServiceDisconnected(ComponentName className) {
            mBoundService = null;
        }
    };

    /**
     * Tell our service to set an alarm for the given date
     * @param c a date to set the notification for
     */
    public void setAlarmForNotification(Calendar c){
        mBoundService.setAlarm(c);
    }

    /**
     * When you have finished with the service call this method to stop it 
     * releasing your connection and resources
     */
    public void doUnbindService() {
        if (mIsBound) {
            // Detach our existing connection.
            mContext.unbindService(mConnection);
            mIsBound = false;
        }
    }
}

ScheduleService.java

package com.blundell.tut.service;

import java.util.Calendar;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import com.blundell.tut.service.task.AlarmTask;

public class ScheduleService extends Service {


    /**
     * Class for clients to access
     */
    NotifyService ns=new NotifyService();
    public class ServiceBinder extends Binder {
        ScheduleService getService() {
            return ScheduleService.this;


        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("ScheduleService", "Received start id " + ns.NOTIFICATION + ": " + intent);

        // We want this service to continue running until it is explicitly stopped, so return sticky.
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    // This is the object that receives interactions from clients. See
    private final IBinder mBinder = new ServiceBinder();

    /**
     * Show an alarm for a certain date when the alarm is called it will pop up a notification
     */
    public void setAlarm(Calendar c) {
        // This starts a new thread to set the alarm
        // You want to push off your tasks onto a new thread to free up the UI to carry on responding
        new AlarmTask(this, c).run();
    }
}

AlarmTask.java

    package com.blundell.tut.service.task;

import java.util.Calendar;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

import com.blundell.tut.service.NotifyService;


public class AlarmTask implements Runnable{
    // The date selected for the alarm
    private final Calendar date;
    // The android system alarm manager
    private final AlarmManager am;
    // Your context to retrieve the alarm manager from
    private final Context context;

    public AlarmTask(Context context, Calendar date) {
        this.context = context;
        this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        this.date = date;
    }

    @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 intent = new Intent(context, NotifyService.class);
        intent.putExtra(NotifyService.INTENT_NOTIFY, true);
        PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);

        // Sets an alarm - note this alarm will be lost if the phone is turned off and on again
        am.set(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), pendingIntent);

        long firstTime = date.getTimeInMillis();

        am.setRepeating(AlarmManager.RTC_WAKEUP, firstTime, am.INTERVAL_DAY * 7, pendingIntent);
    }
}

MainActivity.java

package com.blundell.tut.ui.phone;

import java.util.Calendar;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.DatePicker;
import android.widget.TimePicker;
import android.widget.Toast;

import com.blundell.tut.R;
import com.blundell.tut.service.NotifyService;
import com.blundell.tut.service.ScheduleClient;

public class MainActivity extends Activity  
{
    // This is a handle so that we can call methods on our service
    private ScheduleClient scheduleClient;
    private DatePicker picker;
    NotifyService ns;
    private TimePicker tp;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        scheduleClient = new ScheduleClient(this);
        scheduleClient.doBindService();
        ns=new NotifyService();

        picker = (DatePicker) findViewById(R.id.scheduleTimePicker);
        tp=(TimePicker)findViewById(R.id.TimePicker);
        tp.setIs24HourView(true);
    }


    public void onDateSelectedButtonClick(View v){

        int day = picker.getDayOfMonth();
        int month = picker.getMonth();
        int year = picker.getYear();
        int hour=tp.getCurrentHour();
        int min=tp.getCurrentMinute();
        // Create a new calendar set to the date chosen
        // we set the time to midnight (i.e. the first minute of that day)
        Calendar c = Calendar.getInstance();

        c.set(year, month, day,hour,min,0);

        scheduleClient.setAlarmForNotification(c);
        // Notify the user what they just did
        //Toast.makeText(this, Integer.toString(ns.NOTIFICATION), Toast.LENGTH_SHORT).show();
        //Toast.makeText(this, "Notification set for: "+ day +"/"+ (month+1) +"/"+ year, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onStop() 
    {
        // When our activity is stopped ensure we also stop the connection to the service
        // this stops us leaking our activity into the system *bad*
        if(scheduleClient != null)
            scheduleClient.doUnbindService();
        super.onStop();
    }
}

SecondActivity.java

package com.blundell.tut.ui.phone;

import android.app.Activity;
import android.os.Bundle;

import com.blundell.tut.R;

/**
 * This is the activity that is started when the user presses the notification in the status bar
 * @author paul.blundell
 */
public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

}

请建议我在哪个地方更改代码... ????

3 个答案:

答案 0 :(得分:2)

在这一行中,

mNM.notify(通知,通知);

只要确保每次传递不同的NOTIFICATION值。

答案 1 :(得分:1)

AlarmTask.java,您在PendingIntent中的硬编码始终为0。 requestCode必须是

  

UNIQUE INTEGER NUMBER

所以改变你的代码,

PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);

int random = (int)System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, random, intent, 0); 

答案 2 :(得分:0)

只需编写这样的代码。

int random = (int)System.currentTimeMillis();
manager.notify(random , activeNotification);