zoukankan      html  css  js  c++  java
  • Android学习笔记_22_服务Service应用之—与Activity进行相互通信的本地服务

    一、启动服务的两种方法方法:

      第一种:  startService()和stopService()启动关闭服务。适用于服务和Activity之间没有调用交互的情况。如果相互之间需要方法调用或者传递参数,需要使用bindService()和unbindService()方法启动关闭服务。

        第二种: 采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法,这个时候调用者和服务绑定在一起。 如果客户端要与服务进行通信,那么,onBind()方法必须返回Ibinder对象。如果调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。

      服务有关的生命周期方法

    与采用Context.startService()方法启动服务有关的生命周期方法

      onCreate() 》 onStart()  》 onDestroy()

      onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。

      onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,    但onStart() 方法会被多次调用。

      onDestroy()该方法在服务被终止时调用。

    与采用Context.bindService()方法启动服务有关的生命周期方法

      onCreate() 》 onBind() 》 onUnbind()  》 onDestroy()

      onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用  Context.bindService()方法并不会导致该方法被多次调用。

      onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。

      如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下:

      onCreate() 》onStart()  > onBind() > onUnbind()[重载后的方法需返回true]àonRebind()

    二、代码实现:

      1、配置文件:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.phonelisteners"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            
            <service android:name="com.example.phonelistener.PhoneService"/>
            <receiver android:name="com.example.phonelistener.BootBroadcastReceiver">
                <intent-filter>
                     <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
            </receiver>
        </application>
    <!-- 开机启动权限 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <!-- 监听电话状态 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
     <!-- 在SDCard中创建与删除文件权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!-- 往SDCard写入数据权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!-- 访问internet权限 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <!-- 刻录权限 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    </manifest>

      2、通过广播接收者启动服务:

    public class BootBroadcastReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            //意图是用于激活组件的,服务不能自己启动
            Intent in = new Intent(context,PhoneService.class);
            context.startService(in);
        }
    
    }

      3、监听电话服务:

    package com.example.phonelistener;
    
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.media.MediaRecorder;
    import android.os.IBinder;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    import android.util.Log;
    
    public class PhoneService extends Service {
        private static final String TAG = "PhoneService";
    
        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            // 通过系统内置服务获取电话管理服务
             TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
            telManager.listen(new PhoneListener(),PhoneStateListener.LISTEN_CALL_STATE);
            Log.e(TAG, "onCreate()");
    
        }
    
        private class PhoneListener extends PhoneStateListener {
            private File file;
            private boolean recoding;
            private String mobile;
            private MediaRecorder recorder;
    
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                try {
                    Log.i(TAG, " phone number: "+incomingNumber);
                    switch (state) {
                    /* 无任何状态时,挂断电话回到空闲状态 */
                    case TelephonyManager.CALL_STATE_IDLE: 
                        if (recorder != null) {
                            if (recoding) {
                                recorder.stop();
                                recorder.release();
                                Log.e(TAG, "record finish");
                                recorder = null;
                                //uploadFile();
                            }
                        }
                        break;
    
                    case TelephonyManager.CALL_STATE_OFFHOOK: // 接起电话时 
                        
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                        String filename = mobile + dateFormat.format(new Date()) + ".3gp";
    //                    file=new File(Environment.getExternalStorageDirectory(),filename);
                        file=new File("/storage/sdcard0/Music",filename);
                        recorder = new MediaRecorder();
                        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// .3pg
                        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                        recorder.setOutputFile(file.getAbsolutePath());
                        recorder.prepare();
                        recorder.start();// 开始录音
                        recoding = true;
                        Log.e(TAG, "recording: "+file.getAbsolutePath());
                        break;
    
                    case TelephonyManager.CALL_STATE_RINGING: //电话进来时 
                          mobile = incomingNumber;
                        break;
                    }
                } catch (Exception e) {
                    Log.e(TAG, e.toString());
                }
                super.onCallStateChanged(state, incomingNumber);
            }
            //上传文件
            private void uploadFile(){
           }
    
    }

      4、图解:

  • 相关阅读:
    解决 src/MD2.c:31:20: fatal error: Python.h: No such file or directory安装包错误
    Java 保存对象到文件并恢复 ObjectOutputStream/ObjectInputStream
    Elasticsearch安装配置和测试
    [知识图谱] 环境配置:Java8 + Maven3 + HBase + Titan
    Java8安装配置
    MongoDB 安装、运行、使用、数据恢复
    Java堆空间溢出解决方法 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    服务器重装和配置:Ubuntu16.04 + Anaconda3 + GTX1080驱动 + CUDA8 + cuDNN + 常用工具安装
    [Linux] 输出文件的指定行
    [Linux] sed命令使用之在文件中快速删除/增加指定行
  • 原文地址:https://www.cnblogs.com/lbangel/p/3461045.html
Copyright © 2011-2022 走看看