客户需求只允许通讯录中联系人可以呼入电话。参考自带的黑名单实现
- CallsManager.java类中的onSuccessfulIncomingCall方法有一些过滤器,可以仿照黑名单的方式添加自己的过滤器。
packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java
+import com.android.server.telecom.callfiltering.AsyncContactCheckFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -505,6 +507,7 @@ public class CallsManager extends Call.ListenerBase
filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter()));
filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar,
mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock));
+ filters.add(new AsyncContactCheckFilter(mContext));//mh@[非联系人挂断]
new IncomingCallFilter(mContext, this, incomingCall, mLock,
mTimeoutsAdapter, filters).performFiltering();
}
- 实现过滤器
packages/services/Telecomm/src/com/android/server/telecom/callfiltering/AsyncContactCheckFilter.java
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.server.telecom.callfiltering;
import android.content.Context;
import android.os.AsyncTask;
import android.telecom.Log;
import com.android.server.telecom.Call;
import com.android.server.telecom.LogUtils;
import android.net.Uri;
import android.database.Cursor;
/**
* An {@link AsyncTask} that checks if a call needs to be blocked.
* <p> An {@link AsyncTask} is used to perform the block check to avoid blocking the main thread.
* The block check itself is performed in the {@link AsyncTask#doInBackground(Object[])}.
*/
public class AsyncContactCheckFilter extends AsyncTask<String, Void, Boolean>
implements IncomingCallFilter.CallFilter {
private final Context mContext;
private Call mIncomingCall;
private CallFilterResultCallback mCallback;
public AsyncContactCheckFilter(Context context) {
mContext = context;
}
@Override
public void startFilterLookup(Call call, CallFilterResultCallback callback) {
mCallback = callback;
mIncomingCall = call;
String number = call.getHandle() == null ?
null : call.getHandle().getSchemeSpecificPart();
this.execute(number);
}
@Override
protected void onPreExecute() {
}
@Override
protected Boolean doInBackground(String... params) {
try {
return isContact(mContext, params[0]);
} finally {
}
}
@Override
protected void onPostExecute(Boolean isContact) {
try {
CallFilteringResult result;
if (!isContact) {//非联系人直接挂断
result = new CallFilteringResult(
false, // shouldAllowCall
true, //shouldReject
false, //shouldAddToCallLog
false // shouldShowNotification
);
} else {
result = new CallFilteringResult(
true, // shouldAllowCall
false, // shouldReject
true, // shouldAddToCallLog
true // shouldShowNotification
);
}
mCallback.onCallFilteringComplete(mIncomingCall, result);
} finally {
}
}
//联系人查询
private boolean isContact(Context context, String phoneNum) {
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
Cursor cursor = context.getContentResolver().query(uri, new String[] {android.provider.ContactsContract.Data.DISPLAY_NAME}, null, null, null);
boolean exists = false;
if (cursor != null) {
try {
if(cursor.moveToFirst()){
exists = true;
String name = cursor.getString(0);
Log.i("mh.log", "incoming phone is contact:" + name);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
cursor.close();
}
}
return exists;
}
}
- 可以添加一个开关,这里使用Settings的方式,也可以用广播。
frameworks/base/packages/SettingsProvider/res/values/defaults.xml
+ <!--mh@ phone blocker -->
+ <bool name="xc_unknow_incall_switch">false</bool>
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2355,6 +2355,10 @@ class DatabaseHelper extends SQLiteOpenHelper {
R.bool.def_screen_brightness_automatic_mode);
loadDefaultAnimationSettings(stmt);
+
+ //mh@{
+ loadBooleanSetting(stmt, "xc_unknow_incall_blocker",
+ R.bool.xc_unknow_incall_switch);
+ //mh@}
再修改一下CallsManager.java
public void onSuccessfulIncomingCall(Call incomingCall) {
Log.d(this, "onSuccessfulIncomingCall");
if (incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE)) {
Log.i(this, "Skipping call filtering due to ECBM");
onCallFilteringComplete(incomingCall, new CallFilteringResult(true, false, true, true));
return;
}
List<IncomingCallFilter.CallFilter> filters = new ArrayList<>();
filters.add(new DirectToVoicemailCallFilter(mCallerInfoLookupHelper));
filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter()));
filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar,
mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock));
//mh@{
boolean blocker = Settings.System.getInt(mContext.getContentResolver(), "xc_unknow_incall_blocker", 0) == 1;
if(blocker) {
filters.add(new AsyncContactCheckFilter(mContext));//mh@[非联系人挂断]
}
//mh@}
new IncomingCallFilter(mContext, this, incomingCall, mLock,
mTimeoutsAdapter, filters).performFiltering();
}