也许有时你会有这样一个需求:通电话时有一个重要的事需要记下来或者和一个陌生人特别是大骗子通话时,这是就想如果能把通话录下来就方便多了。(这才是我写这个代码的目的!!!)

在此过程中,犯了一个很大的错误。对电话状态还不熟悉就开始编程,使得我就算编写正确也出现各种bug。

先将代码列出来,供大家参考,然后解释错误和相关知识。

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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.lgqchinese.homework3.MainActivity" > <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启服务"
android:id="@+id/btn_startService"
/> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关闭服务"
android:id="@+id/btn_stopService"
/> </LinearLayout>

MainAvtivity.java:

/**
* 在这里启动服务
*/ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; public class MainActivity extends Activity implements OnClickListener{ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button btn_startService = (Button) findViewById(R.id.btn_startService);
Button btn_stopService = (Button) findViewById(R.id.btn_stopService); //监听按钮点击
btn_startService.setOnClickListener(this);
btn_stopService.setOnClickListener(this);
} @Override
public void onClick(View v) { Intent service = new Intent(getApplicationContext(), MyService.class); switch (v.getId()) {
case R.id.btn_startService:
startService(service); // bindService(service, conn, flags 为了调用服务里面方法
break;
case R.id.btn_stopService:
stopService(service);
break; } } }

MyServier.java:

package com.lgqchinese.homework3;

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 java.io.IOException; public class MyService extends Service {
private MediaRecorder recorder;
public MyService() {
} @Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
System.out.println("onCreate"); // 监听电话状态
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); tm.listen(new myListen(), PhoneStateListener.LISTEN_CALL_STATE); super.onCreate();
} public class myListen extends PhoneStateListener { @Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
/**
* Callback invoked when device call state changes.
*
* @see TelephonyManager#CALL_STATE_IDLE
* @see TelephonyManager#CALL_STATE_RINGING
* @see TelephonyManager#CALL_STATE_OFFHOOK
*/
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 空闲状态
System.out.println("CALL_STATE_IDLE: //空闲状态"); if (recorder != null) {
recorder.stop();
recorder.reset(); // You can reuse the object by going back to// setAudioSource() step
recorder.release(); // Now the object cannot be reused } break;
case TelephonyManager.CALL_STATE_RINGING: // 响铃状态
System.out.println("CALL_STATE_RINGING: //响铃状态"); recorder = new MediaRecorder();
//音频来源
System.out.println("声音来源");
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//音频的输出格式
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //3gp
System.out.println("输出格式");
//设置音频编码格式
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
System.out.println("编码格式");
//音频输出文件地址
recorder.setOutputFile("/mnt/sdcard/luyin.3gp");
System.out.println("文件路径");
//准备录音 try {
recorder.prepare();
System.out.println("正在准备");
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
System.out.println("IllegalStateException异常");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("IOException异常");
} break;
case TelephonyManager.CALL_STATE_OFFHOOK: // 接听状态
System.out.println("CALL_STATE_OFFHOOK: //接听状态");
//开始录音
recorder.start(); // Recording is now started
break; } super.onCallStateChanged(state, incomingNumber);
}
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
System.out.println("onStartCommand");
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() {
// TODO Auto-generated method stub
System.out.println("onDestroy");
super.onDestroy();
}
}

Ok,代码完成。现在就让我们拔打电话来试试吧。(此时很多读过相关文档的小白一定都在笑话我吧)

咦~~,出现这么个问题:

为啥不行!为啥不行!为啥不行!开始调试:

找到了这个:

即在

//开始录音
recorder.start(); // Recording is now started

出现问题,但里面的system.out也执行了呀

然后你还会觉得是start()的问题吗?——会!

应该会发现在响铃状态里面的语句都没执行。所以在start()前面的一些必备方法并没有执行,导致录音失败。

我把响铃状态里面的语句拿到空闲状态,再拨打电话,成功了。。。。。不是真正的成功,虽然可以录音。

此时,就在此时,我还没有阅读有关状态的知识。

我进入CALL_STATE_RINGING所在类,发现里面全部标红:

然后。。我。。把sdk卸载重装一边——(此时智商已经下线了,明明是Android Studio还没加载完)

Ok。Ok,趁这空吃个晚饭,回来后想到了错误:

经过阅读发现,响铃状态,即CALL_STATE_RINGING并不是打电话的状态,那就是接电话的状态了。

敲了半天,不,敲了一天,原来是接电话。结果如下:

由于没有理解电话状态代码的含义,明明对的代码还在不断的调试。以后要避免这种低级的错误。

下面需要记录下状态码的含义:

电话状态:

状态码所在类是TelephonyManager:

CALL_STATE_IDLE 无任何状态时

CALL_STATE_OFFHOOK 接起电话时

CALL_STATE_RINGING 电话进来时

数据活动状态:

DATA_ACTIVITY_IN 数据连接状态:活动,正在接受数据

DATA_ACTIVITY_OUT 数据连接状态:活动,正在发送数据

DATA_ACTIVITY_INOUT 数据连接状态:活动,正在接受和发送数据

DATA_ACTIVITY_NONE 数据连接状态:活动,但无数据发送和接受

数据连接状态:

DATA_CONNECTED 数据连接状态:已连接

DATA_CONNECTING 数据连接状态:正在连接

DATA_DISCONNECTED 数据连接状态:断开

DATA_SUSPENDED 数据连接状态:暂停

网络类型:

NETWORK_TYPE_CDMA 网络类型为CDMA

NETWORK_TYPE_EDGE 网络类型为EDGE

NETWORK_TYPE_EVDO_0 网络类型为EVDO0

NETWORK_TYPE_EVDO_A 网络类型为EVDOA

NETWORK_TYPE_GPRS 网络类型为GPRS

NETWORK_TYPE_HSDPA 网络类型为HSDPA

NETWORK_TYPE_HSPA 网络类型为HSPA

NETWORK_TYPE_HSUPA 网络类型为HSUPA

NETWORK_TYPE_UMTS 网络类型为UMTS

在中国,联通的3G为UMTS或HSDPA,移动和联通的2G为GPRS或EGDE,电信的2G为CDMA,电信的3G为EVDO

移动终端的类型:

PHONE_TYPE_CDMA 手机制式为CDMA,电信

PHONE_TYPE_GSM 手机制式为GSM,移动和联通

PHONE_TYPE_NONE 手机制式未知

移动终端:

SIM_STATE_ABSENT SIM卡未找到

SIM_STATE_NETWORK_LOCKED SIM卡网络被锁定,需要Network PIN解锁

SIM_STATE_PIN_REQUIRED SIM卡PIN被锁定,需要User PIN解锁

SIM_STATE_PUK_REQUIRED SIM卡PUK被锁定,需要User PUK解锁

SIM_STATE_READY SIM卡可用 * SIM_STATE_UNKNOWN SIM卡未知

打电话的功能以后再写。网上很多一起写了,而且都很好。我写一遍主要也是提高自己的水平。

这就完了,得做点什么。我说过了,这才是我的目的。

新建一个类:StartPhoneReceiver.java用来进行开机自启 ,按一下开启服务多不方便呀

package com.lgqchinese.homework3;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent; public class StartPhoneReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
//开启服务 Intent service = new Intent(context, MyService.class); context.startService(service);
}
}

在清单文件里注册一下:

<receiver
android:name=".StartPhoneReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

那你会想看到这个多余的图标吗,在MainActivity.java中加上两行黄底代码:

 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PackageManager p = getPackageManager();
p.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
7
………………………………
}

好了,这是我的目的。这次的错误让我明白,一定要把文档的知识理解了在动手,不能像今天这么傻X了

学习Android过程中遇到的问题及解决方法——电话监听的更多相关文章

  1. 学习Android过程中遇到的问题及解决方法——网络请求

    在学习Android的网络连接时遇到崩溃或异常(出现的问题就这两个,但是不稳定)的问题,先上代码,看看哪里错了(答案在文末) activity_main.xml: <?xml version=& ...

  2. 学习Android过程中遇到的问题及解决方法——AS为xutils添加依赖

    在使用xutils时遇到不能添加以来的问题,花了很长时间终于解决,网上添加依赖的方法很多,在此针对个人出现的问题作下笔记. 我本想使用jar包,因为在使用smartImageView时是用的jar包来 ...

  3. 国内不fq安装K8S四: 安装过程中遇到的问题和解决方法

    目录 4 安装过程中遇到的问题和解决方法 4.1 常见问题 4.2 常用的操作命令 4.3 比较好的博客 国内不fq安装K8S一: 安装docker 国内不fq安装K8S二: 安装kubernet 国 ...

  4. 将html代码部署到阿里云服务器,并进行域名解析,以及在部署过程中遇到的问题和解决方法

    本博客主要是说一下,,如何将html代码部署到阿里云服务器,并进行域名解析,以及在部署过程中遇到的问题和解决方法. 1.先在阿里云上购买一台阿里云服务器(ECS云服务器): 2.远程连接上该服务器,在 ...

  5. 学习Android过程中的一些博客或工具收集

    android studio中使用SlidingMenu: 超简单Android Studio导入第三方库(SlidingMenu)教程绝对傻瓜版 android 更新sdk23以后,报错提示Floa ...

  6. 学习Android过程中遇到的未解决问题(个人笔记,细节补充,随时更新)

    201811/13 使用HttpURLConnection对象调用方法又出现IO异常,我又百度个博客搜寻答案,未果.下午试试真机,完美.自己建了服务器tomcat,编写android访问自己tomca ...

  7. 蘑菇街TeamTalk编译连接过程中遇到的问题及解决方法(iOS)

    今天浏览博文的时候,“蘑菇街开源的即时通讯框架,包括iOS.Android.Mac.Windows客户端和后台 Github源码下载地址:https://github.com/mogujie/Team ...

  8. 2016最新cocoapods安装流程,安装过程中遇到的问题及解决方法

    现在的cocoapods与之前比较.有很多不一样的地方.自己试了一试,终于搞定.现在大概纪录一下. 1.首先查看ruby是否是最新版的. ruby是通过rvm安装的所以需要先安装rvm后查看ruby是 ...

  9. caffe安装过程中遇到的问题以及解决方法

    1. 在安装依赖库的时候,遇到: @gxjun-Latitude-E5440:~$ sudo apt-get install libatlas-base-dev 正在读取软件包列表... 完成 正在分 ...

随机推荐

  1. stl stack用法

    栈后进先出 #include<iostream> #include<algorithm> #include<cstdio> #include<stack> ...

  2. UnderWater+SDN论文之六

    Protocol Emulation Platform Based on Microservice Architecture for Underwater Acoustic Networks Sour ...

  3. Acceleration for ML 论文导读

    Energy efficient parallel neuromorphic architectures with approximate arithmetic on FPGA Motivation ...

  4. Codeforces Round #534 (Div. 2)D. Game with modulo-1104-D(交互+二分+构造)

    D. Game with modulo time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. numpy中random的使用

    import numpy as np a=np.random.random()#用于生成一个0到1的随机浮点数: 0 <= n < 1.0print(a)0.772000903322952 ...

  6. html中怎么设置性别默认选择

    <html><body> <form action="/example/html/form_action.asp" method="get& ...

  7. 福州大学软件工程1816 | W班 第7次作业成绩排名

    写在前面 汇总成绩排名链接 1.作业链接 第七次作业--项目需求分析(团队) 2.评分准则 本次作业映射总分为100分+贡献度得分,由以下部分组成: 引言(5 points) . 用户场景(15 po ...

  8. Java中JDK和JRE的区别是什么?它们的作用分别是什么?

    JDK和JRE是Java开发和运行工具,其中JDK包含了JRE,但是JRE是可以独立安装的,它们在Java开发和运行的时候起到不同的作用~ 1.JDK JDK是Java Development Kit ...

  9. PAT L2-014 列车调度

    https://pintia.cn/problem-sets/994805046380707840/problems/994805063166312448 火车站的列车调度铁轨的结构如下图所示. 两端 ...

  10. Azure系列2.1.1 —— BlobContainerPermissions

    (小弟自学Azure,文中有不正确之处,请路过各位大神指正.) 网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习 ...