【问题标题】:Notification on every 5 minutes每5分钟通知一次
【发布时间】:2013-10-19 12:13:46
【问题描述】:

我想每 5 分钟向用户发送一次通知,我正在使用以下代码。 它第一次向我显示通知,但下次不通知。

public void startAlarm() {
    AlarmManager alarmManager = (AlarmManager) this.getSystemService(this.ALARM_SERVICE);
    long whenFirst = System.currentTimeMillis();         // notification time
    Intent intent = new Intent(this, NotifyUser.class);
    PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
    alarmManager.setRepeating(AlarmManager.RTC, whenFirst, 60*5000, pendingIntent);            
}

public class NotifyUser extends Service {   
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        loadNotification(); 
    }

    private void loadNotification() {
        NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notify = new Notification(R.drawable.ic_launcher/*android.R.drawable.stat_notify_more*/, "Hanumanji waiting for you", System.currentTimeMillis());
        Context context = NotifyUser.this;
        CharSequence title = "Hanumanji is waiting for you";
        CharSequence details = "Do Hanuman Chalisa Parayan with ShlokApp.";
        Intent intent = new Intent(context, NotifyUser.class);
        PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
        notify.setLatestEventInfo(context, title, details, pending);
        notify.sound = Uri.parse("android.resource://pro.shlokapp.hanumanchalisa/"+ R.raw.game_sound_pause);
        nm.notify(0, notify);
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        return 1;
    }

    public void onStart(Intent intent, int startId) {
        // TO DO
    }

    public IBinder onUnBind(Intent arg0) {
        // TO DO Auto-generated method
        return null;
    }

    public void onStop() {}

    public void onPause() {}

    @Override
    public void onDestroy() {}

    @Override
    public void onLowMemory() {}
}

【问题讨论】:

  • 你确定 1/ 你没有取消活动类中的通知吗? 2/ 你不是简单地更新现有的通知?
  • 如何更新现有通知?
  • 当您调用nm.notify(0, notify); 时,您总是传递相同的通知ID(即0),因此更新现有通知而不是创建新通知。为不同的通知传递不同的数字。
  • 尝试返回 START_STICKY,并为警报服务创建一个单独的类,然后从该服务调用另一个创建或生成通知的服务。和 AlarmManager.RTC_WAKEUP 而不是 AlarmManager.RTC

标签: android android-alarms


【解决方案1】:

在这篇文章How exactly to use Notification.Builder 中有一个例子。我用它在我的应用程序中发出通知。它还使用支持库中的 NotificationBuilder。

我认为在您上面的代码中,您只是在更新已经存在的通知。尝试通过每次设置/更新新通知时显示一个增加一的数字来检查它。

希望这对你有帮助 =)。

【讨论】:

    【解决方案2】:

    它第一次显示通知但下次不给。:原因是你使用nm.notify(0, notify); 不要使用 0,因为它会显示最新通知。

    下面的代码就像一个魅力:

    public class MainActivity extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        MyTimerTask myTask = new MyTimerTask();
        Timer myTimer = new Timer();
    
        myTimer.schedule(myTask, 5000, 1500);
    
    }
    
    class MyTimerTask extends TimerTask {
        public void run() {
    
            generateNotification(getApplicationContext(), "Hello");
        }
    }
    
    private void generateNotification(Context context, String message) {
    
        int icon = R.drawable.ic_launcher;
        long when = System.currentTimeMillis();
        String appname = context.getResources().getString(R.string.app_name);
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        Notification notification;
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                new Intent(context, MainActivity.class), 0);
    
        // To support 2.3 os, we use "Notification" class and 3.0+ os will use
        // "NotificationCompat.Builder" class.
        if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
            notification = new Notification(icon, message, 0);
            notification.setLatestEventInfo(context, appname, message,
                    contentIntent);
            notification.flags = Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify((int) when, notification);
    
        } else {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(
                    context);
            notification = builder.setContentIntent(contentIntent)
                    .setSmallIcon(icon).setTicker(appname).setWhen(0)
                    .setAutoCancel(true).setContentTitle(appname)
                    .setContentText(message).build();
    
            notificationManager.notify((int) when, notification);
    
        }
    
    }
    

    }

    使用 Timer 类。根据您的需要更改计时器间隔。 希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      MainActivity.java // 它包含在一个文本视图上 tvTime

          public class MainActivity extends Activity {
          private SampleAlarmReceiver alarm;
          private ListView listView;
          private ArrayList<String> times;
          private ArrayAdapter mAdapter;
      
          private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
              @Override
              public void onReceive(Context context, Intent intent) {
                  displayTime();
              }
          };
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              listView = (ListView) findViewById(R.id.listView);
              alarm = new SampleAlarmReceiver();
              alarm.setAlarm(this);
              times = new ArrayList<>();
              Calendar c = Calendar.getInstance();
              String time = c.get(Calendar.HOUR) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);
              times.add(time);
              mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, times);
              listView.setAdapter(mAdapter);
          }
      
          @Override
          protected void onResume() {
              super.onResume();
              LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
                      new IntentFilter("display_time"));
          }
      
          @Override
          public boolean onCreateOptionsMenu(Menu menu) {
              getMenuInflater().inflate(R.menu.main, menu);
              return true;
          }
      
          @Override
          public boolean onOptionsItemSelected(MenuItem item) {
              switch (item.getItemId()) {
                  // When the user clicks START ALARM, set the alarm.
                  case R.id.start_action:
                      alarm.setAlarm(this);
                      return true;
                  // When the user clicks CANCEL ALARM, cancel the alarm. 
                  case R.id.cancel_action:
                      alarm.cancelAlarm(this);
                      return true;
              }
              return false;
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
              LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
          }
      
          @SuppressLint("SetTextI18n")
          public void displayTime() {
              Calendar c = Calendar.getInstance();
              String time = c.get(Calendar.HOUR) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);
              times.add(time);
              mAdapter.notifyDataSetChanged();
          }
      }
      

      SampleAlarmReceiver.java

      public class SampleAlarmReceiver extends WakefulBroadcastReceiver {
          // The app's AlarmManager, which provides access to the system alarm services.
          private AlarmManager alarmMgr;
          // The pending intent that is triggered when the alarm fires.
          private PendingIntent alarmIntent;
      
          @Override
          public void onReceive(Context context, Intent intent) {
      
              Intent intent1 = new Intent("display_time");
              // You can also include some extra data.
              LocalBroadcastManager.getInstance(context).sendBroadcast(intent1);
      
          }
      
          // BEGIN_INCLUDE(set_alarm)
      
          /**
           * Sets a repeating alarm that runs once a day at approximately 8:30 a.m. When the
           * alarm fires, the app broadcasts an Intent to this WakefulBroadcastReceiver.
           *
           * @param context given context
           */
          public void setAlarm(Context context) {
              alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
              Intent intent = new Intent(context, SampleAlarmReceiver.class);
              alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
      
              alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                      5 * 60 * 1000,  // After five minute
                      5 * 60 * 1000,  // Every five minute
                      alarmIntent);
      
              // Enable {@code SampleBootReceiver} to automatically restart the alarm when the
              // device is rebooted.
              ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
              PackageManager pm = context.getPackageManager();
      
              pm.setComponentEnabledSetting(receiver,
                      PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                      PackageManager.DONT_KILL_APP);
          }
      
          /**
           * Cancels the alarm.
           *
           * @param context given context
           */
          public void cancelAlarm(Context context) {
              // If the alarm has been set, cancel it.
              if (alarmMgr != null) {
                  alarmMgr.cancel(alarmIntent);
              }
      
              // Disable {@code SampleBootReceiver} so that it doesn't automatically restart the 
              // alarm when the device is rebooted.
              ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
              PackageManager pm = context.getPackageManager();
      
              pm.setComponentEnabledSetting(receiver,
                      PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                      PackageManager.DONT_KILL_APP);
          }
      }
      

      SampleBootReceiver.java

      public class SampleBootReceiver extends BroadcastReceiver {
          SampleAlarmReceiver alarm;
          @Override
          public void onReceive(Context context, Intent intent) {
              if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
              {
                  alarm  = new SampleAlarmReceiver();
                  alarm.setAlarm(context);
              }
          }
      }
      

      ma​​in.xml // 它是 MainActivity 中使用的菜单

      <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
          <item
              android:id="@+id/start_action"
              android:title="Start Alarm"
              app:showAsAction="ifRoom|withText" />
          <item
              android:id="@+id/cancel_action"
              android:title="Stop Alarm"
              app:showAsAction="ifRoom|withText" />
      </menu>
      

      ma​​nifest.xml

      <?xml version="1.0" encoding="utf-8"?>
      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.alarmmanager">
      
          <uses-permission android:name="android.permission.WAKE_LOCK" />
          <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
      
          <application
              android:allowBackup="true"
              android:icon="@mipmap/ic_launcher"
              android:label="@string/app_name"
              android:supportsRtl="true"
              android:theme="@style/AppTheme">
              <activity android:name=".MainActivity">
                  <intent-filter>
                      <action android:name="android.intent.action.MAIN" />
      
                      <category android:name="android.intent.category.LAUNCHER" />
                  </intent-filter>
              </activity>
      
              <receiver android:name=".SampleAlarmReceiver" />
      
              <receiver
                  android:name=".SampleBootReceiver"
                  android:enabled="false">
                  <intent-filter>
                      <action android:name="android.intent.action.BOOT_COMPLETED" />
                  </intent-filter>
      
              </receiver>
      
          </application>
      
      </manifest>
      

      【讨论】:

        猜你喜欢
        • 2020-11-17
        • 2018-06-12
        • 2021-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-23
        • 2012-06-30
        • 1970-01-01
        相关资源
        最近更新 更多