首页 \ 问答 \ 使用sharedPreferenceChange中的pendingIntent重新计划不准确的重复警报(Reschedule inexactRepeating alarm with pendingIntent from sharedPreferenceChange)

使用sharedPreferenceChange中的pendingIntent重新计划不准确的重复警报(Reschedule inexactRepeating alarm with pendingIntent from sharedPreferenceChange)

我正在开发一个测试应用程序来学习Android,我需要定期启动服务来更新一些数据。 我正在使用带有BroadcastReceiverAlarmManager来设置警报,并且它使用默认间隔成功更新数据,但我希望将此间隔作为用户定义的值。
我目前有以下代码来注册警报:

在清单中:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".BootReceiver">
    <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

收件人:

public class BootReceiver extends BroadcastReceiver {
    private static final String TAG = BootReceiver.class.getSimpleName();

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG,"onReceive method");
        AlarmCreator.setAlarm(context, intent);

    }
}

实际报警:

public static void setAlarm(Context context, Intent intent){
    Log.d(TAG, "Setting alarm");
    // I need the context here
    context.startService(new Intent(context, RefreshService.class));

    SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(context);
    long interval = Long.parseLong(prefs.getString("interval",
            Long.toString(DEFAULT_INTERVAL)));
    // Here
    PendingIntent operation = PendingIntent.getService(context, -1,
            new Intent(context, RefreshService.class),
            PendingIntent.FLAG_UPDATE_CURRENT);

    // And here
    AlarmManager alarmManager = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);

    if (interval == 0) {
        alarmManager.cancel(operation);
        Log.d(TAG, "Cancelling alarm");
    } else {
        alarmManager.setInexactRepeating(AlarmManager.RTC,
                System.currentTimeMillis(), interval, operation);
        Log.d(TAG, "Setting alarm with interval: " + interval);
    }
}


我试过的

我知道使用onSharedPreferenceChanged我可以在更新首选项时执行代码,问题是为了设置警报,我需要有一个Preference类没有提供的Context 。 我知道getActivity().getApplicationContext()的问题是它们可以返回null,具体取决于Preference活动的生命周期。

public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener{
    private SharedPreferences prefs;
    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
    }

    @Override
    public void onStart() {
        super.onStart();
        prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        prefs.registerOnSharedPreferenceChangeListener(this);
    }
    @Override
    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        if (key.equals("interval")){
                // Since I'm not using the intent I can just simply pass null.
                AlarmCreator.setAlarm(??,null);
            }

    }

}

这个问题

我应该将什么传递给AlarmCreator.setAlarm(Content,intent)以便正确取消或更新警报? 它甚至可能吗? 也许有一种我错过的更好的方法。

附加信息

我刚刚开始学习Android开发,但我花了很多时间阅读文档,而我却无法弄清楚如何去做。 有一个类似的问题有助于我走上正轨,但我发现答案对我目前的理解来说太模糊了。

任何想法,将不胜感激。
干杯。


I'm developing a test app to learn Android in which I need to fire up a service periodically to update some data. I'm using the AlarmManager with a BroadcastReceiver to set the alarm and it successfully updates the data with the default interval but I'd like to have this interval as a user defined value.
I currently have the following code to register the alarm:

In the manifest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".BootReceiver">
    <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

The receiver:

public class BootReceiver extends BroadcastReceiver {
    private static final String TAG = BootReceiver.class.getSimpleName();

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG,"onReceive method");
        AlarmCreator.setAlarm(context, intent);

    }
}

The actual alarm:

public static void setAlarm(Context context, Intent intent){
    Log.d(TAG, "Setting alarm");
    // I need the context here
    context.startService(new Intent(context, RefreshService.class));

    SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(context);
    long interval = Long.parseLong(prefs.getString("interval",
            Long.toString(DEFAULT_INTERVAL)));
    // Here
    PendingIntent operation = PendingIntent.getService(context, -1,
            new Intent(context, RefreshService.class),
            PendingIntent.FLAG_UPDATE_CURRENT);

    // And here
    AlarmManager alarmManager = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);

    if (interval == 0) {
        alarmManager.cancel(operation);
        Log.d(TAG, "Cancelling alarm");
    } else {
        alarmManager.setInexactRepeating(AlarmManager.RTC,
                System.currentTimeMillis(), interval, operation);
        Log.d(TAG, "Setting alarm with interval: " + interval);
    }
}


What I've tried

I know that using the onSharedPreferenceChanged I can execute code when a preference is updated, the problem is that in order to set the alarm I need to have a Context which the Preference class doesn't provide. I am aware of getActivity().getApplicationContext() the problem is that they can return null depending on the life cycle of the Preference activity.

public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener{
    private SharedPreferences prefs;
    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
    }

    @Override
    public void onStart() {
        super.onStart();
        prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        prefs.registerOnSharedPreferenceChangeListener(this);
    }
    @Override
    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        if (key.equals("interval")){
                // Since I'm not using the intent I can just simply pass null.
                AlarmCreator.setAlarm(??,null);
            }

    }

}

The question

What should I pass to AlarmCreator.setAlarm(Content,intent) so that the alarm gets correctly canceled or updated? Is it even possible? Maybe there's a better approach that I'm missing.

Additional info

I just started learning Android development but I've spent a good amount of time reading the documentation and I just couldn't figure out how to do it. There was a similar question which helped to get me on track but I found the answer too vague for my understanding at the moment.

Any Ideas would be appreciated.
Cheers.


原文:https://stackoverflow.com/questions/24406899
更新时间:2022-11-22 22:11

相关问答

更多

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。