【问题标题】:How to call Service with dynamic intervals如何以动态间隔调用服务
【发布时间】:2013-11-08 10:34:50
【问题描述】:

嗨,在我的应用程序中,我使用后台服务和警报管理器执行具有动态间隔的 webview。Webview 将以指定的时间间隔打开。如果在启动服务后用户可以更改间隔时间(第一次时间间隔不同),我想要将此时间间隔更新到警报管理器中。

在这里,我正在尝试什么

private void loadWebview() {
    try {
        loadPrefValues();

        Calendar cur_cal = Calendar.getInstance();
        cur_cal.setTimeInMillis(System.currentTimeMillis());
        Intent webViewIntent = new Intent(MyService.this, XorWebView.class);
        webViewIntent.putExtra("url", mStr);
        webViewIntent.putExtra("duration", mDurationStr);
        webViewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        pintent = PendingIntent.getActivity(MyService.this, 0,
                webViewIntent, 0);

        alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        if (mIntervalStr.equals("1 minute")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 1 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("2 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 2 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("5 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 5 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("10 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 10 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("30 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 30 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("60 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 60 * 60 * 1000, pintent);
        }
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }

    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    System.out.println("Service.onStart()" + "Url:" + mStr
            + "Send to WebActivity");
}

这个方法只会在第一次指定的时间间隔执行。我的代码有什么问题?

编辑#1

在 MainActivity 中,我使用开/关开关按钮和列表视图进行间隔。在列表视图中,我放置了 1、5、10、20、30、60 分钟。用户可以在列表视图中以及何时切换 isChecked()我在这里开始服务。

在这个服务类中,我使用 Alarmmanager 调用间隔。

当用户更改主要活动的间隔时,我想要确切的内容,该间隔将在警报管理器中更新。

我的服务类

public class MyService extends Service {

BroadcastReceiver mReceiver = null;
String mStr, mIntervalStr, mDurationStr;
PendingIntent pintent;
AlarmManager alarm;

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();

    Toast.makeText(MyService.this, "Service Created", Toast.LENGTH_SHORT)
            .show();
    System.out.println("Service.onCreate()");

}

@Override
@Deprecated
public void onStart(Intent intent, int startId) {
    // TODO Auto-generated method stub
    super.onStart(intent, startId);

    Toast.makeText(MyService.this, "Service started", Toast.LENGTH_SHORT)
            .show();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    // Let it continue running until it is stopped.
    try {
        loadWebview();
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }
    Toast.makeText(MyService.this, "Service command started",
            Toast.LENGTH_SHORT).show();
    return START_STICKY;
}


private void loadWebview() {
    try {
        loadPrefValues();

        Calendar cur_cal = Calendar.getInstance();
        cur_cal.setTimeInMillis(System.currentTimeMillis());
        Intent webViewIntent = new Intent(MyService.this, XorWebView.class);
        webViewIntent.putExtra("url", mStr);
        webViewIntent.putExtra("duration", mDurationStr);
        webViewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        pintent = PendingIntent.getActivity(MyService.this, 0,
                webViewIntent, 0);

        alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarm.cancel(pintent);
        if (mIntervalStr.equals("1 minute")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,cur_cal.getTimeInMillis(),
                    1 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("2 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 2 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("5 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 5 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("10 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 10 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("30 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 30 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("60 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 60 * 60 * 1000, pintent);
        }
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }

    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    System.out.println("Service.onStart()" + "Url:" + mStr
            + "Send to WebActivity");
}

private void loadPrefValues() {
    SharedPrefManager.Init(MyService.this);
    SharedPrefManager.LoadFromPref();
    String s1 = SharedPrefManager.getsUrl().toString();
    String s2 = SharedPrefManager.getsInterval().toString();
    String s3 = SharedPrefManager.getsDuration().toString();

    mStr = s1;
    mIntervalStr = s2;
    mDurationStr = s3;


}


@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    if (mReceiver != null)
        unregisterReceiver(mReceiver);
    alarm.cancel(pintent);
    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
    System.out.println("Service.onDestroy()");
}

}

【问题讨论】:

  • 复制并粘贴您的 AlarmManager 代码(来自 loadWebView() 函数)到您的活动中,当您可以从您的活动中更新您的 alarmManager 时,为什么要从您的服务类更新它????
  • 从您的活动中更新您的时间间隔,无需从服务中更改它。
  • 因为,我想在后台运行此服务(如果我的应用程序将关闭(或)重新启动我想运行此服务)。所以,这就是我想将其更新为服务类的原因。如何我可以在主要活动中更新它,请给我发送解决方案。
  • 看,当用户从列表视图中选择值时,您将更新它;这意味着,AlarmManager 只会在您的应用程序可见时更新。即使应用关闭,AlarmManager 也会继续工作,不用担心。
  • 重启后会在不打开应用的情况下每隔一段时间运行一次

标签: android service alarmmanager


【解决方案1】:

你应该先取消之前的pendingIntent,然后再设置新的。

在此行之后的代码中。

alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

alarm.cancel(pintent);

【讨论】:

  • 是的,我添加了上述行但是,该警报将在第一次选择间隔时触发。
  • 正是我不会:当第二次警报管理器调用时,我想在 alarm.setRepeting() 执行之前执行 loadwebview()。我如何调用 loadWebview()..
  • 你在哪里收听报警广播????您可以从广播侦听器调用您的方法,例如 loadWebview()!您的要求不明确。
  • 请检查我的编辑问题
【解决方案2】:

以下事情正在发生。

->从您的活动中更新 alarmManager。 -> 将当前时间间隔保存在首选项中以供将来使用。 -> 实现重启广播接收器,当设备重启时它会调用。 ->在重启功能中设置alarmManager。使用保存在首选项中的时间间隔。

将此代码复制到您的活动中。

       listview.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> arg0, View v, int position,
                            long id) {
                        loadWebView(user's new selected minutes);
                    }
});

这里是设置AlarmManager的代码

     private void loadWebview(String minutes) {
    try {
        loadPrefValues();



        saveCurrentTimeInterval(minutes);




        Calendar cur_cal = Calendar.getInstance();
        cur_cal.setTimeInMillis(System.currentTimeMillis());
        Intent webViewIntent = new Intent(MyService.this, XorWebView.class);
        webViewIntent.putExtra("url", mStr);
        webViewIntent.putExtra("duration", mDurationStr);
        webViewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        pintent = PendingIntent.getActivity(MyService.this, 0,
                webViewIntent, 0);

        alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        if (minutes.equals("1 minute")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 1 * 60 * 1000, pintent);
        }
        if (minutes.equals("2 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 2 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("5 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 5 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("10 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 10 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("30 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 30 * 60 * 1000, pintent);
        }
        if (mIntervalStr.equals("60 minutes")) {
            alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                    cur_cal.getTimeInMillis(), 60 * 60 * 1000, pintent);
        }
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }

}

private void saveCurrentTimeInterval(String minute) { SharedPreferences pref = getSharedPreferences("time", Context.MODE_PRIVATE); SharedPreferences.Editor 编辑器 = pref.edit(); eidtor.putString("间隔", 分钟); editor.commit(); }

现在重新启动监听器

import android.content.BroadcastReceiver;  
import android.content.Context;  
import android.content.Intent;    

public class BootCompleteReceiver extends BroadcastReceiver {   

    @Override  
    public void onReceive(Context context, Intent intent) {  

        SharedPreferences pref = context.getSharedPreferences("time", Context.MODE_PRIVATE);
        setAlarmManager(pref.getString("interval", ""));   

    }  

    private void setAlarmManager(String minutes) {
        try {
            loadPrefValues();

            Calendar cur_cal = Calendar.getInstance();
            cur_cal.setTimeInMillis(System.currentTimeMillis());
            Intent webViewIntent = new Intent(MyService.this, XorWebView.class);
            webViewIntent.putExtra("url", mStr);
            webViewIntent.putExtra("duration", mDurationStr);
            webViewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            pintent = PendingIntent.getActivity(MyService.this, 0,
                    webViewIntent, 0);

            alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            if (minutes.equals("1 minute")) {
                alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                        cur_cal.getTimeInMillis(), 1 * 60 * 1000, pintent);
            }
            if (minutes.equals("2 minutes")) {
                alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                        cur_cal.getTimeInMillis(), 2 * 60 * 1000, pintent);
            }
            if (mIntervalStr.equals("5 minutes")) {
                alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                        cur_cal.getTimeInMillis(), 5 * 60 * 1000, pintent);
            }
            if (mIntervalStr.equals("10 minutes")) {
                alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                        cur_cal.getTimeInMillis(), 10 * 60 * 1000, pintent);
            }
            if (mIntervalStr.equals("30 minutes")) {
                alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                        cur_cal.getTimeInMillis(), 30 * 60 * 1000, pintent);
            }
            if (mIntervalStr.equals("60 minutes")) {
                alarm.setRepeating(AlarmManager.RTC_WAKEUP,
                        cur_cal.getTimeInMillis(), 60 * 60 * 1000, pintent);
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }

}

在你的 xml 中。

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

【讨论】:

  • 也在你的清单中添加这个权限。
  • 我试过上面的代码它会调用服务但是,重启后警报不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
相关资源
最近更新 更多