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

  第一种:  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、图解:

Android学习笔记_22_服务Service应用之—与Activity进行相互通信的本地服务的更多相关文章

  1. Android学习笔记九:Service

    一:Service是什么 Service,服务.一般用于提供需要在后台长期运行的服务(如复杂计算.下载等等耗时任务),其特点是长生命周期的.没有用户界面.在后台运行的. 二:Service的生命周期方 ...

  2. Android学习笔记(5)----启动 Theme.Dialog 主题的Activity时程序崩溃的解决办法

    新建了一个Android Studio工程,在MainActivity的主界面中添加了两个按钮,点击其中一个按钮用来启动 NormalActivity,点击另一按钮用来启动DialogActivity ...

  3. 【转】 Pro Android学习笔记(七七):服务(2):Local Service

    目录(?)[-] Local service代码 调用Local ServiceLocal Service client代码 AndroidManifestxml定义Serviceacitivty的l ...

  4. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

  5. 【转】 Pro Android学习笔记(七六):服务(1):local和remote

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的 ...

  6. 【转】 Pro Android学习笔记(七十):HTTP服务(4):SOAP/JSON/XML、异常

    目录(?)[-] SOAP JSON和XMLPullParser Exception处理 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog. ...

  7. 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

    目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...

  8. 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager

    目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csd ...

  9. 【转】 Pro Android学习笔记(六九):HTTP服务(3):HTTP POST MultiPart

    目录(?)[-] 建立测试环境 开发环境导入第三方JAR HTTP Post Multipart小例子 HTTP POST不仅可以通过键值对传递参数,还可以携带更为复杂的参数,例如文件.HTTP Po ...

随机推荐

  1. 【STM32学习笔记】STM32f407 使用4*4矩阵键盘

    作者:李剀 出处:https://www.cnblogs.com/kevin-nancy/ 欢迎转载,但也请保留上面这段声明.谢谢! 写在前面: 这是本人第一次开始写博客,可能写的不是很好,也请大家谅 ...

  2. pat02-线性结构3. 求前缀表达式的值(25)

    02-线性结构3. 求前缀表达式的值(25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 算术表达式有前缀表示法.中缀表示法和后缀表示法 ...

  3. SQL 表定时同步

    1.创建存储过程 create proc [dbo].[sync_calendar] as truncate table dbo.CalendarEvents insert into Calendar ...

  4. DevExpress 14.2 批量汉化

    1.下载DevExpress_.NET_Localization_Resources_14.2汉化包 2.解压后将zh-CN或zh-CHS复制到安装目录如D:\Program Files (x86)\ ...

  5. HashMap和Hashtable的比较

    相同点 HashMap和Hashtable都是存储“键值对(key-value)”的散列表,而且都是采用拉链法解决hash冲突的.但是1.8中,hashmap引入了红黑树.Hashtable没有引入红 ...

  6. JavaScirpt(JS)的this细究

    一.js中function的不同形态 js中类和函数都要通过function关键字来构建. 1.js中当函数名大写时,一般是当作类来处理 function Foo(name, age) { this. ...

  7. H5分享到微信好友朋友圈QQ好友QQ空间微博二维码

    这是分享按钮: <button onclick="call()">通用分享</button> <button onclick="call(' ...

  8. angular2-生命周期钩子函数

    生命周期的顺序 当Angular使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些生命周期钩子方法: 钩子 目的和时机 ngOnChanges() 当Angular(重新)设置数据绑 ...

  9. Dubbo架构原理

    1 Dubbo核心功能 Remoting:远程通讯,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式. Cluster: 服务框架,提供基于接口方法的透明远程过程调用 ...

  10. Android 仿iPhone的日期时间选择器

    可选只选择日期,也可以同时选择时间 只选择日期的情况 同时选择日期和时间的情况 关键代码: findViewById(R.id.selectDateButton).setOnClickListener ...