編輯:Android開發實例
一、問題描述
使用BordercastReceiver和Service組件實現下述功能:
1.當手機處於來電狀態,啟動監聽服務,對來電進行監聽錄音。
2.設置電話黑名單,當來電是黑名單電話,則直接掛斷。
當撥打電話或電話狀態發生改變時,系統就會發出有序廣播,因此我們可以使用BordercastReceiver接受廣播,因BordercastReceiver執行時間短不能執行耗時任務也不能使用子線程,因此我們應啟動一個Service來監聽電話並進行處理
二、加入AIDL文件
Android沒有對外公開結束通話的API,要結束通話就必須使用AIDL與電話管理服務進行通信,並調用服務中的API實現結束通話,這樣需要android 源碼文件NeighboringCellInfo.aidl和ITelephony.aidl添加到項目中,如圖所示:
Android Studio 會自動編譯產生對應的類文件
三、編寫TelReceiver組件
public class TelReceiver extends BroadcastReceiver { public TelReceiver() { } @Override public void onReceive(Context context, Intent intent) { Intent i=new Intent(context,ListenPhoneService.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setAction(intent.getAction()); i.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER));//電話號碼 i.putExtra(TelephonyManager.EXTRA_STATE, intent.getStringExtra(TelephonyManager.EXTRA_STATE));//電話狀態 context.startService(i);//啟動服務 } }
注冊廣播:
<receiver android:name=".TelReceiver" > <intent-filter android:priority="1000" > <action android:name="android.intent.action.PHONE_STATE" /> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver>
四、編寫ListenPhoneService組件
public class ListenPhoneService extends Service { private AudioManager mAudioManager; private TelephonyManager tm; public ListenPhoneService() { } @Override public void onCreate() { super.onCreate(); mAudioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE); tm=(TelephonyManager)getSystemService(Service.TELEPHONY_SERVICE); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){//去電廣播,android沒有來電話廣播 }else{//去掉撥打電話就是來電狀態了 //方法1 //獲得來電電話 // String number=intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); //獲得電話狀態 // String state=intent.getStringExtra(TelephonyManager.EXTRA_STATE); // Log.d("jereh", "incoming phone:" + number); // Log.d("jereh","call state:"+state); // TelephonyManager.EXTRA_STATE_IDLE: 沒有來電 或者 掛斷 // TelephonyManagerEXTRA_STATE_OFFHOOK: 接起電話 // TelephonyManager.EXTRA_STATE_RINGING:當電話呼入時,響鈴時 // if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){ // if(number.equals("13280998858")){//攔截指定的電話號碼 // mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); // Log.d("jereh","電話被攔截"); // stopCall(); // mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);//恢復鈴聲 // } // }else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ //接起電話 // recordCall();//開始錄音 // }else if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){ // stopCall();//停止錄音 // } //方法2 // 設置一個監聽器,監聽電話狀態 tm.listen(listener,PhoneStateListener.LISTEN_CALL_STATE); } return super.onStartCommand(intent, flags, startId); } /** * 掛斷電話 */ private void stopCall(){ try { //Android的設計將ServiceManager隱藏了,所以只能使用反射機制獲得。 Method method=Class.forName("android.os.ServiceManager").getMethod("getService", String.class); IBinder binder=(IBinder)method.invoke(null, new Object[]{"phone"});//獲得系統電話服務 ITelephony telephoney=ITelephony.Stub.asInterface(binder); telephoney.endCall();//掛斷電話 stopSelf();//停止服務 } catch (Exception e) { e.printStackTrace(); } } PhoneStateListener listener=new PhoneStateListener(){ @Override public void onCallStateChanged(int state,String incomingNumber){ switch (state){ //手機空閒了 case TelephonyManager.CALL_STATE_IDLE: stopCall();//停止錄音 break; //接起電話 case TelephonyManager.CALL_STATE_OFFHOOK: recordCall();//開始錄音 break; // 響鈴時 case TelephonyManager.CALL_STATE_RINGING: Log.e("jereh", "來電號碼是:"+ incomingNumber); // 如果該號碼屬於黑名單 if (incomingNumber.equals("123456")) { // 如果是黑名單,就進行屏蔽 stopCall(); } break; } } }; /** * 停止錄音 */ private void stopRecord(){ if(recording){ recorder.stop(); recorder.release(); recording=false; stopSelf();//停止服務 } } /** * 電話錄音 */ private MediaRecorder recorder; private boolean recording ; private void recordCall(){ Log.d("jereh", "record calling") if( Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ recorder=new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//讀麥克風的聲音 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//設置輸出格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 編碼方式 File file=new File(Environment.getDownloadCacheDirectory().getAbsolutePath(),"recorder"); if(!file.exists()){ file.mkdir(); } recorder.setOutputFile(file.getAbsolutePath() + "/" + System.currentTimeMillis() + "3gp");// 存放的位置是放在sd卡recorder目錄下 try { recorder.prepare(); recorder.start(); recording=true; } catch (IOException e) { e.printStackTrace(); } } } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } }
Service XML配置
<service android:name=".ListenPhoneService" android:enabled="true" android:exported="true" > </service>
五、最後別忘了一些權限的設置
<!-- 添加訪問手機電話狀態的權限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 撥打電話權限 -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- 監聽手機去電的權限 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<!-- 在SDCard中創建與刪除文件權限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 往SDCard寫入數據權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
好了,以上就是本文的全部所述,希望對大家學習android四大基本組件有所幫助,謝謝。
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
前面文章講解了Android的藍牙基本用法,本文講得深入些,探討下藍牙方面的隱藏API。用過Android系統設置(Setting)的人都知道藍牙搜索之後可以建立
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩