如何在运营商月度通话/短信额度耗尽时拦截呼出电话与短信?
解决方案推荐与自定义实现思路
一、第三方应用选项
- My Data Manager & Security:支持设置通话、短信、数据的月度额度与结算日期,超额度后可配置无通知强制拦截(仅触发限制开关),核心聚焦用量管控,无家长控制类冗余功能。
- Data Monitor & Manager:兼容三类用量的额度设置,超量后自动禁用对应服务,支持自定义结算周期,操作简洁直接。
二、自定义开发实现(Android平台)
如果现有应用无法完全匹配需求,可基于Android原生API自行实现,核心逻辑对应你的伪代码:
核心代码片段
// 监听通话状态,统计时长 TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); long callStartTime = 0; int minutesUsed = 0; telephonyManager.listen(new PhoneStateListener() { @Override public void onCallStateChanged(int state, String phoneNumber) { super.onCallStateChanged(state, phoneNumber); if (state == TelephonyManager.CALL_STATE_OFFHOOK) { callStartTime = System.currentTimeMillis(); } else if (state == TelephonyManager.CALL_STATE_IDLE && callStartTime != 0) { long callDuration = (System.currentTimeMillis() - callStartTime) / 60000; // 转换为分钟 minutesUsed += callDuration; checkUsageLimits(); } } }, PhoneStateListener.LISTEN_CALL_STATE); // 检查额度并执行限制 private void checkUsageLimits() { SharedPreferences prefs = getSharedPreferences("UsageControl", MODE_PRIVATE); int bundleMinutes = prefs.getInt("bundleMinutes", 0); boolean isMonthEnded = isSettlementDate(); // 自定义方法判断是否到结算日 if (isMonthEnded) { minutesUsed = 0; prefs.edit().putInt("minutesUsed", 0).apply(); enableCallingServices(); } else if (minutesUsed > bundleMinutes) { disableCallingServices(); } } // 禁用通话(需设备管理权限) private void disableCallingServices() { DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName adminReceiver = new ComponentName(this, MyDeviceAdminReceiver.class); if (dpm.isAdminActive(adminReceiver)) { dpm.setRestriction(adminReceiver, DevicePolicyManager.RESTRICTION_OUTGOING_CALLS, true); } } // 恢复通话 private void enableCallingServices() { DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName adminReceiver = new ComponentName(this, MyDeviceAdminReceiver.class); if (dpm.isAdminActive(adminReceiver)) { dpm.setRestriction(adminReceiver, DevicePolicyManager.RESTRICTION_OUTGOING_CALLS, false); } } // 判断是否到达结算日期 private boolean isSettlementDate() { SharedPreferences prefs = getSharedPreferences("UsageControl", MODE_PRIVATE); int settlementDay = prefs.getInt("settlementDay", 1); Calendar today = Calendar.getInstance(); return today.get(Calendar.DAY_OF_MONTH) == settlementDay; }
关键说明
- 需申请
READ_PHONE_STATE、DEVICE_ADMIN等权限 - 短信管控可通过监听
SMS_SENT广播统计发送数量,数据用量可通过ConnectivityManager或NetworkStatsManager获取 - 结算日期逻辑可根据用户设置的日期,每日自动校验并重置用量统计
三、无开发能力的替代方案
- 通话管控:利用系统设备管理器权限,使用简易设备管理工具(可找到现成的开源模板打包),配合日历提醒手动重置时长统计
- 数据与短信:结合系统自带数据限制器+第三方短信计数器应用,实现三类用量的分别管控
内容的提问来源于stack exchange,提问作者OzzyOsbourne
相关产品推荐
相关产品推荐

