智能体感功能总结文档.docx
- 文档编号:13036417
- 上传时间:2023-06-10
- 格式:DOCX
- 页数:17
- 大小:48.82KB
智能体感功能总结文档.docx
《智能体感功能总结文档.docx》由会员分享,可在线阅读,更多相关《智能体感功能总结文档.docx(17页珍藏版)》请在冰点文库上搜索。
智能体感功能总结文档
1.需求背景
目前终端上面会存在一些常用的传感器,利用这些传感器可以做一些新颖的设计。
接下来要介绍的这个功能是市场上很多手机都存在的功能。
当有来电时通过挥动手机至耳朵处,可以自动接听。
以此扩展的还有当在通话详情等界面时,通过挥动手机至耳朵处,可以完成自动呼入操作。
在好玩的同时,完成一些很方便实用的操作。
这样可以给机器增一些亮点。
2.需求分析
这个需求从实现上面来说,大体的流程图如下面所示:
图一对应的是自动呼出。
图二对应的是自动接听。
图1:
自动呼出图2:
自动接听
1.在特定的场景和时机中,判断控制开关状态。
2.需要监听传感器数据,并做出判断。
3.满足条件之后,进行相应的操作。
3.实现过程
1.在特定的时机和场景中加入对于控制开关的判断
(1).自动接听:
当有来电的时候,原生的代码中,对于接近传感器有自己一些的处理,原生的代码中会根据接近传感器远离还是接近用来控制是否灭屏。
所以在当来电的时候在InCallPresenter中,会对于ProximitySensor进行实例化。
所以在ProximitySensor的构造函数中对于当前的开关进行判断:
publicProximitySensor(Contextcontext,AudioModeProvideraudioModeProvider,
AccelerometerListeneraccelerometerListener){
…………………………………………
mContext=context;
AutoAnswerAndDial=Settings.System.getInt(context.getContentResolver(),
"call_auto_answeranddial",0)==1;
m_ProximityListener=newProximityListener(context);
m_ProximityListener.setListener(this);
m_GyroscopeListener=newGyroscopeListener(context);
……………………………………
}
并且在InCallPresenter通过接口对于当前的通话状态进行一个广播,在ProximitySensor中继承InCallPresenter中的接口,并且当通话状态发生变化时,使用onStateChange的回调得知。
@Override
publicvoidonStateChange(InCallStateoldState,InCallStatenewState,CallListcallList){
booleanhasOngoingCall=InCallState.INCALL==newState&&callList.hasLiveCall();
booleanisOffhook=(InCallState.OUTGOING==newState)||hasOngoingCall;
……………………………………………..
Log.i("ProximitySensor","newState"+newState);
Log.i("ProximitySensor","oldState"+oldState);
if((newState!
=oldState)&&((newState==InCallState.INCALL)&&(oldState!
=InCallState.INCALL)))
{
……………………………………..
}
elseif((Flag_INCOMING==false)&&(newState==InCallState.INCOMING))
{
Flag_INCOMING=true;
mAccelerometerListener.enable(true);
m_CallList=callList;
if((m_ProximityListener.HasProximityFunc()==true)&&(AutoAnswerAndDial==true))
{
m_ProximityListener.enable(true);//当功能打开的时候对于接近传感器数据进行监听
}
if((m_GyroscopeListener.HasGyroscopeFunc()==true)&&((AutoAnswerAndDial==true)))
{
m_GyroscopeListener.enable(true);//当功能打开的时候对于陀螺仪传感器数据进行监听
}
}
elseif((newState!
=oldState)&&(oldState==InCallState.INCALL)&&(newState!
=InCallState.INCALL))
{
if((m_GyroscopeListener.HasGyroscopeFunc()==true)&&((AutoAnswerAndDial==true)||(ChangeAudioRoute==true)))
{
m_GyroscopeListener.enable(false);//当功能打开的时候对于陀螺仪传感器数据关闭监听
}
Flag_INCOMING=false;
m_CallList=null;
}
在这个onStateChange中,当前的通话状态为INCOMING的时候打开对于接近传感器和陀螺仪数据的监听,当现在的Callstate变为非Incall的时候将这些传感器的监听关闭。
(2)自动呼出
对于自动呼出,现在我们将这个功能添加在了通话详情,联系人详情,短信会话界面。
对于这些界面的Activity在Onresume中对于开关状态进行判断,并且对于数据打开监听。
@Override
publicvoidonResume(){
super.onResume();
………………………………
booleanchecked=Settings.System.getInt(getApplicationContext().getContentResolver(),
"call_auto_answeranddial",0)==1;
if(checked){//calllogcanusedauto_answeranddialfunc
if(mSensorManager!
=null)
{
zASuitFlag=false;
zGSuitFlag=false;
for(inti=0;i { mSensorManager.registerListener(mSensorListener,mSensor.get(i), SensorManager.SENSOR_DELAY_NORMAL); } } } } 在onpause中对于监听进行关闭。 @Override protectedvoidonPause(){ super.onPause(); if(mSensorManager! =null) { mSensorManager.unregisterListener(mSensorListener); } 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 } 2.需要监听传感器数据,并做出判断。 (1)自动接听 自动接听和下面的自动呼出基本上是一样的,不同的是关于条件判断方面不同: @Override publicvoidSensorChangedNear(booleanchange){ if(Firstchange==false) { FirstchangeDelayNearThreadFirstchangeDelayNear=newFirstchangeDelayNearThread(); FirstchangeDelayNear.start(); if(change==true) { ProximityAlreadyNear=true; } return; }//上面的代码也是对于,一监听就出现接近,但是实际没有接近的处理 if(Firstchange==true) { if(change==false) { } else { if(m_GyroscopeListener.HasGyroscopeFunc()==true)//当存在陀螺仪传感器 { if((Flag_INCOMING==true)&&(change==true)&&(m_CallList! =null)&&(audioMode! =CallAudioState.ROUTE_BLUETOOTH)&&(audioMode! =CallAudioState.ROUTE_WIRED_HEADSET) &&(mAccelerometerListener.zASuitJudge()==true)&&(m_GyroscopeListener.zGSuitJudge()==true)&&AutoAnswerAndDial==true)//对于这个功能只有当通话的音频通路为听筒时才满足条件 { 满足触发条件 } } else { if((Flag_INCOMING==true)&&(change==true)&&(m_CallList! =null)&&(audioMode! =CallAudioState.ROUTE_BLUETOOTH)&&(audioMode! =CallAudioState.ROUTE_WIRED_HEADSET) &&(mAccelerometerListener.zASuitJudge()==true)&&AutoAnswerAndDial==true) { 满足触发条件 } } } (2)自动呼出 1.通过SensorEventListener系统接口对于传感器的数据进行监听。 SensorEventListenermSensorListener=newSensorEventListener(){ @Override publicsynchronizedvoidonSensorChanged(SensorEventevent){ if(event.sensor.getType()==Sensor.TYPE_PROXIMITY) { if((firstPROXIMITY==true)&&(event.values[0]<5f)) { firstPROXIMITY=false; return; } else { firstPROXIMITY=false; }//上面的这一部分代码重点为了处理,在当时的硬件下面一开始监听就会上报一个接近上来。 但是并没有实际上的接近。 Log.i(TAG,"ComposeMessageActivityvalues"+event.values[0]); if(hasGYROSCOPE==true)//当硬件上面存在陀螺仪传感器 { if((event.values[0]<5f)&&(zASuitFlag==true)&&(zGSuitFlag==true)) { 当前的状态满足触发条件 } } else { if((event.values[0]<5f)&&(zASuitFlag==true)) { 当前的状态满足触发条件 } } } elseif(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER) { onSensorAZSuitJudge(event.values[0],event.values[1],event.values[2]); } elseif(event.sensor.getType()==Sensor.TYPE_GYROSCOPE) { onSensorGZSuitJudge(event.values[0],event.values[1],event.values[2]); } } @Override publicvoidonAccuracyChanged(Sensorsensor,intaccuracy){ //ignore } }; //判断当前的加速度传感器是否满足状态,用此来判断当前的手机在空间中的状态,是否处于直立状态 privatevoidonSensorAZSuitJudge(doublex,doubley,doublez){ Log.i(TAG,"onZSensorSuitJudge("+x+","+y+","+z+")"); if(x==0.0||y==0.0||z==0.0)return; if((z<=ACRITICAL_DOWN_ANGLE)||(z>=ACRITICAL_UP_ANGLE)) { zASuitFlag=false; } else { zASuitFlag=true; } } //判断当前的陀螺仪传感器是否满足状态,用此来判断当前的手机在空间中的运动状态,是否绕Z轴发生了旋转运动 privatevoidonSensorGZSuitJudge(doublex,doubley,doublez){ Log.i(TAG,"onZSensorSuitJudge("+x+","+y+","+z+")"); if(x==0.0||y==0.0||z==0.0)return; if((z<=GCRITICAL_DOWN_ANGLE)||(z>=GCRITICAL_UP_ANGLE)) { if(zGSuitFlag==false) { zGSuitFlag=true; zGSuitResetflagThreadzSuit=newzGSuitResetflagThread(); zSuit.start(); } } } //这个zGSuitResetflagThread线程的处理,为了增加成功率,将发生运动的状态保持合理的时间 classzGSuitResetflagThreadextendsThread { @Override publicvoidrun(){ //TODOAuto-generatedmethodstub super.run(); try{ Thread.sleep(2000); }catch(Exceptione){ //TODO: handleexception } zGSuitFlag=false; } } 3.满足条件之后,进行相应的操作 (1)自动接听 对于自动接听满足条件之后,将完成下面的处理,接听这个通话。 if(m_CallList.getIncomingCall().getVideoState()==VideoProfile.STATE_AUDIO_ONLY) { InCallPresenter.getInstance().answerIncomingCall(mContext,VideoProfile.STATE_AUDIO_ONLY); } elseif(m_CallList.getIncomingCall().getVideoState()==VideoProfile.STATE_BIDIRECTIONAL){ InCallPresenter.getInstance().answerIncomingCall(mContext,VideoProfile.STATE_BIDIRECTIONAL); } (2)自动呼出 而自动呼出则是通过下面的代码直接调用系统Intent呼出,在这个地方我们要注意: finalintsubId=SubscriptionManager.getDefaultVoiceSubscriptionId(); PhoneAccountHandlephoneAccountHandle=subscriptionIdToPhoneAccountHandle(subId);对于双卡的时候会使用系统默认的Sub呼出,要不然就会出现呼出的时候选卡槽的问题,这样就会出现麻烦和不人性化的现象。 Intentintent=newCallIntentBuilder(getDialableNumber()) .setCallInitiationType(LogState.INITIATION_CALL_DETAILS) .build(); finalintsubId=SubscriptionManager.getDefaultVoiceSubscriptionId(); PhoneAccountHandlephoneAccountHandle=subscriptionIdToPhoneAccountHandle(subId); if(phoneAccountHandle! =null) { intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,phoneAccountHandle); } mContext.startActivity(intent); 4.总结 1.在开发过程中,需要注意的就是传感器门限的设定,这个设定需要进行大量的实验,以确保准确性。 建议的加速度传感器Z轴的范围: privatestaticfinalfloatACRITICAL_DOWN_ANGLE=-5.0f; privatestaticfinalfloatACRITICAL_UP_ANGLE=5.0f; 建议的陀螺仪传感器Z轴的范围: privatestaticfinalfloatGCRITICAL_DOWN_ANGLE=-2.5f; privatestaticfinalfloatGCRITICAL_UP_ANGLE=2.5f; 这个值需要根据硬件的不同进行调整。 2.对于上面讲述的处理逻辑,我们还可以设置其他一些使用场景的判断,比如智能音频切换,当为speaker通话时,放至耳朵处之后切换为听筒。 其第一步自动接听差不多,只有第二步和第三步不同: @Override publicvoidSensorChangedNear(booleanchange){ intaudioMode=mAudioModeProvider.getAudioMode(); AudioManageraudoManager=(AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); Log.i("ProximitySensor","audioMode"+audioMode); Log.i("ProximitySensor","oldAudioMode"+oldAudioMode); Log.i("ProximitySensor","needSetRoute"+needSetRoute); Log.i("ProximitySensor","Firstchange"+Firstchange); Log.i("ProximitySensor","Flag_INCOMING"+Flag_INCOMING); Log.i("ProximitySensor","change"+change); if(Firstchange==false) { FirstchangeDelayNearThreadFirstchangeDelayNear=newFirstchangeDelayNearThread(); FirstchangeDelayNear.start(); if(change==true) { ProximityAlreadyNear=true; } return; } if(Firstchange==true) { if(change==false) { /*if((audioMode! =CallAudioState.ROUTE_SPEAKER) &&(audioMode! =CallAudioState.ROUTE_WIRED_HEADSET)&&(audioMode! =CallAudioState.ROUTE_BLUETOOTH) &&(needSetRoute==false)&&ChangeAudioRoute==true&&ProximityAlreadyNear==true) { Log.i("ProximitySensor","setAudioRoute(CallAudioState.ROUTE_SPEAKER)"); TelecomAdapter.getInstance().setAudioRoute(CallAudioState.ROUTE_SPEAKER); needSetRoute=true; }*/ } else { if(m_GyroscopeListener.HasGyroscopeFunc()==true) { /*if((needSetRoute==true)&&(mAccelerometerListener.zASuitJudge()==true)&&(m_GyroscopeListener.zGSuitJudge()==true)&&ChangeAudioRoute==true) { TelecomAdapter.getInstance().setAudioRoute(oldAudioMode); Log.i("ProximitySensor","setAudioRoute(oldAudioMode)"); needSetRoute=false; }*/ /*if((mAccelerometerListener.zASuitJudge()==true)&&(m_GyroscopeListener.zGSuitJudge()==true)&&ChangeAudioRoute==true) { ProximityAlreadyNear=true; if(needSetRoute==true) { TelecomAdapter.getInstance().setAudioRoute(oldAudioMode); Log.i("ProximitySensor","setAudioRoute(oldAudioMode)"); //needSetRoute=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 智能 功能 总结 文档