【问题标题】:Intent not repeated by AlarmManagerAlarmManager 未重复意图
【发布时间】:2015-08-06 12:25:49
【问题描述】:

这是我的 BootBroadcast

public class BootBroadcast extends BroadcastReceiver {

    public static final String FILE_NAME = "BootBroadcast.java";
    private static final long REPEAT_TIME_TO_CHECK_EXPENSES = 1000 * 60; //1 minute

@Override
    public void onReceive(Context context, Intent intent) {
        Log.v(FILE_NAME, "in onReceive");
        AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        Intent service1 = new Intent(context, ISCheckExpenses.class);
        Log.v(FILE_NAME, "starting service1");
        context.startService(service1);

        PendingIntent pending1 = PendingIntent.getBroadcast(context, 0, service1, PendingIntent.FLAG_UPDATE_CURRENT);
        Calendar cal1 = Calendar.getInstance();
        cal1.add(Calendar.SECOND, 600);
        service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, pending1);
    }
}

这是我的 ISCheckExpenses

public class ISCheckExpenses extends IntentService {
public static final String FILE_NAME = "ISCER";
private int recurringExpensesNotificationID = 001;
private int recurringExpensesMultiplier = 123;

public ISCheckExpenses(){
        super(ISCheckExpenses.class.getName());
    }

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

@Override
    protected void onHandleIntent(Intent intent){

        Log.d(FILE_NAME, "IntentService Started!");

     //do some processing and send a notification to the user
    String subject, content;
    subject = getString(R.string.recurring_expenses_notification_due_subject);
                content = getApplicationContext().getString(R.string.recurring_expenses_notification_due_content);
     sendNotification(recurringExpensesNotificationID,1,subject,content);
    }

    private void sendNotification(int notificationID, int notificationType, String subject, String content){
        Intent myIntent = new Intent(this, MainActivity.class);
        int randomID = 1;

            myIntent.putExtra("intentCaller","expensesRecurring");
            randomID = recurringExpensesMultiplier * requestID;

        //just to make sure the random ID is non-negative
        if (randomID < 0){
            randomID = randomID * -1;
        }
        myIntent.setAction(Intent.ACTION_VIEW);
        myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pIntent = PendingIntent.getActivity(getBaseContext(), randomID, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder n  = new NotificationCompat.Builder(this)
                .setContentTitle(subject)
                .setContentText(content)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pIntent)
                .setAutoCancel(true);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        n.build().flags |= Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(notificationID, n.build());
    }
}

这两个文件都已经在我的 AndroidManifest.xml 中了

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
<service
            android:name=".ISCheckExpenses"
            android:exported="false"
            android:icon="@mipmap/ic_launcher"
            android:enabled="true" />
<receiver android:name=".BootBroadcast" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
</application>

重启设备几秒钟后,将显示通知。然后我点击通知清除它。我的应用程序应该在 1 分钟后重新显示通知,对吗?但事实并非如此。我希望看到“IntentService 已启动!”在我的 logcat 中每 1 分钟 .. 但什么也没有出现? “IntentService 已启动!”只显示一次。

我在这里缺少什么?谢谢

顺便说一句,我在 KitKat 和 Lollipop 上进行了测试。

【问题讨论】:

    标签: android android-intentservice


    【解决方案1】:

    问题是您尝试使用PendingIntent 开始您的Service 进行广播。您需要让闹钟向另一个BroadcastReceiver 发送广播,因为您希望唤醒设备,然后让该接收器启动您的Service。您可能还需要配合唤醒锁来确保设备保持足够长的唤醒时间。

    【讨论】:

    • 我已尝试将其更改为 AlarmManager.RTC 但问题仍然存在...顺便说一句,对于迟到的回复感到抱歉,因为几天前我的意图服务开始工作了。我所做的是,我只是重新排列了我的 AndroidManifest.xml 的内容。我以为我已经弄清楚了,但是昨天突然这个问题再次存在 - 警报管理器没有重复我的意图
    【解决方案2】:

    您将获得第一个“IntentService 已启动!”因为您从 BootReceiver 显式调用 startService(),但您的警报管理器设置为在 10 分钟后触发,而不是在第一次发生的 1 分钟后触发,因为您这样做了:

    Calendar cal1 = Calendar.getInstance();
    cal1.add(Calendar.SECOND, 600);
    service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, pending1);
    

    即您正在将 600 秒(10 分钟)添加到当前时间,并将其用于 AlarmManager 应首次触发的时间。我不只是将您添加的时间从 600 秒更改为 60 秒,而是更改BroadcastReceiver,这样我就无需调用startService() 并设置第一次调用,而是将当前时间(以毫秒为单位)传递给AlarmManager.setInexactRepeating() 用于 triggerAtMillis 时间,以便立即触发,然后以 60 秒的间隔触发 - 即将 onReceive() 方法更改为:

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v(FILE_NAME, "in onReceive");
        AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    
        Intent service1 = new Intent(context, ISCheckExpenses.class);
        Log.v(FILE_NAME, "starting service1");
        context.startService(service1);
    
        PendingIntent pending1 = PendingIntent.getBroadcast(context, 0, service1, PendingIntent.FLAG_UPDATE_CURRENT);
        service.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, pending1);
    }
    

    您还应该记住,当您使用 setInexactRepeating() 时,警报最多可能会延迟 60 秒,如文档中所述。

    【讨论】:

    • 对不起,这仍然不能解决我的问题。顺便说一句,很抱歉回复晚了,因为几天前我的意向服务开始工作了。我所做的是,我只是重新排列了我的 AndroidManifest.xml 的内容。我以为我已经弄清楚了,但是昨天突然这个问题再次存在 - 警报管理器没有重复我的意图
    【解决方案3】:

    我的错误是我误解了 BroadcastReceiver 和 AlarmManager 应该可以工作。我不应该像上面那样在 onReceive 中执行 AlarmManager,而是应该创建另一个函数,它调用 new Intent 并将调用活动作为 Context 传递,并将 BroadcastReceiver 作为类传递。

    这就是我工作的 BroadcastReceiver 的样子:

    public class BootBroadcast extends BroadcastReceiver {
    
        //private static final long REPEAT_TIME_TO_CHECK_EXPENSES = 1000 * 30;
        //private static final long REPEAT_TIME_TO_ANALYZE_LOCATION = 1000 * 30;
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            int what = intent.getIntExtra("what",0);
    
            if (what == 1) {
                Intent intentService1 = new Intent(context, ISCheckRecurringItemsAndCC.class);
                context.startService(intentService1);
            }else if (what == 2) {
                Intent service2 = new Intent(context, ISCheckLocationAndRating.class);
                context.startService(service2);
            }else{
                //should only reach here when the device boots
                Intent intentService1 = new Intent(context, ISCheckRecurringItemsAndCC.class);
                context.startService(intentService1);
    
                Intent service2 = new Intent(context, ISCheckLocationAndRating.class);
                context.startService(service2);
            }
        }
    
        public void setAlarm(Context context){
            Log.v(FILE_NAME,"inside setAlarm");
            AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    
            Intent myIntent = new Intent(context, BootBroadcast.class);
            myIntent.putExtra("what", 1);
            PendingIntent myPendingIntent = PendingIntent.getBroadcast(context, 111, myIntent, 0);
            am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), REPEAT_TIME_TO_CHECK_EXPENSES, myPendingIntent);
    
            myIntent = new Intent(context, BootBroadcast.class);
            myIntent.putExtra("what", 2);
            myPendingIntent = PendingIntent.getBroadcast(context, 222, myIntent, 0);
            am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), REPEAT_TIME_TO_ANALYZE_LOCATION, myPendingIntent);
    
        }
    }
    

    上面的代码现在非常适合我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多