当前位置: 代码迷 >> 综合 >> 安卓【AlarmManager】实现周期性定时执行某项任务(每15分钟监听手机接收到的短信数量)- 轮询
  详细解决方案

安卓【AlarmManager】实现周期性定时执行某项任务(每15分钟监听手机接收到的短信数量)- 轮询

热度:13   发布时间:2024-02-13 03:56:21.0

引言:
AlarmManager,Timer都可以实现安卓中的定时任务。但是对于一些后台任务,往往需要在cpu处于非唤醒状态时执行。使用AlarmManager结合BroadCastReceiver以及Service就能实现轮询效果。

分析:
在我这个demo里面,我将实现一个 “每15分钟监听手机接收到的短信数量” 的程序。当这段时间内接收的短信数量>我们设置的阈值,将会提示当前接收的短信数量,并开始下一次监听。手机收到短信时,系统会发送一条广播,我们可以定义接收器捕捉这个广播。为了程序能够后台运行,我们还需要一个服务用来每15分钟对短信数量做出反应。
整个程序的构建可以用一张图来概括:
在这里插入图片描述
代码:
MainActivity.java

package com.example.smstest;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.widget.Toast;public class MainActivity extends AppCompatActivity {IntentFilter filter;MySmsReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//RECEIVE_SMS属于危险权限,需要动态申请judegeRequest();}private void registerBroadCast() {filter=new IntentFilter();filter.addAction("android.provider.Telephony.SMS_RECEIVED" ); //手机收到短信时响应filter.addAction("android.intent.handle.num"); //我们自定义的 用于处理短信数量的广播receiver=new MySmsReceiver();registerReceiver(receiver,filter);//动态注册广播接收器,防止静态失效startService(new Intent(this,MyService.class)); //启动服务以进行计时}private void judegeRequest() {//6.0以上需要动态申请权限if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {requestPermissions(new String[]{Manifest.permission.RECEIVE_SMS},1);} else{registerBroadCast();}}else{registerBroadCast();}}@Overrideprotected  void onDestroy() {super.onDestroy();unregisterReceiver(receiver);//解绑广播接收器}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode){case 1:if (grantResults.length > 0 &&grantResults[0] == PackageManager.PERMISSION_GRANTED) {registerBroadCast();}break;}}
}

MySmsReceiver.java

package com.example.smstest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MySmsReceiver extends BroadcastReceiver {private int count;public MySmsReceiver() {super();count=0;}@Overridepublic void onReceive(Context context, Intent intent) {if(intent.getAction()==null) return;switch (intent.getAction()){case "android.intent.handle.num":handleNum(context);break;default:count++;break;}}private void handleNum(Context context) {//我们阈值为30条短信if(count>=30){Toast.makeText(context, "Detected excessive SMS activity: "+count+" messages", Toast.LENGTH_SHORT).show();}count=0;//重启服务以实现定时执行context.startService(new Intent(context,MyService.class));}
}

MyService.java

package com.example.smstest;import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
import android.widget.Toast;public class MyService extends Service {private String action="android.intent.handle.num";private static int MINUTE = 15*60000; //十五分钟 即15*60*1000毫秒private AlarmManager manager; //用于实现定时功能@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {manager=(AlarmManager) getSystemService(ALARM_SERVICE);long triggerAtTime = SystemClock.elapsedRealtime() + MINUTE;Intent intent1=new Intent(action);PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent1, 0);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);} else {manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);}return super.onStartCommand(intent, flags, startId);}}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.smstest"><uses-permission android:name="android.permission.RECEIVE_SMS"/><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><receiver android:name=".MySmsReceiver"><intent-filter android:priority="1000"><action android:name="android.provider.Telephony.SMS_RECEIVED"/><action android:name="android.intent.handle.num"/></intent-filter></receiver><service android:name=".MyService"></service></application></manifest>