Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口...
Service
Service的奇妙之處。在于他不須要界面,一切的操作都在后臺操作,所以非常多全局性(手機助手,語音助手)之類的應用非常長須要這個。我們今天也來玩玩
我們新建一個project——ServiceDemo
1.啟動服務
服務是怎么啟動的。我們先定義一個按鈕吧
<Buttonandroid:id="@+id/startservice"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="啟動服務" />我們還得新建一個類——MyService
package com.lgl.servicedemo;import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log;/*** 我的服務* Created by lgl on 16/4/10.*/ public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {return null;} }記得要注冊哦
<service android:name=".MyService"/>好了,我們如今來看看怎么啟動。事實上跟activity一模一樣
case R.id.startservice:Intent i = new Intent(this, MyService.class);//啟動服務startService(i);break;我們啟動之后就能夠在后臺看到
這里我們能夠看到有一個服務
2.停止服務
停止服務就相對來講非常easy了,首先我們定義一個Button
<Buttonandroid:id="@+id/stopservice"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="停止服務" />然后就能夠手動停止了
case R.id.stopservice:Intent intent = new Intent(this, MyService.class);//停止服務stopService(intent);break;這樣就停止了
3.聲明周期
用一張圖表示。畢竟天天看Activity的生命周期。這個看懂不是難事
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}這里不多做介紹
4.通話錄音機
我們來寫個小案例。就是用service監聽通話。錄音之后保存下來。我們在button中啟動這個service,然后在service中一創建,我們就獲取電話狀態
@Overridepublic void onCreate() {super.onCreate();getService();}public void getService() {//服務一創建就監聽TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);tm.listen(new myListener(), PhoneStateListener.LISTEN_CALL_STATE);}class myListener extends PhoneStateListener {//電話狀態改變的回調@Overridepublic void onCallStateChanged(int state, String incomingNumber) {super.onCallStateChanged(state, incomingNumber);//推斷當前的狀態switch (state) {//電話空暇case TelephonyManager.CALL_STATE_IDLE:Log.i("myListener", "電話空暇");break;//電話響鈴case TelephonyManager.CALL_STATE_RINGING:Log.i("myListener", "電話響鈴");break;//正在通話case TelephonyManager.CALL_STATE_OFFHOOK:Log.i("myListener", "電話通話");break;}}}這里隱私授權,須要權限哦
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>那我們先來調試一下,我們點擊啟動服務
如今我們能夠在響鈴就開始準備錄音資源了
//電話響鈴case TelephonyManager.CALL_STATE_RINGING:Log.i("myListener", "電話響鈴");//推斷硬件是否支持錄音if (recorder == null) {getRecorder();}break;錄音方法
/*** 通話錄音*/private void getRecorder() {recorder = new MediaRecorder();//麥克風recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//設置格式 3GPrecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//設置保存文件夾 權限recorder.setOutputFile("sdcard/audio.3gp");//設置音頻編碼recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);try {//準備錄音recorder.prepare();} catch (IOException e) {e.printStackTrace();}}這里準備好了之后,我們僅僅要接通了就開始錄音
//正在通話case TelephonyManager.CALL_STATE_OFFHOOK:Log.i("myListener", "電話通話");if(recorder != null){//開始錄音recorder.start();}break;當我們掛斷電話,電話狀態又一次回到空暇的時候就停止而且釋放資源
//電話空暇case TelephonyManager.CALL_STATE_IDLE:Log.i("myListener", "電話空暇");if(recorder != null){//停止錄音recorder.stop();//釋放資源recorder.release();recorder = null;}break;我們來測試一下,我們撥打一個電話。狀態是這種
我們去文件夾下翻一翻
這里,能夠看到有一個audio.3gp說明我們錄音成功了
完整代碼
MyService
package com.lgl.servicedemo;import android.app.Service; import android.content.Intent; import android.media.MediaRecorder; import android.os.IBinder; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log;import java.io.IOException;/*** 電話錄音* Created by lgl on 16/4/10.*/ public class MyService extends Service {//錄音private MediaRecorder recorder;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void onCreate() {super.onCreate();getService();}/*** 獲取電話狀態*/public void getService() {//服務一創建就監聽TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);tm.listen(new myListener(), PhoneStateListener.LISTEN_CALL_STATE);}class myListener extends PhoneStateListener {//電話狀態改變的回調@Overridepublic void onCallStateChanged(int state, String incomingNumber) {super.onCallStateChanged(state, incomingNumber);//推斷當前的狀態switch (state) {//電話空暇case TelephonyManager.CALL_STATE_IDLE:Log.i("myListener", "電話空暇");if(recorder != null){//停止錄音recorder.stop();//釋放資源recorder.release();recorder = null;}break;//電話響鈴case TelephonyManager.CALL_STATE_RINGING:Log.i("myListener", "電話響鈴");//推斷硬件是否支持錄音if (recorder == null) {getRecorder();}break;//正在通話case TelephonyManager.CALL_STATE_OFFHOOK:Log.i("myListener", "電話通話");if(recorder != null){//開始錄音recorder.start();}break;}}}/*** 通話錄音*/private void getRecorder() {recorder = new MediaRecorder();//麥克風recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//設置格式 3GPrecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//設置保存文件夾 權限recorder.setOutputFile("sdcard/audio.3gp");//設置音頻編碼recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);try {//準備錄音recorder.prepare();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void onDestroy() {super.onDestroy();} }Demo下載:http://download.csdn.net/detail/qq_26787115/9486846
5.Service的兩種啟動方式
servic啟動有兩種方式,我們來比對一下。
我們寫一個新建一個項目ServiceTwo
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <Button android:id="@+id/btn_start" android:text="啟動服務" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_stop" android:text="停止服務" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_bind" android:text="綁定服務" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_unbind" android:text="解除綁定" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>MainActivity
package com.lgl.servicetwo;import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btn_start, btn_stop, btn_bind, btn_unbind;private MyConn conn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();conn = new MyConn();}private void initView() {btn_start = (Button) findViewById(R.id.btn_start);btn_stop = (Button) findViewById(R.id.btn_stop);btn_bind = (Button) findViewById(R.id.btn_bind);btn_unbind = (Button) findViewById(R.id.btn_unbind);btn_start.setOnClickListener(this);btn_stop.setOnClickListener(this);btn_bind.setOnClickListener(this);btn_unbind.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.btn_start:startService(new Intent(this,OneService.class));break;case R.id.btn_stop:stopService(new Intent(this,OneService.class));break;case R.id.btn_bind:bindService(new Intent(this,OneService.class),conn,BIND_AUTO_CREATE);break;case R.id.btn_unbind:unbindService(conn);break;}}/*** 服務回調*/class MyConn implements ServiceConnection{//到服務的連接被建立了@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {}//到服務的連接中斷了@Overridepublic void onServiceDisconnected(ComponentName name) {}} }關于服務里面
OneService
package com.lgl.servicetwo;import android.app.Service; import android.content.Intent; import android.os.IBinder;/*** Created by lgl on 16/4/10.*/ public class OneService extends Service {//綁定@Overridepublic IBinder onBind(Intent intent) {return null;}//解綁@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}//創建@Overridepublic void onCreate() {super.onCreate();}//開始@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}//銷毀@Overridepublic void onDestroy() {super.onDestroy();} }這里就不贅述了。啟動的相應方法,我們通過上面的分析出差別來
startService:通過startService啟動的服務。該服務所在的進程會變成服務進程
bindSevice:進程優先級不變,可是綁定的服務和activity同生共死
6.調用service的方法
你會發現,假設單純的看startsevice和bindservice。事實上差別不大,事實上。bindservice有一個用處就是能夠調用service的方法。本身來看的話,你是無法吊桶service的方法的,由于你服務是啟動起來的,你不能new。所以這里就要用上bindservice了,我們新建一個TwoService,而且寫一個方法
//服務方法public void isShow(){System.out.print("我是服務里的一個方法");}這個button啟動
<Buttonandroid:id="@+id/btn_isshow"android:text="調用方法"android:layout_width="wrap_content"android:layout_height="wrap_content" />TwoService
package com.lgl.servicetwo;import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder;/*** Created by lgl on 16/4/10.*/ public class TwoService extends Service {@Overridepublic IBinder onBind(Intent intent) {//返回IBinder對象return new Onclick();}/*** 中間銜接*/class Onclick extends Binder {public void getPic() {isShow();}}//服務方法public void isShow() {Log.i("TwoService","我是服務里的一個方法");} }這里,我們實現了一個中間回傳,把這種方法給傳出去,然后在MainActivity中。我們首先先啟動這個服務
Intent i = new Intent(this,TwoService.class);//假設須要解綁的話就不能用匿名內部類bindService(i, new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//就是返回的對象onclick = (TwoService.Onclick) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {}}, BIND_AUTO_CREATE);這樣。就能夠拿到Onclick的事件,我們點擊按鈕就僅僅要調用
case R.id.btn_isshow:onclick.getPic();break;執行效果
7.方法抽調成接口
當你以為這樣就結束了。那就太不給力了。這里service里有些東西是不能對外提供的。java的思想還是來源于生活,所以我們要把他抽調成接口,我們新建一個接口
package com.lgl.servicetwo;/*** 接口* Created by lgl on 16/4/12.*/ public interface PublicGG {void getPic(); }然后讓Onclik去實現這個接口
/*** 中間銜接*/class Onclick extends Binder implements PublicGG{@Overridepublic void getPic() {isShow();}}這樣,我們就能夠
PublicGG pg;去接收service相同能夠調用getPic的方法
Demo下載:http://download.csdn.net/detail/qq_26787115/9489246
總結
以上是生活随笔為你收集整理的Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 欧阳修、司马光批他无耻,王安石、苏轼则褒
- 下一篇: Git分支高级管理[四]