Chinaunix首页 | 论坛 | 博客
  • 博客访问: 637002
  • 博文数量: 237
  • 博客积分: 4285
  • 博客等级: 上校
  • 技术积分: 2701
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-15 14:05
文章分类

全部博文(237)

文章存档

2014年(2)

2013年(3)

2012年(47)

2011年(15)

2010年(68)

2009年(102)

我的朋友

分类: Android平台

2014-01-16 15:25:46

 无论从拨号盘输入号码、通话记录、联系人拨打电话等,都会进入OutgoingCallBroadcaster类中。该类继承Activity,理所当然开始进入onCreate()中,让我们在onCreate()做什么操作:

1、onCreate():

复制代码

protected void onCreate(Bundle icicle) { super.onCreate(icicle); //获取传入的intent意图 Intent intent = getIntent(); if (icicle != null) { return;
        }
        processIntent(intent);
}

复制代码

2、获取到intent后,通过intent获取action和电话号码

复制代码

private void processIntent(Intent intent) {

      String action = intent.getAction();
      String number = PhoneNumberUtils.getNumberFromIntent(intent, this); //在此对号码进行啦一个转换操作: //比如输入1-800-GOOG-411 实际为1-800-4664-411 if (number != null) { if (!PhoneNumberUtils.isUriNumber(number)) {
                number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
                number = PhoneNumberUtils.stripSeparators(number);
            }
        } else {
            Log.w(TAG, "The number obtained from Intent is null.");
        }    

}

复制代码

3、获取到号码后,判断号码是否为紧急号码

复制代码

final boolean isPotentialEmergencyNumber = (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, this); //在此对紧急号码与非紧急号码设置不同action if (isPotentialEmergencyNumber) {
     Log.i(TAG, "ACTION_CALL_PRIVILEGED is used while the number is a potential"
                        + " emergency number. Use ACTION_CALL_EMERGENCY as an action instead.");
     action = Intent.ACTION_CALL_EMERGENCY;
} else {
     action = Intent.ACTION_CALL;
} if (DBG) Log.v(TAG, " - updating action from CALL_PRIVILEGED to " + action);
    intent.setAction(action);
} //如果为紧急号码则直接进入InCallScreen界面 if (callNow) { 
   Log.i(TAG, "onCreate(): callNow case! Calling placeCall(): " + intent);
   PhoneGlobals.getInstance().callController.placeCall(intent);
}

复制代码

 

4、如果不是紧急号码,则通过另一种方式开启InCallScreen():

复制代码

//发送广播

Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); if (number != null) {
            broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
        }
        PhoneUtils.checkAndCopyPhoneProviderExtras(intent, broadcastIntent);
        broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow);
        broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, uri.toString()); // Need to raise foreground in-call UI as soon as possible while allowing 3rd party app // to intercept the outgoing call.  broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if (DBG) Log.v(TAG, " - Broadcasting intent: " + broadcastIntent + "."); // Set a timer so that we can prepare for unexpected delay introduced by the broadcast. // If it takes too much time, the timer will show "waiting" spinner. // This message will be removed when OutgoingCallReceiver#onReceive() is called before the // timeout.  mHandler.sendEmptyMessageDelayed(EVENT_OUTGOING_CALL_TIMEOUT,
                OUTGOING_CALL_TIMEOUT_THRESHOLD);
        sendOrderedBroadcastAsUser(broadcastIntent, UserHandle.OWNER,
                PERMISSION, new OutgoingCallReceiver(), null, // scheduler Activity.RESULT_OK, // initialCode number, // initialData: initial value for the result data null); // initialExtras //接收广播,执行onReceive(): alreadyCalled = intent.getBooleanExtra( OutgoingCallBroadcaster.EXTRA_ALREADY_CALLED, false); //如果已经存在InCallScreen,直接finish if (alreadyCalled) { if (DBG) Log.v(TAG, "CALL already placed -- returning."); return;
 } //获取到number和uri String number = getResultData();
String originalUri = intent.getStringExtra( OutgoingCallBroadcaster.EXTRA_ORIGINAL_URI); //开启sip网络通话,在2.2版本好像是直接开启InCallScreen startSipCallOptionHandler(context, intent, uri, number);

复制代码

5、通过代码可知,OutgoingCallBroadcaster只做了对number及uri数据传递和紧急号码判断。既然每个去电都必须通过此类,我们可以通过它对同时拨打号码数量的限制。google只允许同时拨打2个电话,大家可以试试,我们先看看google是如何限制的:

CallManager (frameworks)----- canDial():通过修改此类限制----比如三方通话,同时我们也可以在OutgoingCallBroadcaster中onCreate()中拦截。

复制代码

//判断是否可以拨打 private boolean canDial(Phone phone) { int serviceState = phone.getServiceState().getState(); boolean hasRingingCall = hasActiveRingingCall();//是否响铃 boolean hasActiveCall = hasActiveFgCall();//是否活动在前台 boolean hasHoldingCall = hasActiveBgCall();//是否后台  boolean allLinesTaken = hasActiveCall && hasHoldingCall; 

 Call.State fgCallState = getActiveFgCallState();

 boolean result = (serviceState != ServiceState.STATE_POWER_OFF && !hasRingingCall && !allLinesTaken && ((fgCallState == Call.State.ACTIVE) || (fgCallState == Call.State.IDLE) || (fgCallState == Call.State.DISCONNECTED))); return result;   
}
http://www.cnblogs.com/ProgramBoy/p/3304529.html
复制代码
阅读(944) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~