如果我使用的是 BroadcastReceiver,Android CallScreeningService 会放在哪里?



我正在使用广播接收器来检测传入呼叫,然后调用我的自定义传入屏幕,如下所示:

public class CallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String phoneNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
String msg = phoneNumber + " Incoming Call";
String name = "Gil Pires";
//showToast(context, msg);

Intent callerIntent = new Intent(context, CallerInfoActivity.class);
callerIntent.putExtras(callerIntent);
callerIntent.putExtra("EXTRA_PHONE_CALLER", phoneNumber);
callerIntent.putExtra("EXTRA_NAME_CALLER", name);
context.startActivity(callerIntent);
//showToast(context,msg);
}
}
void showToast(Context context,String message){
Toast toast=Toast.makeText(context,message,Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER,0,0);
toast.show();
}
}

CallScreeningService:

@RequiresApi(api = Build.VERSION_CODES.N)
public class CallService extends CallScreeningService {
@Override
public void onScreenCall(@NonNull Call.Details callDetails) {
CallResponse.Builder response = new CallResponse.Builder();
Uri callerPhone = callDetails.getHandle();
Log.e("CallBouncer", "Call screening service triggered " + callerPhone);
respondToCall(callDetails, response.build() );
}
}

所以我不确定这个CallScreeningService在哪里被用作BroadcastReceiver,我能够在传入呼叫上创建和显示我的自定义屏幕?

我使用CallScreenService来显示一个小窗口,其中包含来电者的详细信息。你必须遵循一些步骤来实现CallScreenService:Manifest.xml中的第一个声明

`<activity
android:name=".calling_app.ui.navigation.HomeActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:excludeFromRecents="false"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustNothing">
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
<action android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
<action android:name="android.intent.category.DEFAULT"/>
<data android:scheme="tel"/>
</intent-filter>
</activity>`

创建一个类,你将在其中实现CallScreenService并在那里编写你的逻辑myServiceClass:

class CallerAppService : CallScreeningService() {
@Inject
lateinit var applicationRepository: ApplicationRepository
@Inject
lateinit var telephonyManager: TelephonyManager
private val windowManagerForNumber by lazy {
WindowManagerForNumber(this)
}
private var finalPhoneNumb: String? = ""
private val callerName: String?
get() = finalPhoneNumb?.let {
applicationRepository.fetchNameFromPhoneNumber(
it
)
}
private val notificationManagerImpl = NotificationManagerImpl()
private val notification by lazy {
com.example.truecaller.calling_app.utils.notification.Notification(this)
}
companion object {
fun startService(context: Context) {
Intent(context, TrueCallerAppService::class.java).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(context, this)
} else {
context.startService(this)
}
}
}
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
startNotification()
return START_STICKY
}
override fun onScreenCall(p0: Call.Details) {
val number = getPhoneNumber(p0)
var callResponse = CallResponse.Builder()
callResponse = handlePhoneCall(callResponse, number)
respondToCall(p0, callResponse.build())
}
private fun handlePhoneCall(                 //Here you will write your logic 
//what you want to do on ScreenCall
response: CallResponse.Builder,
phoneNumber: String
): CallResponse.Builder {
if (phoneNumber == FORBIDDEN_PHONE_CALL_NUMBER) {
response.apply {
setRejectCall(true)
setDisallowCall(true)
setSkipCallLog(false)
}
} else {
if (Settings.canDrawOverlays(this)) {
finalPhoneNumb = phoneNumber
if (PhoneNumberValidCheck.checkValidPhoneNumber(phoneNumber)) {
displayToast(phoneNumber)
Log.e("phone", "handlePhoneCall: $phoneNumber")
}
}
}
return response
}
private fun startNotification() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(notification.notificationId, notification.createNotification())
} else {
startForeground(
notification.notificationId,
android.app.Notification()
)
}
isForeGroundService = true
}
private fun displayToast(message: String) {
try {
val countryCodeOfNumber = telephonyManager.simCountryIso.toString()
val phoneNumberUtil = PhoneNumberUtil.getInstance()
val phoneNumber: Phonenumber.PhoneNumber =
phoneNumberUtil.parse(message, countryCodeOfNumber.uppercase(Locale.ENGLISH))
val incomingNumber = phoneNumberUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.E164)
notificationManagerImpl.appRepo(applicationRepository, windowManagerForNumber, incomingNumber)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun getPhoneNumber(callDetails: Call.Details): String {
return callDetails.handle.toString().removeTelephonePrefix().parseNumberCountryCode()
}

}

你必须让你的应用默认拨号应用或默认来电显示和垃圾邮件

@RequiresApi(Build.VERSION_CODES.Q)
fun Activity.startCallScreeningPermissionScreen(onCall: (intent: Intent) -> Unit) {
val roleManager = this.getSystemService(AppCompatActivity.ROLE_SERVICE) as RoleManager
val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING)
onCall.invoke(intent)
}
fun Activity.startSelectDialerScreen(onCall: (intent: Intent) -> Unit) {
if (this.hasDialerCapability())
return
val intent = Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
onCall.invoke(intent)
}

现在在你的mainActivity请求中改变默认拨号程序

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
activity.startCallScreeningPermissionScreen { intent->
activityResultLauncher?.launch(intent)
}
} else {
activity.startSelectDialerScreen { intent ->
activityResultLauncher?.launch(intent)
}

activityResultLauncher:

activityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
when (it.resultCode) {
RESULT_OK -> {
//do something when the app selected as a default dialer
}
}
}

相关内容

  • 没有找到相关文章

最新更新