我正在开发SIP应用程序并且它已成功运行,但仅在KitKat Android版本上获得PHONE_STATE的安全权限拒绝例外。 有谁知道是什么原因,请帮我找一个解决方案。
以下是代码的一部分: -
Intent intent = new Intent(ACTION_PHONE_STATE_CHANGED);
intent.putExtra("state",state);
if (number != null)
intent.putExtra("incoming_number", number);
intent.putExtra(mContext.getString(R.string.app_name), true);
mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
LogCat: -
05-28 01:48:52.556: E/AndroidRuntime(2860): FATAL EXCEPTION: main
05-28 01:48:52.556: E/AndroidRuntime(2860): Process: org.sipdroid.sipua, PID: 2860
05-28 01:48:52.556: E/AndroidRuntime(2860): java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.PHONE_STATE from pid=2860, uid=10051
05-28 01:48:52.556: E/AndroidRuntime(2860): at android.os.Parcel.readException(Parcel.java:1461)
05-28 01:48:52.556: E/AndroidRuntime(2860): at android.os.Parcel.readException(Parcel.java:1415)
05-28 01:48:52.556: E/AndroidRuntime(2860): at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2373)
05-28 01:48:52.556: E/AndroidRuntime(2860): at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1141)
05-28 01:48:52.556: E/AndroidRuntime(2860): at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:370)
05-28 01:48:52.556: E/AndroidRuntime(2860): at org.sipdroid.sipua.ui.Receiver.broadcastCallStateChanged(Receiver.java:496)
答案 0 :(得分:0)
你不能这样做。在KitKat上,只允许系统服务发送广播。
您需要找到解决方法。
答案 1 :(得分:0)
更改SipService类的makeCallWithOptions()方法,如下所示......
public void makeCallWithOptions(final String callee, final int accountId, final Bundle options)
throws RemoteException {
SipService.this.enforceCallingOrSelfPermission(SipManager.PERMISSION_USE_SIP, null);
//We have to ensure service is properly started and not just binded
SipService.this.startService(new Intent(SipService.this, SipService.class));
if(pjService == null) {
Log.e(THIS_FILE, "Can't place call if service not started");
// TODO - we should return a failing status here
return;
}
if(!supportMultipleCalls) {
// Check if there is no ongoing calls if so drop this request by alerting user
SipCallSession activeCall = pjService.getActiveCallInProgress();
if(activeCall != null) {
if(!CustomDistribution.forceNoMultipleCalls()) {
notifyUserOfMessage(R.string.not_configured_multiple_calls);
Log.d("call......", "makecallwithoption");
}
return;
}
}
Intent intent = new Intent(SipManager.ACTION_SIP_CALL_LAUNCH);
intent.putExtra(SipProfile.FIELD_ID, accountId);
intent.putExtra(SipManager.EXTRA_SIP_CALL_TARGET, callee);
intent.putExtra(SipManager.EXTRA_SIP_CALL_OPTIONS, options);
sendOrderedBroadcast (intent , SipManager.PERMISSION_USE_SIP, mPlaceCallResultReceiver, null, Activity.RESULT_OK, null, null);
}
添加以下广播接收器..... private BroadcastReceiver mPlaceCallResultReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, final Intent intent) {
final Bundle extras = intent.getExtras();
final String action = intent.getAction();
if(extras == null) {
Log.e(THIS_FILE, "No data in intent retrieved for call");
return;
}
if(!SipManager.ACTION_SIP_CALL_LAUNCH.equals(action)) {
Log.e(THIS_FILE, "Received invalid action " + action);
return;
}
final int accountId = extras.getInt(SipProfile.FIELD_ID, -2);
final String callee = extras.getString(SipManager.EXTRA_SIP_CALL_TARGET);
final Bundle options = extras.getBundle(SipManager.EXTRA_SIP_CALL_OPTIONS);
if(accountId == -2 || callee == null) {
Log.e(THIS_FILE, "Invalid rewrite " + accountId);
return;
}
getExecutor().execute(new SipRunnable() {
@Override
protected void doRun() throws SameThreadException {
pjService.makeCall(callee, accountId, options);
}
});
}
};
在UAStateReceiver类中更改以下内容
private void onBroadcastCallState(final SipCallSession callInfo) {
SipCallSession publicCallInfo = new SipCallSession(callInfo);
Intent callStateChangedIntent = new Intent(SipManager.ACTION_SIP_CALL_CHANGED);
callStateChangedIntent.putExtra(SipManager.EXTRA_CALL_INFO, publicCallInfo);
pjService.service.sendBroadcast(callStateChangedIntent, SipManager.PERMISSION_USE_SIP);
}
和......
private void broadCastAndroidCallState(String state, String number) {
// Android normalized event
if(!Compatibility.isCompatible(19)) {
// Not allowed to do that from kitkat
Intent intent = new Intent(ACTION_PHONE_STATE_CHANGED);
intent.putExtra(TelephonyManager.EXTRA_STATE, state);
if (number != null) {
intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, number);
}
intent.putExtra(pjService.service.getString(R.string.app_name), true);
pjService.service.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
}
}
它将能够在android 4.4.2中进行调用快乐的coading:)