在Android 7.1之前,您可以使用 ITelephony.endCall()
方法结束来电,并为您的应用提供权限 android.permission.CALL_PHONE
,的 android.permission.READ_PHONE_STATE
即可。
在Android 8.0 Oreo (API 26)
上执行相同操作时,我收到此错误
12-09 18:11:25.195 16833-16833 / li.doerf.leavemealone E / TelephonyServiceCallHangup:缺少权限MODIFY_PHONE_STATE, 无法挂断电话
由于 MODIFY_PHONE_STATE
是受保护的权限,我的应用无法获取。有没有办法以编程方式结束Android 8.0+
上的来电?
答案 0 :(得分:1)
Please check below 2 link which is helpful to you:
Permission is only granted to system app, in Manifest
https://source.android.com/devices/tech/config/perms-whitelist
above link is used for white-list your MODIFY_PHONE_STATE permission. This is for security purpose so if you want to access this kind of permission at that time to white-list your permission after you will call your operations.
I think as per android oreo latest update you can receive phone call in your activity using inbuilt method implementation but those are not providing developer to handle end of call. Also get(read) phone number of receiving call but you need to define permission of it. I think my above description is enough to understand
Hope you understand and closed this question.
答案 1 :(得分:1)
将应用程序目标和编译级别更改为28。
并具有权限。
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
在MyPhoneStateListener类的onCallStateChanged方法上添加以下代码。
public void endCall() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
TelecomManager tm = (TelecomManager) mcontext.getSystemService(Context.TELECOM_SERVICE);
if (tm != null) {
boolean success = tm.endCall();
}
// success == true if call was terminated.
} else {
if (mcontext != null) {
TelephonyManager telephony = (TelephonyManager) mcontext
.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
// telephonyService.silenceRinger();
telephonyService.endCall();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
答案 2 :(得分:0)
尝试使用回答,如答案here。
它适用于READ_PHONE_STATE和CALL_PHONE权限。根据{{3}}
,这些权限可用于非系统应用程序答案 3 :(得分:0)
您需要在清单中添加此权限 - :
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
答案 4 :(得分:0)
我找到了一个解决方案。它需要注册为NotificationListenerService,然后解析操作并发送适当的PendingIntent:
public class NotificationListener extends NotificationListenerService {
private static final String TAG = "NotificationListener";
private PendingIntent answerIntent;
private PendingIntent hangupIntent;
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
String packageName = sbn.getPackageName();
if ("com.google.android.dialer".equals(packageName)) {
Notification notification = sbn.getNotification();
for (Notification.Action action : notification.actions) {
String title = String.valueOf(action.title);
if ("hang up".equalsIgnoreCase(title) || "decline".equalsIgnoreCase(title)) {
hangupIntent = action.actionIntent;
} else if ("answer".equalsIgnoreCase(title)) {
answerIntent = action.actionIntent;
}
}
}
}
@Override
public void onListenerConnected() {
Log.i(TAG, "Listener connected");
for (StatusBarNotification sbn : getActiveNotifications()) {
onNotificationPosted(sbn);
}
}
public void answerCall() {
try {
answerIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
public void endCall() {
try {
hangupIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
}
然后在AndroidManifest.xml中声明以下内容:
<service
android:name=".NotificationListener"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
还有一个步骤:用户必须手动将您的应用程序启用为通知侦听器。您可以显示一个带有说明的对话框,然后使用以下代码将用户转到设置页面:
Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivity(intent);
答案 5 :(得分:0)
添加以下权限:
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once "db.php";
if(isset($_POST["submit"]) && $_POST["submit"]!="") {
// var_dump($_POST);
$usersCount = count($_POST["hour"]);
$stmt = $mysqli->prepare('UPDATE events SET hour = ? , minute= ?');
for($i=0;$i<$usersCount;$i++) {
$stmt->bind_param("ss",$_POST["hour"][$i],$_POST["minute"][$i]);
$stmt->execute();
}
// header("Location:golist.php");
}
?>
<form name="frmUser" method="post" action="">
<div style="width:500px;">
<table border="0" cellpadding="10" cellspacing="0" width="500" align="center">
<tr class="tableheader">
<td>Edit Event</td>
</tr>
<?php
$rowCount = count($_POST["myevents"]);
// var_dump($_POST);
$stmt = $mysqli->prepare('SELECT * FROM events WHERE event= ?');
for($i=0;$i<$rowCount;$i++) {
$stmt->bind_param("s",$_POST["myevents"][$i]);
$stmt->execute();
$row[$i] = $stmt->get_result()->fetch_array();
// $CompanyID=$row["id"];
?>
<tr>
<td>
<table border="0" cellpadding="10" cellspacing="0" width="500" align="center" class="tblSaveForm">
<tr>
<td><label>Hour</label></td>
<td><input type="hidden" class="txtField" name="event[]" value="<?php echo $row[$i]['event']; ?>">
<select name="hour[]">
<option><?php echo $row[$i]['hour']; ?></option>
<option value="00">00</option>
<option value="01">01</option>
<option value="02">02</option>
</select>
</td>
</tr>
<tr>
<td><label for="minute">Minute</label></td>
<td><input type="hidden" class="txtField" name="event[]" value="<?php echo $row[$i]['event']; ?>">
<select name="minute[]">
<option><?php echo $row[$i]['minute']; ?></option>
<option value="15">15</option>
<option value="30">30</option>
<option value="45">45</option>
</select>
</td>
</tr>
</table>
</td>
</tr>
<?php
}
?>
<tr>
<td colspan="2"><input type="submit" name="submit" value="Submit" class="btnSubmit"></td>
</tr>
</table>
</div>
</form>
</body></html>
还要求获得ANSWER_PHONE_CALLS和READ_CALL_LOG权限的运行时权限(因为它们是危险权限)。
对于android oreo及以下版本:
在您的项目中创建com.android.internal.telephony软件包,并将其放入名为“ ITelephony.aidl”的文件中:
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
对于上述android oreo:
TelecomManager类提供了直接结束呼叫的方法(代码中提供)。
完成上述步骤后,添加以下提供的方法:(在此之前,请确保初始化TelecomManager和TelephonyManager)。
package com.android.internal.telephony;
interface ITelephony {
boolean endCall();
}