热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android应用开发实例篇(2)挂接电震动

一、概述Android原生自带的电话软件是不支持挂接电震动设置的,但很多时候我们却需要这功能,要实现这功能有两种可行的办法,一是修改电话软

一、概述

       Android原生自带的电话软件是不支持挂接电震动设置的,但很多时候我们却需要这功能,要实现这功能有两种可行的办法,一是修改电话软件的代码,二是使用第三方软件,在这里我利用的是第二种方法。我们知道,Android提供给了开发者通过API直接监听到的三种电话状态:CALL_STATE_IDLE、CALL_STATE_OFFHOOK和CALL_STATE_RINGING,网上有很多文章对这三种状态进行了说明,但具体哪种STATE对应于实际中的哪个状态却很少提到,下面进行说明。

     电话一开始所处的状态无非就两种:去电和来电。下面的图片是来电和去电的流程图。

       来电和去电的流程非常相似,图中蓝色字体的英文字母就是对应于API里的三种状态,关键的状态是OFFHOOK,通过仔细观察流程可以知道,如果先有RINGING状态再有OFFHOOK状态的话就处于来电;如果先有OFFHOOK的话就处于去电,在程序里可以通过一个标志位区分它们。实现中是通过一个boolean变量,初始化为false,在检测到RINGING状态时将变量置为true,在IDLE状态将它置为false,最后通过用户的设置共同决定是否震动。或许有人埋怨为什么Android只提供三种状态,其实通过这三种状态再结合一些标志变量就可以检测到电话处于任何一种状态。如果Android什么功能都提供了,那程序员靠什么吃饭?呵呵,开玩笑的。关于开机自动启动怎么实现就不说了,网上有一大堆文章。利用SharedPreferences保存用户的设置。

二、功能

1、支持挂、接电震动设置(还没实现主叫接通震动)

2、开机自动运行

三、实现

      本程序主要由4个java源文件组成,VibrationMainActivity.java、PhoneReceiver.java、VibrationService.java和BootReceiver.java。

VibrationMainActivity.java提供界面给用户设置;PhoneReceiver.java监听接收电话状态改变并根据设置决定是否震动;VibrationService.java后台服务,负责注册和注销电话状态改变接收者(PhoneReceiver);BootReceiver.java监听开机信息并启动服务。

     代码都很简单,直接上代码,最后注意一下权限。

VibrationMainActivity.java文件:

1 package com.nan.vibration;
2
3 import android.os.Bundle;
4 import android.app.Activity;
5 import android.content.Intent;
6 import android.content.SharedPreferences;
7 import android.view.Menu;
8 import android.widget.CheckBox;
9 import android.widget.CompoundButton;
10
11
12
13 public class VibrationMainActivity extends Activity
14 {
15
16 private CheckBox handOnCheckBox = null;
17 private CheckBox handUpCheckBox = null;
18 final Intent mIntent = new Intent();
19
20 private SharedPreferences mSharedPreferences = null;
21 private SharedPreferences.Editor mEditor = null;
22
23 //记录用户设置(接通和挂断)
24 boolean handon = false;
25 boolean handup = false;
26
27
28 @Override
29 public void onCreate(Bundle savedInstanceState)
30 {
31 super.onCreate(savedInstanceState);
32 setContentView(R.layout.activity_vibration_main);
33
34
35 handOnCheckBox = (CheckBox)findViewById(R.id.hand_on_checkBox);
36 handUpCheckBox = (CheckBox)findViewById(R.id.hand_up_checkBox);
37
38 //获取用户设置
39 mSharedPreferences = getSharedPreferences("myshare",MODE_PRIVATE);
40 mEditor = mSharedPreferences.edit();
41
42 //根据设置更新界面
43 handon = mSharedPreferences.getBoolean("On", false);
44 if(handon)
45 handOnCheckBox.setChecked(true);
46 else
47 handOnCheckBox.setChecked(false);
48
49 handup = mSharedPreferences.getBoolean("Up", false);
50 if(handup)
51 handUpCheckBox.setChecked(true);
52 else
53 handUpCheckBox.setChecked(false);
54
55 //用户启动service的动作
56 mIntent.setAction("com.nan.vibration.TELE_SERVICE");
57
58
59 handOnCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
60 {
61
62 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
63 {
64 // TODO Auto-generated method stub
65 //用户设置改变时先停止service
66 stopService(mIntent);
67
68 if(isChecked)
69 handon = true;
70 else
71 handon = false;
72 //保存记录
73 mEditor.putBoolean("On", handon);
74 mEditor.commit();
75
76 //用户设置完再开启service
77 startService(mIntent);
78 //如果两个都没有设置就停止service
79 if((!handup)&&(!handon))
80 stopService(mIntent);
81
82 }
83 });
84
85 handUpCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
86 {
87
88 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
89 {
90 // TODO Auto-generated method stub
91 //用户设置改变时先停止service
92 stopService(mIntent);
93
94 if(isChecked)
95 handup = true;
96 else
97 handup = false;
98 //保存记录
99 mEditor.putBoolean("Up", handup);
100 mEditor.commit();
101 //用户设置完再开启service
102 startService(mIntent);
103 //如果两个都没有设置就停止service
104 if((!handon)&&(!handup))
105 stopService(mIntent);
106
107 }
108 });
109
110
111 }
112
113
114 @Override
115 public boolean onCreateOptionsMenu(Menu menu) {
116 getMenuInflater().inflate(R.menu.activity_vibration_main, menu);
117 return true;
118 }
119 }

VibrationService.java文件:

1 package com.nan.vibration;
2
3 import android.app.Service;
4 import android.content.Intent;
5 import android.content.IntentFilter;
6 import android.os.IBinder;
7 import android.telephony.TelephonyManager;
8
9
10 public class VibrationService extends Service
11 {
12
13 public final static String PHONE_STATE = TelephonyManager.ACTION_PHONE_STATE_CHANGED;
14 private PhoneReceiver mPhoneReceiver;
15
16
17 @Override
18 public IBinder onBind(Intent arg0)
19 {
20 // TODO Auto-generated method stub
21
22 return null;
23 }
24
25 @Override
26 public void onCreate()
27 {
28
29 }
30
31 @Override
32 public int onStartCommand(Intent intent, int flags, int startId)
33 {
34 mPhoneReceiver = new PhoneReceiver();
35 IntentFilter intentFilter = new IntentFilter();
36 //添加receiver接收的动作
37 intentFilter.addAction(PHONE_STATE);
38 intentFilter.setPriority(Integer.MAX_VALUE);
39 //注册receiver
40 registerReceiver(mPhoneReceiver, intentFilter);
41
42 return START_STICKY;
43 }
44
45 @Override
46 public void onDestroy()
47 {
48 //注销receiver
49 unregisterReceiver(mPhoneReceiver);
50 }
51
52 }

PhoneReceiver.java文件

1 package com.nan.vibration;
2
3 import android.app.Service;
4 import android.content.BroadcastReceiver;
5 import android.content.Context;
6 import android.content.Intent;
7 import android.content.SharedPreferences;
8 import android.os.Vibrator;
9 import android.telephony.TelephonyManager;
10
11
12 public class PhoneReceiver extends BroadcastReceiver
13 {
14 private Vibrator mVibrator = null;
15 private SharedPreferences mSharedPreferences = null;
16 boolean handon;
17 boolean handup;
18 boolean hadRinging = false;
19
20 @Override
21 public void onReceive(Context arg0, Intent arg1)
22 {
23 // TODO Auto-generated method stub
24
25 TelephonyManager tManager = (TelephonyManager) arg0.getSystemService(Service.TELEPHONY_SERVICE);
26 mVibrator = (Vibrator)arg0.getSystemService(Service.VIBRATOR_SERVICE);
27 mSharedPreferences = arg0.getSharedPreferences("myshare",0);
28 //读取用户设置
29 handon = mSharedPreferences.getBoolean("On", false);
30 handup = mSharedPreferences.getBoolean("Up", false);
31
32 switch(tManager.getCallState())
33 {
34 //挂断
35 case TelephonyManager.CALL_STATE_IDLE:
36 {
37 if(handup)
38 mVibrator.vibrate(200);//震动200ms
39 hadRinging = false;
40 }
41 break;
42 //接通
43 case TelephonyManager.CALL_STATE_OFFHOOK:
44 {
45 if(handon&&hadRinging)
46 mVibrator.vibrate(200);//震动200ms
47 }
48 break;
49 //来电响铃
50 case TelephonyManager.CALL_STATE_RINGING:
51 {
52 hadRinging = true;
53 }
54 break;
55 //
56 default:
57 break;
58 }
59
60
61 }
62
63 }

BootReceiver.java文件

1 package com.nan.vibration;
2
3 import android.content.BroadcastReceiver;
4 import android.content.Context;
5 import android.content.Intent;
6
7
8 public class BootReceiver extends BroadcastReceiver
9 {
10
11 final Intent mIntent = new Intent();
12
13 @Override
14 public void onReceive(Context arg0, Intent arg1)
15 {
16 // TODO Auto-generated method stub
17 //开机动作?
18 if(arg1.getAction().equals( Intent.ACTION_BOOT_COMPLETED ))
19 {
20 mIntent.setAction("com.nan.vibration.TELE_SERVICE");
21 //开启service
22 arg0.startService(mIntent);
23
24 }
25
26 }
27
28 }

最后,AndroidManifest.xml文件

1 <manifest xmlns:android&#61;"http://schemas.android.com/apk/res/android"
2 package&#61;"com.nan.vibration"
3 android:versionCode&#61;"1"
4 android:versionName&#61;"1.0" >
5
6 <uses-sdk
7 android:minSdkVersion&#61;"8"
8 android:targetSdkVersion&#61;"15" />
9
10 <uses-permission android:name&#61;"android.permission.READ_PHONE_STATE" />
11 <uses-permission android:name&#61;"android.permission.VIBRATE" />
12 <uses-permission android:name&#61;"android.permission.RECEIVE_BOOT_COMPLETED" />
13
14
15 <application
16 android:icon&#61;"&#64;drawable/ic_launcher"
17 android:label&#61;"&#64;string/app_name"
18 android:theme&#61;"&#64;style/AppTheme" >
19 <activity
20 android:name&#61;".VibrationMainActivity"
21 android:label&#61;"&#64;string/title_activity_vibration_main" >
22 <intent-filter>
23 <action android:name&#61;"android.intent.action.MAIN" />
24
25 <category android:name&#61;"android.intent.category.LAUNCHER" />
26 intent-filter>
27 activity>
28
29 <service android:name&#61;".VibrationService" android:exported&#61;"false" >
30 <intent-filter>
31 <action android:name&#61;"com.nan.vibration.TELE_SERVICE" />
32 intent-filter>
33 service>
34 <receiver android:name&#61;".BootReceiver">
35 <intent-filter>
36 <action android:name&#61;"android.intent.action.BOOT_COMPLETED" />
37 intent-filter>
38 receiver>
39
40
41 application>
42
43
44 manifest>

真机运行时&#xff1a;

PS&#xff1a;

    本人在原生Android4.1.2的galaxy nexus&#xff08;三星I9250&#xff09;上亲测可用。

 



推荐阅读
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • 详解Android  自定义UI模板设计_由浅入深
    学习安卓已有一些日子,前段时间整理了不少笔记,但是发现笔记不变分享与携带。今天开始整理博客,全当是与大家分享交流与自身学习理解的过程吧。结合最近在做的一个新闻类app及学习中的问题,一点一点整理一下, ... [详细]
  • vue使用
    关键词: ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 本文介绍了包的基础知识,包是一种模块,本质上是一个文件夹,与普通文件夹的区别在于包含一个init文件。包的作用是从文件夹级别组织代码,提高代码的维护性。当代码抽取到模块中后,如果模块较多,结构仍然混乱,可以使用包来组织代码。创建包的方法是右键新建Python包,使用方式与模块一样,使用import来导入包。init文件的使用是将文件夹变成一个模块的方法,通过执行init文件来导入包。一个包中通常包含多个模块。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 十六.增加一个项目协作留言板功能(二)----- 建立一个任务管理的列表页面
    我们设计一个页面来展示正在处理的任务,该表格可以参照之前基础信息的增删改查。用户通过这个页面对任务进行相应操作。1.在views. ... [详细]
author-avatar
王小小小小弦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有