清除未接来电及通知

应用中有时候会需要获取未接来电,但是当你看完这些未接来电你可能想清除未接来电的通知,及把未接来电变成已读,这时候你需要对数据库操作。


有两种方法可以达到上述需求(其实原理都一样):

一、 直接更改数据库

我们可以参考源码来进行操作,找到MissedCallNotifierImpl.java类,路径是:
packages\services\Telecomm\src\com\android\server\telecom\ui\MissedCallNotifierImpl.java
其中清除未接来电通知的及将未接来电改成已读的代码是:

    /** Clears missed call notification and marks the call log's missed calls as read. */
    @Override
    public void clearMissedCalls() {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                // Clear the list of new missed calls from the call log.
                ContentValues values = new ContentValues();
                values.put(Calls.NEW, 0);
                values.put(Calls.IS_READ, 1);
                StringBuilder where = new StringBuilder();
                where.append(Calls.NEW);
                where.append(" = 1 AND ");
                where.append(Calls.TYPE);
                where.append(" = ?");
                try {
                    mContext.getContentResolver().update(Calls.CONTENT_URI, values,
                            where.toString(), new String[]{ Integer.toString(Calls.
                            MISSED_TYPE) });
                } catch (IllegalArgumentException e) {
                    Log.w(this, "ContactsProvider update command failed", e);
                }
            }
        });
        cancelMissedCallNotification();
    }

由上面的代码可知这是通过Calls.CONTENT_URI这个URI()来对数据进行操作,将所有的未接的Calls.NEW更新为0,并且将Calls.IS_READ更新为1,这样数据里面的未接来接来电就全部更新为已接了。但进行这些,还不完美,我们还没有清除未接来电的通知,这不,最后cancelMissedCallNotification()就是用来清除通知的。照例,我们也来看看cancelMissedCallNotification()的实现方式:

    /** Cancels the "missed call" notification. */
    private void cancelMissedCallNotification() {
        // Reset the number of missed calls to 0.
        mMissedCallCount = 0;
        long token = Binder.clearCallingIdentity();
        try {
            mNotificationManager.cancelAsUser(null, MISSED_CALL_NOTIFICATION_ID,
                    UserHandle.CURRENT);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

这代码任务也很简单,就是清除通知,但是问题来了,我们怎么才能清除另一个应用发出的通知的呢?比如dailer发出未接来电通知,无疑是不能直接清除清除的,只能采取迂回的方法,比如反射调用cancelMissedCallNotification()这个方法,我没有试过,但是应该是可行的!看到你是不是想说,坑爹的Android,不会这么麻烦的吧,清除未接来电都要费这么大的功夫!别着急,接下来揭秘第二种方法,之所以放在后面是因为第二种方法太简单了,以至于你要是先看第二种就不会看第一种方法了。


二、使用系统广播

Android当然不会让你费这么大劲的,早就有广播供开发者使用了,在
packages\services\Telecomm\src\com\android\server\telecom\TelecomBroadcastIntentProcessor.java中可以看到ACTION_CLEAR_MISSED_CALLS这个action,同时你还能看到其他功能的action。
比如:

    /** The action used to send SMS response for the missed call notification. */
    public static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
            "com.android.server.telecom.ACTION_SEND_SMS_FROM_NOTIFICATION";

    /** The action used to call a handle back for the missed call notification. */
    public static final String ACTION_CALL_BACK_FROM_NOTIFICATION =
            "com.android.server.telecom.ACTION_CALL_BACK_FROM_NOTIFICATION";

    /** The action used to clear missed calls. */
    public static final String ACTION_CLEAR_MISSED_CALLS =
            "com.android.server.telecom.ACTION_CLEAR_MISSED_CALLS";

    public static final String ACTION_CALL_PULL =
            "org.codeaurora.ims.ACTION_CALL_PULL";
也就是说你只要在代码里面如下代码就行了:
  • 注:M版本可以这么用,N版本的话sendBroadcast时,除了传送intent过去,还要传一个UserHandler参数!
            Intent intent = new Intent();
            intent.setAction(ACTION_CLEAR_MISSED_CALLS);

            mContext.sendBroadcast(intent);
            callInfos.clear();
            mHandler.sendEmptyMessage(0x00);
    1. **用法是很简单,我们照例追踪一下源码,首先是BroadcastReceiver收到广播**

packages\services\Telecomm\src\com\android\server\telecom\components\TelecomBroadcastReceiver.java

public final class TelecomBroadcastReceiver
        extends BroadcastReceiver implements TelecomSystem.Component {

    /** {@inheritDoc} */
    @Override
    public void onReceive(Context context, Intent intent) {
        synchronized (getTelecomSystem().getLock()) {
            getTelecomSystem().getTelecomBroadcastIntentProcessor().processIntent(intent);
        }
    }

    @Override
    public TelecomSystem getTelecomSystem() {
        return TelecomSystem.getInstance();
    }

}
    2. **接着处理广播**
    packages\services\Telecomm\src\com\android\server\telecom\TelecomBroadcastIntentProcessor.java
public void processIntent(Intent intent) {
        String action = intent.getAction();

        Log.v(this, "Action received: %s.", action);

        MissedCallNotifier missedCallNotifier = mCallsManager.getMissedCallNotifier();

        // Send an SMS from the missed call notification.
        if (ACTION_SEND_SMS_FROM_NOTIFICATION.equals(action)) {
            // Close the notification shade and the notification itself.
            closeSystemDialogs(mContext);
            missedCallNotifier.clearMissedCalls();

            Intent callIntent = new Intent(Intent.ACTION_SENDTO, intent.getData());
            callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivityAsUser(callIntent, UserHandle.CURRENT);

        // Call back recent caller from the missed call notification.
        } else if (ACTION_CALL_BACK_FROM_NOTIFICATION.equals(action)) {
            // Close the notification shade and the notification itself.
            closeSystemDialogs(mContext);
            missedCallNotifier.clearMissedCalls();

            Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
            callIntent.setFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            mContext.startActivityAsUser(callIntent, UserHandle.CURRENT);

        // Clear the missed call notification and call log entries.
        } else if (ACTION_CLEAR_MISSED_CALLS.equals(action)) {
            missedCallNotifier.clearMissedCalls();
        } else if (ACTION_CALL_PULL.equals(action)) {
            // Close the notification shade and the notification itself.
            closeSystemDialogs(mContext);

            String dialogId =  intent.getStringExtra("org.codeaurora.ims.VICE_CLEAR");
            int callType =  intent.getIntExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, 0);
            Log.i(this,"ACTION_CALL_PULL: calltype = " + callType + ", dialogId = " + dialogId);

            Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
            callIntent.putExtra(TelephonyProperties.EXTRA_IS_CALL_PULL, true);
            callIntent.putExtra(TelephonyProperties.EXTRA_SKIP_SCHEMA_PARSING, true);
            callIntent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, callType);
            callIntent.setFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            mContext.startActivityAsUser(callIntent, UserHandle.CURRENT);
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值