Laidian Butler for android Project (5), android butler
In the above four sections, the interface design has been implemented. The blacklist (the addition and deletion of the white list are the same as those of the black list, so we will not repeat it here), the listener switch, the timed interception switch, and the selection of the interception mode are enabled, the following describes how to implement the core function, that is, the interception function.
Main Ideas:
1. There are two main blocking modes: one is Blacklist, that is, only the number in the blacklist is intercepted, and the other is whitelist, which intercepts numbers other than the whitelist.
2. Create regular expressions based on user-defined settings to determine interception criteria.
3. Use the corresponding class to implement the function of hanging up the phone.
The listener module mainly uses the service to implement functions. To enable the call stop function, you need to call the remote AIDL Service, most books describe how to copy the following two files in the Android source code to the corresponding location of the project:
ITelephony. aidl under com. android. internal. telephony
NeighboringCellinfo. aidl In the android. telephony package
However, downloading the source code requires a great deal of trouble. In fact, the purpose of doing this is to automatically generate the ITelephony. java source file under the root directory. Therefore, you can do this without the source code. The procedure is as follows:
1) create a package in the src directory of the project: com. android. internal. telephony
2) create a new file named ITelephony. aidl under the newly created package.
3) copy the following code to the newly created file.
package com.android.internal.telephony; interface ITelephony{ boolean endCall(); void answerRingingCall(); }
In this way, the ADT will automatically generate the ITelephony. java source file under the root directory.
The entire service code is as follows, which also explains:
ListenService. java
Package com. example. callmanager; import java. lang. reflect. invocationTargetException; import java. lang. reflect. method; import java. text. simpleDateFormat; import java. util. date; import android. app. activity; import android. app. service; import android. content. context; import android. content. intent; import android. content. sharedPreferences; import android. database. cursor; import android. database. sqlite. SQLiteDatab Ase; import android. media. audioManager; import android.net. uri; import android. OS. IBinder; import android. OS. remoteException; import android. provider. contactsContract. phoneLookup; import android. telephony. phoneStateListener; import android. telephony. telephonyManager; import android. widget. toast; import com. android. internal. telephony. ITelephony; public class ListenService extends Service {TelephonyManager tM Anager; private SQLiteDatabase db; private SharedPreferences spf; private CustomPhoneCallListener callListener; @ Overridepublic void onCreate () {// TODO Auto-generated method stubsuper. onCreate (); System. out. println ("create") ;}@ Overridepublic int onStartCommand (Intent intent, int flags, int startId) {// TODO Auto-generated method stubtManager = (TelephonyManager) getSystemService (TELEPHONY_SERVICE ); ca LlListener = new CustomPhoneCallListener (); spf = this. getSharedPreferences ("setting", Activity. MODE_PRIVATE); tManager. listen (callListener, PhoneStateListener. LISTEN_CALL_STATE); System. out. println ("start"); return super. onStartCommand (intent, flags, startId) ;}@ Overridepublic void onDestroy () {// TODO Auto-generated method stubsuper. onDestroy (); callListener = null; tManager = null; System. out. println (" Destory "); stopSelf () ;}@ Overridepublic boolean onUnbind (Intent intent) {// TODO Auto-generated method stubreturn super. onUnbind (intent);} // create or open the public void create_db () {// create or open the database db = SQLiteDatabase. openOrCreateDatabase (ListenService. this. getFilesDir (). toString () + "/list. db3 ", null); if (db = null) {Toast. makeText (ListenService. this, "database creation failed", Toast. LENGTH_LONG ). show ();} else {/* // create another table for storage Electrical information db.exe cSQL ("create table if not exists callInfo (_ id integer primary key autoincrement," + "name varchar (50)," + "number varchar (15 ), "+" callTimes varchar (20); "); * //} insert public void insert_callInfo (String name, String number, String time) {Cursor cursor = db. rawQuery ("select * from callInfo where callTimes = '" + time + "';", null); if (cursor. getCount () = 0) {db.exe cSQL ("insert into callInfo (nam E, number, callTimes) values ('"+ name +"', '"+ number +"', '"+ time +"'); ");} cursor. close ();} public class CustomPhoneCallListener extends PhoneStateListener {@ Override public void onCallStateChanged (int state, String incomingNumber) {super. onCallStateChanged (state, incomingNumber); if (spf. getBoolean ("isStartListen", false) {// determines whether the phone is in the blacklist. create_db (); boolean callEnd_flag = false; String inco MingName = null; SimpleDateFormat formatter = new SimpleDateFormat ("MM-dd HH: mm"); Date curDate = new Date (System. currentTimeMillis (); // obtain the current time String strTime = formatter. format (curDate); // if the whitelist mode is enabled if (spf. getBoolean ("isWhiteList", false) {System. out. println ("whiteList"); callEnd_flag =! IsInWhiteList (incomingNumber); // locate the contact name incomingName = getContactsNameByNumber (incomingNumber) based on the contact number;} // in the blacklist mode, else {incomingName = isInBalckList (incomingNumber ); if (incomingName = null) callEnd_flag = false; else callEnd_flag = true;} // if the time range is enabled, determine whether the current call time is in the specified time range if (spf. getBoolean ("isTime", false) {System. out. println ("inTime"); callEnd_flag = callEnd_flag & isInterceptTime (strTime);} switch (state) {case TelephonyManager. CALL_STATE_IDLE: break; case TelephonyManager. CALL_STATE_OFFHOOK: break; // case TelephonyManager when the call is received. CALL_STATE_RINGING: toggleRingerMute (getApplicationContext (); if (callEnd_flag) {try {Method method = Class. forName ("android. OS. serviceManager "). getMethod ("getService", String. class); // obtain the proxy IBinder binder = (IBinder) method of the IBindler object of the remote telephony_service. invoke (null, new Object [] {TELEPHONY_SERVICE}); // convert the proxy of the IBinder Object to the ITelephony Object ITelephony telephony = ITelephony. stub. asInterface (binder); // call telephony. endCall ();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke. printStackTrace ();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke. printStackTrace ();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke. printStackTrace ();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke. printStackTrace ();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke. printStackTrace ();} catch (RemoteException e) {// TODO Auto-generated catch blocke. printStackTrace ();} // insert this number into the Caller information database // obtain the current time if (incomingName = null) {incomingName = "unfamiliar number ";} insert_callInfo (incomingName, incomingNumber, strTime);} System. out. println ("bindListen"); break;} db. close () ;}// call the phone number to find the contact name. If yes, the contact name is returned. Otherwise, null public String getContactsNameByNumber (String number) is returned) {Cursor c = getContentResolver (). query (Uri. withAppendedPath (PhoneLookup. CONTENT_FILTER_URI, number), new String [] {PhoneLookup. _ ID, PhoneLookup. NUMBER, PhoneLookup. DISPLAY_NAME, PhoneLookup. TYPE, PhoneLookup. LABEL}, null); if (c. getCount () = 0) {return null;} else {c. moveToFirst (); return c. getString (2); // get name} private static int previusmutemode =-1;/*** call mute ** @ param context */private void toggleRingerMute (Context context) {AudioManager am = (AudioManager) context. getSystemService (Context. AUDIO_SERVICE); if (previousMuteMode =-1) {previousMuteMode = am. getRingerMode (); am. setRingerMode (0);} am. setRingerMode (previusmutemode); previusmutemode =-1;} // determines whether the current call time is in the public boolean isInterceptTime (String time) during the interception period {// if the time period is enabled if (spf. getBoolean ("isTime", false) {String startTime = spf. getString ("startTime", ""); String endTime = spf. getString ("endTime", ""); // compare whether the current time is within the interception period if (time. compareTo (startTime)> = 0 & time. compareTo (endTime) <= 0) {return true;} return false;} // determines whether the given number is in the whitelist public boolean isInWhiteList (String phone) {Cursor cursor = db. rawQuery ("select * from whiteList where number = '" + phone + "';", null); cursor. moveToFirst (); // returns true if (cursor. getCount ()> 0) {cursor. close (); return true;} return false;} // checks whether the specified number is in the blacklist. public String isInBalckList (String phone) {Cursor cursor = db. rawQuery ("select * from blackList where number = '" + phone + "';", null); String name = null; cursor. moveToFirst (); if (cursor. getCount ()> 0) name = cursor. getString (cursor. getColumnIndex ("name"); cursor. close (); return name ;}@ Overridepublic IBinder onBind (Intent intent) {// TODO Auto-generated method stubreturn null ;}}
The code is very long, but the core is the CustomPhoneCallListener part. The main idea is to read the user's settings and determine whether to intercept them.
At the same time, the interception information is written to the database, so the database code in the above Code is also available.
Finally, the important thing is that, like Activity, the service also needs to be registered and added to AndroidManifest. xml:
<service android:name="com.example.callmanager.ListenService" android:enabled="true" > <intent-filter> <action android:name="com.example.callmanager.ListenService" /> </intent-filter> </service>
Of course, to listen to the incoming call status, you must read the call history and the permission to read the phone status. Add the following in AndroidManifest. xml:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/><uses-permission android:name="android.permission.CALL_PHONE"/>
In this way, when you need to enable the listener service, you can use Intent to start the service. After the service is enabled, even if you exit the Activity, you can also implement listening, because the service is still running in the background, this is the basic function of the service.
What is the difference between China Unicom's 3 yuan and 5 yuan laidian manager?
You can bind another number. When someone calls your phone and fails to answer the call, it will send a text message to the bound mobile phone and send a text message indicating that the phone is missing.
Online android projects with eclipse cannot be debugged
Why can't I debug it? Is there any error message?
Generally, it can be debugged. We recommend that you do not use 1.5, or at least 1.6 or 2.2.