项目场景:


智能车载机


问题描述:

车载机使用4G流量,但客户接入的是带通话功能的sim卡,客户测试过程中遇到有人拨号,来电音量不是静音情况下,居然通了。客户提出禁止来电功能。


原因分析:

尽管系统进行了裁剪,去掉了拨号和来电APP,但是来电等功能还是可以使用的,最后无人接通,系统通知栏出现了来电未接图标。


解决方案:

方案1,求助

系统开发人员在系统层修改代码,禁止来电及拨号功能,当然是行的通的,但是被告知不能及时修改,那么进行OTA升级可能要过段时间,可是应用马上到了发布日,就先自己想想办法了。当然如果你的小伙伴很给力,那么直接进行OTA升级就可以解决,应用层无需更改。

方案2,实现来电自动拒接

监听来电通知,在有电话进来的时候,拒接,注意:权限。

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />

实现方法(注意我这边因为有系统编译的SDK包,所以可以直接调用,没有的话,可通过反射实现)

反射实现参考点击我

private void  endCall(){
        AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
        TelephonyManager  tm = (TelephonyManager) getSystemService(Service.TELEPHONY_SERVICE);
        tm.listen(new PhoneStateListener(){

            @Override
            public void onCallStateChanged(int state, String phoneNumber) {
                super.onCallStateChanged(state, phoneNumber);
                Log.e("onCallStateChanged","state = "+state +"  phoneNumber = "+phoneNumber);
                if(state==TelephonyManager.CALL_STATE_RINGING){
                    am.setRingerMode(AudioManager.RINGER_MODE_SILENT);//设置为静音模式,解决延迟导致的响铃问题
                    tm.endCall();
                    am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);//恢复普通模式,恢复声音
                }
            }
        },PhoneStateListener.LISTEN_CALL_STATE);

    }

方案3,设置勿扰模式

通过设置勿扰模式策略,设置在一些场景下,忽略来电,短信,通知,闹铃等,此处参考android 7.0的源码,路径com.android.settings.notification.ZenModePrioritySettings。

还是那个前提,因为是定制系统,我有系统SDK的jar包,并且是系统签名的app,所以直接调用。

<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
public class ZenModePriorityUtils {



    public static void zenMode_switch(Context context,int categoryType,boolean allowed){
        NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        nm.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY);
        NotificationManager.Policy policy = nm.getNotificationPolicy();
        int priorityCategories = getNewPriorityCategories(policy,allowed,categoryType);
        NotificationManager.Policy newPolicy = new NotificationManager.Policy(priorityCategories, policy.priorityCallSenders, policy.priorityMessageSenders,
                policy.suppressedVisualEffects);
        NotificationManager.from(context).setNotificationPolicy(newPolicy);
    }


    private static boolean isPriorityCategoryEnabled(NotificationManager.Policy mPolicy,int categoryType) {
        return (mPolicy.priorityCategories & categoryType) != 0;
    }

    private static int getNewPriorityCategories(NotificationManager.Policy mPolicy,boolean allow, int categoryType) {
        int priorityCategories = mPolicy.priorityCategories;
        if (allow) {
            priorityCategories |= categoryType;
        } else {
            priorityCategories &= ~categoryType;
        }
        return priorityCategories;
    }
//设置勿扰模式---重复来电者
        ZenModePriorityUtils.zenMode_switch(this,NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS,false);
        //设置勿扰模式---来电
        ZenModePriorityUtils.zenMode_switch(this,NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,false);
        //设置勿扰模式---媒体(设备有广告,媒体音量不加入勿扰模式)
        ZenModePriorityUtils.zenMode_switch(this,NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA,true);
        //设置勿扰模式---讯息
        ZenModePriorityUtils.zenMode_switch(this,NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,false);
        //设置勿扰模式---闹铃
        ZenModePriorityUtils.zenMode_switch(this,NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS,false);
        //设置勿扰模式---提醒
        ZenModePriorityUtils.zenMode_switch(this,NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,false);
        //设置勿扰模式---活动
        ZenModePriorityUtils.zenMode_switch(this,NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS,false);

总结:

最终采用方案3,但需要注意的,由于7.0到9.0这部分代码,android进行了较大改动,部分设置需要在9.0上才能有效果。