每隔5分钟启动安卓服务

17

我在过去的两天里在互联网上搜索,但没有找到任何有用的教程。我创建了一个服务,并在服务启动时向状态栏发送通知。我希望在显示通知后停止该服务,并在5分钟后重新启动它。如果可能的话,请告诉我并提供一些有用的教程。我听说过 TimerTaskAlarmManager,我也尝试使用它们,但是未能获得所需的结果。

编辑:即使我的应用程序没有运行,我也需要每5分钟启动服务。

3个回答

25

使用 TimerTask 并不可行,因为它需要你的应用程序持续运行。使用 AlarmManager 实现可以确保在执行之间应用程序被杀死也是安全的。

仅仅说尝试使用 AlarmManager 但未获得预期结果并没有帮助,因为这并没有告诉任何人如何帮助你成功。更有用的是表达实际发生了什么。

http://web.archive.org/web/20170713001201/http://code4reference.com/2012/07/tutorial-on-android-alarmmanager/ 包含了一篇关于 AlarmManager 的教程,看起来很有用。以下是重点:

1)闹钟到期时将会触发一个 Intent ,你需要自己决定生成哪种类型的 Intent 以及如何实现。提供的链接中有一个基于 BroadcastReceiver 的完整示例。

2)你可以用类似以下的示例来安装你的闹钟:

public void setOnetimeTimer(Context context) {
    AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
    intent.putExtra(ONE_TIME, Boolean.TRUE);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
    am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000 * 60 * 5), pi);
}

2
很好的方法,确实。你应该这样使用AlarmManager;Calendar wakeUpTime = Calendar.getInstance(); wakeUpTime.add(Calendar.SECOND, seconds); AlarmManager aMgr = (AlarmManager) getSystemService(ALARM_SERVICE); aMgr.set(AlarmManager.RTC_WAKEUP, wakeUpTime.getTimeInMillis(), pendingIntent); - Alpay
1
我曾经使用AlarmManager来实现同样的目的。我在AlarmManager中设置了2分钟。但是AlarmManager会随机触发。我认为这不是使用AlarmManager每2分钟调用的最佳方式。 - kels
http://code4reference.com/2012/07/tutorial-on-android-alarmmanager/无法工作。 - Ravi Yadav
@mah,我能否在应用程序进入后台时每5秒钟发送一次位置信息吗?我的应用程序在后台停止发送位置信息10分钟后,我正在使用计时器。 - Farhana Naaz Ansari
这很好,但用户说他必须每五分钟运行一次,因此使用AlarmManager.setRepeating(...)可能更好。在此添加文档: https://developer.android.com/reference/android/app/AlarmManager#setRepeating(int,%20long,%20long,%20android.app.PendingIntent) - shaked428

15

下面我提供了三个文件,MainActivity.java是启动服务的文件,第二个文件MyService.java提供5分钟的服务,第三个文件是清单文件。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService(new Intent(this, MyService.class)); //start service which is MyService.java
    }
}

MyService.java

 public class MyService extends Service {

    public static final int notify = 300000;  //interval between two services(Here Service run every 5 Minute)
    private Handler mHandler = new Handler();   //run on another Thread to avoid crash
    private Timer mTimer = null;    //timer handling

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        if (mTimer != null) // Cancel if already existed
            mTimer.cancel();
        else
            mTimer = new Timer();   //recreate new
        mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify);   //Schedule task
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mTimer.cancel();    //For Cancel Timer
        Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show();
    }

    //class TimeDisplay for handling task
    class TimeDisplay extends TimerTask {
        @Override
        public void run() {
            // run on another thread
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // display toast
                    Toast.makeText(MyService.this, "Service is running", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}

AndroidManifest.xml

  <service android:name=".MyService" android:enabled="true" android:exported="true"></service>

2
当服务完成后,我想在五分钟内再次执行服务而不需要用户输入怎么办? - Kashif Umair Liaqat
@KULKING,我也想知道同样的问题,如果你找到任何解决方案,请告诉我。 - Ronak Shethia
@Khyati Fatania 当应用程序被杀死时会发生什么? 目前,此代码正在应用程序的前台和后台运行。 - Hardik Parmar

-4
创建一个 Timer 对象,并给它一个 TimerTask,执行你想要执行的代码。
Timer timer = new Timer ();
TimerTask hourlyTask = new TimerTask () {
    @Override
    public void run () {
        // your code here...
    }
};

// schedule the task to run starting now and then every hour...
timer.schedule (hourlyTask, 0l, 1000*60*60);   // 1000*10*60 every 10 minut

使用Timer对象的优点在于它可以处理多个TimerTask对象,每个对象都有自己的定时、延迟等。只要将Timer对象声明为类变量或其他形式并持有它,您还可以启动和停止计时器。

10
被踩了;使用计时器绝对是一个糟糕的解决方案,因为Android可以终止应用程序,如果你正在使用计时器或TimerTask,它无法处理。这不是“可工作的代码”,而是“仅在理想条件下可工作的代码”。 - mah
2
同意@mah的观点,我也看到一些评论反对在某些问题上使用定时器。顺便说一句,我赞赏Nirav Ranpara的参与。你能提供一个使用AlarmManager的解决方案吗? - Kashif Umair Liaqat
1
非常抱歉提到,我希望这项服务每隔5分钟启动一次,即使我的应用程序没有运行。我也已经编辑了问题。 - Kashif Umair Liaqat
@mah:好的。请问你能告诉我如何做吗? - Nirav Ranpara
@NiravRanpara 请查看我的答案,以及链接到更多详细信息的教程。请注意,谷歌搜索“alarmmanager教程”将找到几个其他教程,我只选择了第一个列出的教程。 - mah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接