zoukankan      html  css  js  c++  java
  • Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口

    Service


    Service的奇妙之处。在于他不须要界面,一切的操作都在后台操作,所以非常多全局性(手机助手,语音助手)之类的应用非常长须要这个。我们今天也来玩玩

    我们新建一个project——ServiceDemo

    1.启动服务

    服务是怎么启动的。我们先定义一个按钮吧

         <Button
            android: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 {
    
        @Override
        public 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

         <Button
            android: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的生命周期。这个看懂不是难事

    这里写图片描写叙述

    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }

    这里不多做介绍

    4.通话录音机

    我们来写个小案例。就是用service监听通话。录音之后保存下来。我們在button中启动这个service,然后在service中一创建,我们就获取电话状态

    @Override
        public 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 {
    
            //电话状态改变的回调
            @Override
            public 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);
            //设置格式 3GP
            recorder.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;
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public 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 {
    
            //电话状态改变的回调
            @Override
            public 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);
            //设置格式 3GP
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            //设置保存文件夹 权限
            recorder.setOutputFile("sdcard/audio.3gp");
            //设置音频编码
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    
            try {
                //准备录音
                recorder.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public 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;
    
        @Override
        protected 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);
    
    
        }
    
        @Override
        public 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{
    
            //到服务的连接被建立了
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
    
            }
            //到服务的连接中断了
            @Override
            public 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 {
    
        //绑定
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        //解绑
        @Override
        public boolean onUnbind(Intent intent) {
            return super.onUnbind(intent);
        }
    
        //创建
        @Override
        public void onCreate() {
            super.onCreate();
        }
    
        //開始
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return super.onStartCommand(intent, flags, startId);
        }
    
        //销毁
        @Override
        public 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启动

         <Button
            android: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 {
    
        @Override
        public 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() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    //就是返回的对象
                    onclick = (TwoService.Onclick) service;
                }
    
                @Override
                public 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{
    
            @Override
            public void getPic() {
                isShow();
            }
        }

    这样,我们就能够

    PublicGG pg;

    去接收service相同能够调用getPic的方法

    Demo下载:http://download.csdn.net/detail/qq_26787115/9489246

  • 相关阅读:
    MATLAB 2019a 安装包及安装教程
    三角形最大周长
    两数的和
    “精致”的数
    总分最高的学生姓名和各科成绩
    列表元素改写
    统计单词个数
    凯撒密码
    Django入门学习--配置路由(urls)
    Django入门学习--熟悉配置信息
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7382268.html
Copyright © 2011-2022 走看看