安卓【AlarmManager】实现周期性定时执行某项任务(每15分钟监听手机接收到的短信数量)- 轮询
程序员文章站
2022-03-10 23:42:45
引言:AlarmManager,Timer都可以实现安卓中的定时任务。但是对于一些后台任务,往往需要在cpu处于非唤醒状态时执行。使用AlarmManager结合BroadCastReceiver以及Service就能实现轮询效果。分析:在我这个demo里面,我将实现一个 “每15分钟监听手机接收到的短信数量” 的程序。当这段时间内接收的短信数量>我们设置的阈值,将会提示当前接收的短信数量,并开始下一次监听。手机收到短信时,系统会发送一条广播,我们可以定义接收器捕捉这个广播。为了程序能够后台运行...
引言:
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;
@Override
protected 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();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);//解绑广播接收器
}
@Override
public 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;
}
@Override
public 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; //用于实现定时功能
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public 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"/>
<application
android: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>
本文地址:https://blog.csdn.net/tran_sient/article/details/108143007
下一篇: 茶叶蛋怎么存放