如何从应用

时间:2016-02-04 10:50:16

标签: java android android-service alarmmanager android-alarms

我有一个关于从我的应用设置每日数据检查的一般性问题(在发生某些事件时发出通知)。

我目前的做法是:

  • 从应用程序(onCreate)开始服务
  • 从服务中我在检查是否已经存在匹配的PendingIntent后使用AlarmManager设置警报(在这种情况下我不会 需要设置新警报)
  • 服务检查来自SharedPreferences的数据并最终显示通知

出于测试目的,我将闹钟设置为+1分钟......但是它没有那样工作。也许我在概念上做错了什么?

一些代码

的AndroidManifest.xml

<application
    <activity
        android:name=".OverviewActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar"
        android:configChanges="orientation"
        android:screenOrientation="portrait">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service
        android:name="xxxxx.CheckDaysMonths" >
    </service>
</application>

服务CheckDaysMonths

public class CheckDaysMonths extends Service {

    private static int ALARM_ID = 131313;
    private static String DECLARED_ACTION = "xxxxx.CheckDaysMonths";

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

        PendingIntent alarmIntent = AlarmHelper.getPendingIntentFromAlarm(this, ALARM_ID, DECLARED_ACTION);
        if(alarmIntent == null) {
           if(someConditionIsMet)
              sendNotification(" my notification text ");
           // Set an alarm for the next time this service should run:
           setAlarm();
        }

        stopSelf();
    }

    public void setAlarm() {

        AlarmHelper.setAlarm(this, ALARM_ID, DECLARED_ACTION, 8);
    }

    public void sendNotification(String notifyText) {

        Intent mainIntent = new Intent(this, OverviewActivity.class);
        @SuppressWarnings("deprecation")
        Notification noti = new Notification.Builder(this)
                .setAutoCancel(true)
                .setContentIntent(PendingIntent.getActivity(this, 131314, mainIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT))
                .setContentTitle("Gratuliere!")
                .setContentText("Du bist seit " + notifyText + " rauchfrei!")
                .setDefaults(Notification.DEFAULT_ALL)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setTicker("Du bist seit " + notifyText + " rauchfrei!")
                .setWhen(System.currentTimeMillis())
                .getNotification();

        NotificationManager notificationManager
                = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(131315, noti);

    }

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

主要活动( OverviewActivity.java

编辑:将服务调用从隐式更改为显式

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_overview);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    startService(new Intent(this, CheckDaysMonths.class));


    // additional stuff happening on the activity of my app goes here:
    ...
}

AlarmHelper.java

public class AlarmHelper {

    public static PendingIntent getPendingIntentFromAlarm(Context context, int alarmId, String declaredAction) {
        return (PendingIntent.getService(context, alarmId,
                new Intent(declaredAction),
                PendingIntent.FLAG_NO_CREATE));
    }

    public static void setAlarm(Context context, int alarmId, String declaredAction, int hourOfDay) {
        Intent serviceIntent = new Intent(declaredAction);
        PendingIntent pi = PendingIntent.getService(context, alarmId, serviceIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        // How long until tomorrow to its hourOfDay?
        //DateTime tomorrow = (new DateTime()).plusDays(1);
        //DateTime tomorrowAtHourOfDay = new DateTime(tomorrow.getYear(), tomorrow.getMonthOfYear(), tomorrow.getDayOfMonth(), hourOfDay, 0);

        DateTime tomorrowAtHourOfDay = (new DateTime()).plusHours(3);

        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        am.set(AlarmManager.RTC_WAKEUP, tomorrowAtHourOfDay.getMillis(), pi);
    }
}

1 个答案:

答案 0 :(得分:1)

我通过引入另一个“中间层”服务来修复它

所以现在我有了

  • 应用GUI启动服务1
  • 服务1将检查是否已经有正确签名运行的警报。如果没有,它将启动警报
  • 闹钟将在凌晨2点开始,然后开始服务2
  • 服务2将检查数据(SharedPreferences)并最终发送通知。然后它将再次启动警报
  • 用于BOOT的BroadcastReceiver启动服务2

这很有效