android 2.1電話の状態を傍受し、自動的に電話に出る
35738 ワード
一、開発環境Elispse 5.5,JDK1.6,Aadroid 2.1二、開発で使用した重点技術点:距離誘導(SENSOR_SERVICE)、音信管理(AUDIO_SERVICE)、電話状態傍受(TELEPHONY_SERVICE)、java反射起動自動受信、起動自動起動サービス、着信傍受、サービスでActivityを起動し、パラメータを伝達する三、主な開発プロセス:1.最初の3つのステップでは、共通の補助クラスCommonHelperを見ました.
実はこのクラスを最初のステップに置くのは適切ではありません.この共通クラスは本当に私がコードを書く過程で完備しているので、最初から作成したわけではありません.2.まず、着信時または発信時の拡声器のスイッチを管理するための音信管理クラスを構築します.
3.傍受電話状態のクラスを確立する
4.距離誘導を傍受するクラスを確立する
5.サービスを構築します
6.起動後にサービスを開始し、発信を傍受して発信電話番号を取得するブロードキャスト受信クラスを確立します.
7.上記のクラスによっていくつかの権限を使用する必要があるので、AndroidManifestにいます.xmlプロファイルでは、次の変更を行います.
package com.org.speaker;
import android.content.Context;
import android.content.Intent;
public class CommonHelper { //
public static int phoneState=0; //
public static MyAudioManager mam=null; //
public static String outGoingPhoneNumber="";
// Activity
public static void StartCustomerInfoActivity(Context context,String telNo)
{ // Acitivity Context; Acitivity
Intent intent = new Intent(context,CustomerInfo.class); // Service Activity Flag
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Activity
intent.putExtra("TelNo",telNo); // Activity
context.startActivity(intent);
}
}
実はこのクラスを最初のステップに置くのは適切ではありません.この共通クラスは本当に私がコードを書く過程で完備しているので、最初から作成したわけではありません.2.まず、着信時または発信時の拡声器のスイッチを管理するための音信管理クラスを構築します.
import android.content.Context; import android.media.AudioManager;
import android.widget.Toast; public class MyAudioManager {
private AudioManager audioManager;
private int currVolume=0;
private Context context;
public MyAudioManager(Object object,Context mc){
// (http://www.my400800.cn ) this.audioManager=(AudioManager)object; this.context=mc; //
this.audioManager.setMode(AudioManager.ROUTE_SPEAKER); //
currVolume=audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
}
//
public void OpenSpeaker()
{ // true,
audioManager.setSpeakerphoneOn(true); //
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL ),
AudioManager.STREAM_VOICE_CALL);
//Toast.makeText(context," ",Toast.LENGTH_SHORT).show();
}
//
public void CloseSpeaker(){ // false,
audioManager.setSpeakerphoneOn(false); //
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,currVolume,
AudioManager.STREAM_VOICE_CALL);
//Toast.makeText(context," ",Toast.LENGTH_SHORT).show();
}
}
3.傍受電話状態のクラスを確立する
package com.org.speaker;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.android.internal.*;
import com.android.internal.telephony.ITelephony;
import android.content.Context;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
public class SpeakMananger{
private TelephonyManager teleManager;
private Context context;
public SpeakMananger(Object object,Context p_context) { // Object TelephonyManager
this.teleManager=(TelephonyManager)object;
this.context=p_context;
}
//
public void RegisterListener()
{
teleManager.listen(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);
}
class MyPhoneStateListener extends PhoneStateListener
{
@Override
public void onCallStateChanged(int state,String incomingNumber)
{
super.onCallStateChanged(state, incomingNumber);
switch(state)
{
//
case TelephonyManager.CALL_STATE_IDLE:
//Toast.makeText(context," ",Toast.LENGTH_SHORT).show();
break;
//
case TelephonyManager.CALL_STATE_OFFHOOK:
//Toast.makeText(context," ",Toast.LENGTH_SHORT).show();
// incomingNumber null "" //【 , null ""】
if(incomingNumber==null || incomingNumber.length()<=0){ //
CommonHelper.mam.OpenSpeaker(); // Activity
CommonHelper.StartCustomerInfoActivity(context,CommonHelper.outGoingPhoneNumber);
}
//else // Acitivity,
//CommonHelper.StartCustomerInfoActivity(context,incomingNumber); break;
// Activity
case TelephonyManager.CALL_STATE_RINGING:
//Toast.makeText(context," ",Toast.LENGTH_SHORT).show();
try {
/* */
//StartCall();
answerPhoneAidl(); // Activity
CommonHelper.StartCustomerInfoActivity(context,incomingNumber);
} catch (Exception e) {
Toast.makeText(context," :"+e.getMessage(),Toast.LENGTH_LONG).show();
}
break;
} //
CommonHelper.phoneState=state;
}
}
// Demo http://code.google.com/p/auto-answer/source/detail?r=17
private void answerPhoneAidl() throws Exception {
Class c = Class.forName(teleManager.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony",(Class[])null);
m.setAccessible(true);
ITelephony telephonyService;
telephonyService = (ITelephony)m.invoke(teleManager,(Object[])null);
// Silence the ringer and answer the call!
telephonyService.silenceRinger();
telephonyService.answerRingingCall();
}
/**
* JAVA ITelephony answerRingingCall() 。
*/
private void StartCall() {
// iTelephony
Class<TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
try {
// public/private/protected/
// , public , getMethod.
getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);
// , public/private/protected/
// 。 true Java 。 false
// Java 。
getITelephonyMethod.setAccessible(true);
} catch (SecurityException e) {
Toast.makeText(context," :"+e.getMessage(),Toast.LENGTH_SHORT).show();
} catch (NoSuchMethodException e) {
Toast.makeText(context," :"+e.getMessage(),Toast.LENGTH_SHORT).show();
} try {
ITelephony iTelephony = (ITelephony) getITelephonyMethod.invoke(teleManager, (Object[])null); //
iTelephony.silenceRinger(); //
iTelephony.answerRingingCall();
} catch (IllegalArgumentException e) {
Toast.makeText(context," :"+e.getMessage(),Toast.LENGTH_SHORT).show();
} catch (IllegalAccessException e) {
Toast.makeText(context," :"+e.getMessage(),Toast.LENGTH_SHORT).show();
} catch (InvocationTargetException e) {
Toast.makeText(context," :"+e.getMessage(),Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
Toast.makeText(context,"Remote :"+e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
}
4.距離誘導を傍受するクラスを確立する
package com.org.speaker; import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.telephony.TelephonyManager; public class ProximitySensor {
private SensorManager sensorManager;
private Sensor sensor;
private SensorEventListener listener;
public ProximitySensor(Object object)
{ // SensorManager
this.sensorManager=(SensorManager)object; //
this.sensor=sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
listener=new SensorEventListener()
{
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
if(event.values[0]==1.0){
switch(CommonHelper.phoneState)
{
// ,
case TelephonyManager.CALL_STATE_IDLE:
CommonHelper.mam.CloseSpeaker();
break;
// ,
case TelephonyManager.CALL_STATE_OFFHOOK:
CommonHelper.mam.OpenSpeaker();
break;
}
}else{ //
CommonHelper.mam.CloseSpeaker();
}
}
};
}
//
public void RegisterListener()
{
this.sensorManager.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_FASTEST);
}
//
public void UnRegisterListener(){
this.sensorManager.unregisterListener(listener);
} }
5.サービスを構築します
package com.org.speaker;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class PhoneCallStateService extends Service{
@Overide
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate(){
super.onCreate();
}
/* Service , */
@Override
public void onStart(Intent intent,int startId)
{
super.onStart(intent, startId);
//
MyAudioManager am=new MyAudioManager(this.getSystemService(AUDIO_SERVICE),this); //
CommonHelper.mam=am;
// - - 【 、 、 】
SpeakMananger sm=new SpeakMananger(this.getSystemService(TELEPHONY_SERVICE),this);
sm.RegisterListener();
//
ProximitySensor ps=new ProximitySensor(this.getSystemService(SENSOR_SERVICE));
ps.RegisterListener();
}
@Override
public void onDestroy(){
super.onDestroy();
} }
6.起動後にサービスを開始し、発信を傍受して発信電話番号を取得するブロードキャスト受信クラスを確立します.
package com.org.speaker;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent; /*
* 1. Standard Broadcast Action,
* android.intent.action.BOOT_COMPLETED, Action 。
* 2. BroadcastReceiver , onReceive(Context context, Intent intent),
* Service。
* 3. AndroidManifest.xml ,
* <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
* BOOT_COMPLETED , IntentReceiver ,
* <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> ,
* Action。
* :
*/
public class StartReceiver extends BroadcastReceiver
{
/* intent */
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
public void onReceive(Context context, Intent intent)
{
// ,
if (intent.getAction().equals(ACTION))
{
//
context.startService(new Intent(context,PhoneCallStateService.class));
}
/*
* intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)
* intent.getAction().equals(Intent.ACTION_CALL))
*/
//
if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL))
{
CommonHelper.outGoingPhoneNumber=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}
}
}
7.上記のクラスによっていくつかの権限を使用する必要があるので、AndroidManifestにいます.xmlプロファイルでは、次の変更を行います.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" http://schemas.android.com/apk/res/android "
package="com.org.speaker"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon">
<activity android:name="CustomerInfo"></activity>
<receiver android:name="StartReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.LAUNCHER" /> <!-- -->
<action android:name="android.intent.action.PHONE_STATE"/> <!-- -->
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<service android:name="PhoneCallStateService" android:enabled="true"></service>
</application>
<uses-sdk android:minSdkVersion="4" /> <!-- -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- -->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <!-- SD -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> <!-- -->
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <!-- -->
<uses-permission android:name="android.permission.CALL_PHONE" />
</manifest>