android service实现循环定时提醒功能

人每天都要喝8杯水才能保持健康,于是苦逼的程序员总是一遍代码就忘了时间,于是我突发奇想能不能开发一个apk能够实现固定的间隔时间定时提醒我要喝水了呢?

apk基本功能:

1)能够设置间隔时间 2)在apk应用被停止的情况下仍然能定时提醒 3)能够播放指定闹铃 4)能够及时终止提醒

效果图:

设置间隔

时间到后会跳出全局AlertDialog提示并且开始播放闹铃

即使APP被终止了,仍然能够提示

结束提示

废话不多说,直接上代码:

布局layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="bai.cslg.servicebestpractice.MainActivity"
  android:baselineAligned="false"
  android:orientation="vertical">

  <LinearLayout
    android:paddingTop="20dp"
    android:layout_width="match_parent"
    android:layout_height="70dp">
    <TextView
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="5"
      android:padding="10dp"
      android:gravity="center_vertical"
      android:text="请设置提示时间间隔:"
      android:textSize="20sp"/>
    <EditText
      android:id="@+id/time"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"/>
    <TextView
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="2"
      android:gravity="center_vertical"
      android:text="分"
      android:textSize="20sp"/>
  </LinearLayout>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
  <Button
    android:id="@+id/start_serice"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="开启"/>
    <Button
      android:id="@+id/stop_serice"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:text="结束"/>
  </LinearLayout>
</LinearLayout>

MainActivity代码:

/*
*因为要服务常驻后台,就不需要BindService,直接StartService即可
*/
package bai.cslg.servicebestpractice;

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

  private Context mContext = MainActivity.this;

  private Button startService;
  private Button stopService;
  private EditText time;

  public static int TIME; //记录时间间隔

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startService = (Button) findViewById(R.id.start_serice);
    stopService = (Button) findViewById(R.id.stop_serice);
    time = (EditText) findViewById(R.id.time);

    startService.setOnClickListener(this);
    stopService.setOnClickListener(this);

  }

  @Override
  public void onClick(View view) {
    switch (view.getId()){
      case R.id.start_serice:
        Intent startIntent = new Intent(this,LongRunningService.class);
        TIME = Integer.parseInt(time.getText().toString().trim());
        //通过Intent将时间间隔传递给Service
        startIntent.putExtra("Time",TIME);
        Toast.makeText(MainActivity.this,"开始提醒",Toast.LENGTH_SHORT).show();
        startService(startIntent);
        break;
      case R.id.stop_serice:
        Intent stopIntent = new Intent(this,LongRunningService.class);
        Toast.makeText(MainActivity.this,"结束提醒",Toast.LENGTH_SHORT).show();
        stopService(stopIntent);
        break;
    }
  }
}

Service代码:

package bai.cslg.servicebestpractice;

import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.WindowManager;

import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * Created by baiqihui on 2016/9/21.
 */
public class LongRunningService extends Service {

  public int anHour; //记录间隔时间

  public int number = 0; //记录alertdialog出现次数

  private MediaPlayer mediaPlayer = new MediaPlayer();

  AlarmManager manager;
  PendingIntent pi;

  private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      switch (msg.what){
        case 1:
          if (!mediaPlayer.isPlaying()){
            mediaPlayer.start();
          }
          AlertDialog.Builder builder = new AlertDialog.Builder(LongRunningService.this);
          builder.setTitle("提醒");
          builder.setMessage("该补水啦" + (number-1));
          builder.setCancelable(false);
          builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
              mediaPlayer.reset();
              initMediaPlayer();
            }
          });
          final AlertDialog dialog = builder.create();
          dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
          dialog.show();
      }
    }
  };

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

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

  }

  private void initMediaPlayer() {
    File file = new File("/storage/emulated/0/naoling","music.mp3");
    try {
      mediaPlayer.setDataSource(file.getPath());
      mediaPlayer.prepare();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    if (number!=0) {
      new Thread(new Runnable() {
        @Override
        public void run() {
          Log.e("bai", "executed at " + new Date().toString());
          mHandler.sendEmptyMessage(1);
        }
      }).start();
    }
    manager = (AlarmManager) getSystemService(ALARM_SERVICE);
    int time = intent.getIntExtra("Time",2);
    anHour = time*60*1000;
    Log.e("bai","Time:"+time+"anhour:"+anHour);
    long triggerAtTime = SystemClock.elapsedRealtime()+(anHour);
    Intent i = new Intent(this,AlarmReceiver.class);
    pi = PendingIntent.getBroadcast(this,0,i,0);
    manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pi);
    number++;
    return super.onStartCommand(intent, flags, startId);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    mediaPlayer.release();
    manager.cancel(pi);
  }
}

AlarmReceiver代码:

package bai.cslg.servicebestpractice;

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

/**
 * Created by baiqihui on 2016/9/21.
 */
public class AlarmReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
      Intent i = new Intent(context, LongRunningService.class);
      context.startService(i);
  }
}

1)在apk应用被停止的情况下仍然能定时提醒,这里采用startService即可实现,使service常驻内存,即使Activity被杀死,依旧可以执行。

2)间隔时间提醒。这里采用的是Android的Alarm机制。

Android中的定时任务一般有两种实现方式,一种是使用Java API里提供的Timer类,一种是使用Android的Alarm机制。这两种情况在多数情况下都能实现类似的效果,但Timer类有一个明显的短板,它并不太适用于那些需要长期在后台运行的定时任务。我们都知道,为了能让电池更耐用,每种手机都会有自己的休眠策略,Android手机就会在长时间不操作的情况下自动让CPU进入到睡眠状态,这就有可能导致Timer中的定时任务无法正常运行。而Alarm机制则不存在这种情况,它具有唤醒CPU的功能,即可以保证每次需要执行定时任务的时候CPU都能正常工作。需要注意,这里唤醒CPU和唤醒屏幕完全不是一个概念。

从Service代码中可以看出,onCreate()中完成对mediaPlayer的初始化(因为mediaPlayer只需要初始化一次),在onStartCommand()中开启一个新的线程,线程中通过handler发送一条空的消息,并且在handler的handleMessage()方法中完成AlertDialog的创建以及播放闹铃,要注意这里创建的是一个全局的AlertDialog。因为第一次开启任务的时候不需要新建一个AlertDialog(用户第一次开启任务的时候是设置好时间并且点击了“开启”,这个时候不需要创建Dialog)。

在onStartCommand()还执行了AlarmManager的初始化以及时间的设定,因为AlarmManager中第三个参数PendingIntent能够执行一个广播,所以还需要写一个广播接收者。

AlarmManager的取消:manager.cancel(PendingIntent pi);取消对应PendingIntent即可。

AlarmReceiver:这就很简单了,接收到广播之后开启再开启服务即可。这就详单与是一个死循环,服务开启后会定时发送广播,广播接收到之后又会开启服务。

因为时间有限,所以代码肯定有很多不完善之处,希望多多指教。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android编程使用Service实现Notification定时发送功能示例
  • Android闹钟机制实现定时任务功能
  • android用闹钟定时做http请求推送的解决方案
(0)

相关推荐

  • Android编程使用Service实现Notification定时发送功能示例

    本文实例讲述了Android编程使用Service实现Notification定时发送功能.分享给大家供大家参考,具体如下: /** * 通过启动或停止服务来管理通知功能 * * @description: * @author ldm * @date 2016-4-29 上午9:15:15 */ public class NotifyControlActivity extends Activity { private Button notifyStart;// 启动通知服务 private Bu

  • android用闹钟定时做http请求推送的解决方案

    设计思路 如果在开发当中需要做push接入,而产品又要求不允许用第三方sdk(百度push,友盟push),而且又没有网络编程的经验,这个时候怎么办?这里就给大家分享下用http请求解决这个问题. 大体的设计思路是,写一个service(为了保证长时间运行不被kill,就将其定义到另外的进程当中去),在这个service里面启动闹钟,每隔一段时间(这个时间可以自己定义)去请求服务器,如果有新的push消息,就通知给用户. 具体实现 貌似很简单定义一个闹钟不断轮循请求服务器一句话,却在实际开发中要

  • Android闹钟机制实现定时任务功能

    Android的闹钟实现机制, 需要调用AlarmManager.set()将闹铃时间记录到系统中,当闹铃时间到后,系统会给应用程序发送广播,我们只需要去注册广播接收器就可以了. 本文分三部分讲解如何实现闹钟: 目录: 1. 设置闹铃时间; 2. 接收闹铃事件广播; 3. 重开机后重新计算并设置闹铃时间; 1. 设置闹铃时间(毫秒) private void setAlarmTime(Context context, long triggerAtMillis) { AlarmManager am

  • android service实现循环定时提醒功能

    人每天都要喝8杯水才能保持健康,于是苦逼的程序员总是一遍代码就忘了时间,于是我突发奇想能不能开发一个apk能够实现固定的间隔时间定时提醒我要喝水了呢? apk基本功能: 1)能够设置间隔时间 2)在apk应用被停止的情况下仍然能定时提醒 3)能够播放指定闹铃 4)能够及时终止提醒 效果图: 设置间隔 时间到后会跳出全局AlertDialog提示并且开始播放闹铃 即使APP被终止了,仍然能够提示 结束提示 废话不多说,直接上代码: 布局layout: <?xml version="1.0&q

  • Android后台定时提醒功能实现

    前提:考虑到自己每次在敲代码或者打游戏的时候总是会不注意时间,一不留神就对着电脑连续3个小时以上,对眼睛的伤害还是挺大的,重度近视了可是会遗传给将来的孩子的呀,可能老婆都跟别人跑了. 于是,为了保护眼睛,便做了个如下的应用: 打开后效果: 时间到之后有后台提醒: 好了,接下来说一下做这样一个APP主要涉及到的知识点: Service:使用service,便可以在程序即使后台运行的时候,也能够做出相应的提醒,并且不影响手机进行其他工作. AlarmManager:此知识点主要是用来计时,具体的在代

  • Android基于广播事件机制实现简单定时提醒功能代码

    本文实例讲述了Android基于广播事件机制实现简单定时提醒功能代码.分享给大家供大家参考,具体如下: 1.Android广播事件机制 Android的广播事件处理类似于普通的事件处理.不同之处在于,后者是靠点击按钮这样的组件行为来触发,而前者是通过构建Intent对象,使用sentBroadcast()方法来发起一个系统级别的事件广播来传递信息.广播事件的接收是通过定义一个继承Broadcast Receiver的类实现的,继承该类后覆盖其onReceive()方法,在该方法中响应事件.And

  • Android实现每天定时提醒功能

    这个是设置定时提醒的功能,即设置几点几分后提醒,用的是给系统设置个时间点,当系统时间到达设置的时间点的时候就会给我们发送一个广播,然后达到时间提醒功能 网上找了很多,遇到了很多坑,经过摸索出来的,比如下面设置重复时间的第二个参数,网上有很多说是执行提醒延时多少毫秒执行,我用的刷了MIUI的三星手机测试怎么都不对,经过摸索测试才发现,原来不是,原来那个参数是设定的时间点的毫秒值!好了,不多说,看代码: /** * 开启提醒 */ private void startRemind(){ //得到日历

  • Android自定义相机实现定时拍照功能

    这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能. 首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件: activity_main.xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="m

  • Android中AlarmManager+Notification实现定时通知提醒功能

    AlarmManager简介 AlarmManager实质是一个全局的定时器,是Android中常用的一种系统级别的提示服务,在指定时间或周期性启动其它组件(包括Activity,Service,BroadcastReceiver).本文将讲解一下如何使用AlarmManager实现定时提醒功能. 闹钟配置 周期闹钟 Intent intent = new Intent(); intent.setAction(GlobalValues.TIMER_ACTION_REPEATING); Pendi

  • Android编程实现添加低电流提醒功能的方法

    本文实例讲述了Android编程实现添加低电流提醒功能的方法.分享给大家供大家参考,具体如下: 特殊需求,检测电流是否正常. 监听如下广播: Intent.ACTION_BATTERY_CHANGED plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); if(mLowElectricityRemind == null){ mLowElectricityRemind = new LowElectricityRemind(B

  • Android Service服务详细介绍及使用总结

    Android Service服务详解 一.Service简介 Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver. ContentProvider),它跟Activity的级别差不多,但不能页面显示只能后台运行,并且可以和其他组件进行交互.service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变

  • 用python写一个定时提醒程序的实现代码

    身体是革命的本钱,身体健康了我们才有更多精力做自己想做的事情,追求女神,追求梦想.然而程序员是一个苦比的职业,大部分时间都对着电脑,我现在颈椎就不好了,有时候眼睛还疼,我还没20阿,伤心...于是乎写了一个小程序,指定时间会打开浏览器播放一段音乐,提醒我们休息一会儿,防止我们猝死,说多了都是泪. 较基础,适合python新手及对python感兴趣的同学阅读. 我们来理一遍这个程序,大概功能是:我们设置一个时间,时间到了以后会打开浏览器播放一段音频. 1.等待 2.打开浏览器,播放音频. 3.重复

随机推荐