CTA-敏感行为-呼叫转移

本文详细介绍了Android中的电话权限管理,特别是关于`CALL_PHONE`和`MODIFY_PHONE_STATE`权限,以及如何使用`TelephonyManager`发送USSD请求和设置呼叫转移功能的接口和示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0 索引表

权限

https://developer.android.google.cn/reference/android/Manifest.permission

/frameworks/base/core/res/AndroidManifest.xml

android.permission.CALL_PHONE

android.permission.MODIFY_PHONE_STATE

接口

https://developer.android.google.cn/reference/android/telephony/TelephonyManager

/frameworks/base/telephony/java/android/telephony/TelephonyManager.java

android.telephony.TelephonyManager.sendUssdRequest

android.telephony.TelephonyManager.setCallForwarding


1 需求


2 权限

https://developer.android.google.cn/reference/android/Manifest.permission

/frameworks/base/core/res/AndroidManifest.xml

android.permission.CALL_PHONE

  • Added in API level 1
  • Protection level: dangerous

android.permission.MODIFY_PHONE_STATE

  • Added in API level 1
  • Not for use by third-party applications.

3 接口

https://developer.android.google.cn/reference/android/telephony/TelephonyManager

/frameworks/base/telephony/java/android/telephony/TelephonyManager.java

android.telephony.TelephonyManager.sendUssdRequest

  • Added in API level 26
  • @RequiresPermission(android.Manifest.permission.CALL_PHONE)
  • @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
10484      /**
10485       * Sends an Unstructured Supplementary Service Data (USSD) request to the mobile network and
10486       * informs the caller of the response via the supplied {@code callback}.
10487       * <p>Carriers define USSD codes which can be sent by the user to request information such as
10488       * the user's current data balance or minutes balance.
10489       * <p>Requires permission:
10490       * {@link android.Manifest.permission#CALL_PHONE}
10491       * @param ussdRequest the USSD command to be executed.
10492       * @param callback called by the framework to inform the caller of the result of executing the
10493       *                 USSD request (see {@link UssdResponseCallback}).
10494       * @param handler the {@link Handler} to run the request on.
10495       */
10496      @RequiresPermission(android.Manifest.permission.CALL_PHONE)
10497      @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
10498      public void sendUssdRequest(String ussdRequest,
10499                                  final UssdResponseCallback callback, Handler handler) {
10500          checkNotNull(callback, "UssdResponseCallback cannot be null.");
10501          final TelephonyManager telephonyManager = this;
10502  
10503          ResultReceiver wrappedCallback = new ResultReceiver(handler) {
10504              @Override
10505              protected void onReceiveResult(int resultCode, Bundle ussdResponse) {
10506                  Rlog.d(TAG, "USSD:" + resultCode);
10507                  checkNotNull(ussdResponse, "ussdResponse cannot be null.");
10508                  UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE, android.telephony.UssdResponse.class);
10509  
10510                  if (resultCode == USSD_RETURN_SUCCESS) {
10511                      callback.onReceiveUssdResponse(telephonyManager, response.getUssdRequest(),
10512                              response.getReturnMessage());
10513                  } else {
10514                      callback.onReceiveUssdResponseFailed(telephonyManager,
10515                              response.getUssdRequest(), resultCode);
10516                  }
10517              }
10518          };
10519  
10520          try {
10521              ITelephony telephony = getITelephony();
10522              if (telephony != null) {
10523                  telephony.handleUssdRequest(getSubId(), ussdRequest, wrappedCallback);
10524              }
10525          } catch (RemoteException e) {
10526              Log.e(TAG, "Error calling ITelephony#sendUSSDCode", e);
10527              UssdResponse response = new UssdResponse(ussdRequest, "");
10528              Bundle returnData = new Bundle();
10529              returnData.putParcelable(USSD_RESPONSE, response);
10530              wrappedCallback.send(USSD_ERROR_SERVICE_UNAVAIL, returnData);
10531          }
10532      }

android.telephony.TelephonyManager.sendUssdRequest

  • @SystemApi
  • @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
  • @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
15623      /**
15624       * Sets voice call forwarding behavior as described by the provided {@link CallForwardingInfo}.
15625       *
15626       * This method will enable call forwarding if the provided {@link CallForwardingInfo} returns
15627       * {@code true} from its {@link CallForwardingInfo#isEnabled()} method, and disables call
15628       * forwarding otherwise.
15629       *
15630       * If you wish to be notified about the results of this operation, provide an {@link Executor}
15631       * and {@link Consumer<Integer>} to be notified asynchronously when the operation completes.
15632       *
15633       * @param callForwardingInfo Info about whether calls should be forwarded and where they
15634       *                           should be forwarded to.
15635       * @param executor The executor on which the listener will be called. Must be non-null if
15636       *                 {@code listener} is non-null.
15637       * @param resultListener Asynchronous listener that'll be called when the operation completes.
15638       *                      Called with {@link CallForwardingInfoCallback#RESULT_SUCCESS} if the
15639       *                      operation succeeded and an error code from
15640       *                      {@link CallForwardingInfoCallback} it failed.
15641       *
15642       * @throws IllegalArgumentException if any of the following are true for the parameter
15643       * callForwardingInfo:
15644       * <ul>
15645       * <li>it is {@code null}.</li>
15646       * <li>{@link CallForwardingInfo#getReason()} is not any of:
15647       *     <ul>
15648       *         <li>{@link CallForwardingInfo#REASON_UNCONDITIONAL}</li>
15649       *         <li>{@link CallForwardingInfo#REASON_BUSY}</li>
15650       *         <li>{@link CallForwardingInfo#REASON_NO_REPLY}</li>
15651       *         <li>{@link CallForwardingInfo#REASON_NOT_REACHABLE}</li>
15652       *         <li>{@link CallForwardingInfo#REASON_ALL}</li>
15653       *         <li>{@link CallForwardingInfo#REASON_ALL_CONDITIONAL}</li>
15654       *     </ul>
15655       * <li>{@link CallForwardingInfo#getNumber()} returns {@code null} when enabling call
15656       * forwarding</li>
15657       * <li>{@link CallForwardingInfo#getTimeoutSeconds()} returns a non-positive value when
15658       * enabling call forwarding</li>
15659       * </ul>
15660       * @hide
15661       */
15662      @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
15663      @SystemApi
15664      @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
15665      public void setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo,
15666              @Nullable @CallbackExecutor Executor executor,
15667              @Nullable @CallForwardingInfoCallback.CallForwardingError
15668                      Consumer<Integer> resultListener) {
15669          if (callForwardingInfo == null) {
15670              throw new IllegalArgumentException("callForwardingInfo is null");
15671          }
15672          int callForwardingReason = callForwardingInfo.getReason();
15673          if (callForwardingReason < CallForwardingInfo.REASON_UNCONDITIONAL
15674                  || callForwardingReason > CallForwardingInfo.REASON_ALL_CONDITIONAL) {
15675              throw new IllegalArgumentException("callForwardingReason is out of range");
15676          }
15677          if (callForwardingInfo.isEnabled()) {
15678              if (callForwardingInfo.getNumber() == null) {
15679                  throw new IllegalArgumentException("callForwarding number is null");
15680              }
15681              if (callForwardingReason == CallForwardingInfo.REASON_NO_REPLY
15682                          && callForwardingInfo.getTimeoutSeconds() <= 0) {
15683                  throw new IllegalArgumentException("callForwarding timeout isn't positive");
15684              }
15685          }
15686          if (resultListener != null) {
15687              Objects.requireNonNull(executor);
15688          }
15689  
15690          IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
15691              @Override
15692              public void accept(int result) {
15693                  executor.execute(() ->
15694                          Binder.withCleanCallingIdentity(() -> resultListener.accept(result)));
15695              }
15696          };
15697  
15698          try {
15699              ITelephony telephony = getITelephony();
15700              if (telephony != null) {
15701                  telephony.setCallForwarding(getSubId(), callForwardingInfo, internalCallback);
15702              }
15703          } catch (RemoteException ex) {
15704              Rlog.e(TAG, "setCallForwarding RemoteException", ex);
15705              ex.rethrowAsRuntimeException();
15706          } catch (NullPointerException ex) {
15707              Rlog.e(TAG, "setCallForwarding NPE", ex);
15708              throw ex;
15709          }
15710      }


4 示例


5 adb


6 验证


7 参考资料

我的Android进阶之旅------>四种呼叫转移场景-CSDN博客

android 呼叫转移流程代码_setcallforwardresponse_Zero_plucky的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值