[android基础]《疯狂android讲义》重点整理(2)

article/2025/9/18 8:50:20


十、Service与BroadcastReceiver:


1.Service与Activity还有一点相似之处,它们都是从Context派生出来的,因此它们都可调用Context里定义的如getResources()、getContentResolver()等方法。

2.与配置Activity相似的是,配置Service时也可为<service.../>元素配置<intent-filter.../>子元素,用于说明该Service可被哪些Intent启动。

3.每当Service被创建时会回调onCreate方法,每次Service被启动时都会回调onStart方法——多次启动一个已有的Service组件将不会再回调onCreate方法,但每次启动时都会回调onStart方法。

4.当程序通过startService()和stopService()启动、关闭Service时,Service与访问者之间基本上不存在太多的关联,因此Service和访问者之间也无法进行通信、数据交换;如果Service和访问者之间需要进行方法调用或数据交换,则应该使用bindService()和unbindService()方法启动、关闭服务。

5.客户端访问Service时,Android并不是直接返回Service对象给客户端,Service只是将一个回调对象(IBinder对象)通过onBind()方法返回给客户端。

6.与多次调用startService()方法启动Service不同的是,多次调用bindService()方法并不会执行重复绑定,系统只会回调Service的onBind()方法一次。



7.有一种特殊情形,当某个Service之前已由某个客户端通过startService()方法启动了,接下来其他客户端再调用bindService()方法来绑定该服务后,再调用unbindService()方法解除绑定,最后又调用了bindService()方法再次绑定到服务,这个过程所触发的生命周期方法为onCreate()->onStart()->onBind()->onUnbind()[重写该方法时返回了true]->onRebind()。


8.跨进程调用Service(AIDL服务)

(1)本地Service的onBind()方法会直接把IBinder对象本身传给客户端,但远程Service的onBind()方法只是将IBinder对象的代理传给了客户端,当客户端获取了远程Service的IBinder对象的代理之后,接下来就可通过该IBinder对象去回调远程Service的属性或方法了。

(2)AIDL接口中用到的数据类型,除了基本类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即使它们在同一个包中也需要导包。

(3)开发人员定义的AIDL接口只是定义了进程之间的通信接口,Service端、客户端都需要实现该接口。


AIDL接口代码:

interface ICat {String getColor();double getWeight();
}

(4)定义好上面的AIDL接口之后,ADT工具会自动生成一个ICat.java接口,在该接口里包含一个Stub内部类,该内部类实现了IBinder、ICat两个接口,这个Stub类将会作为远程Service的回调类——它实现了IBinder接口,因此可作为Service的onBind()方法的返回值。

(5)定义一个Service实现类,该Service的onBind()方法所返回的IBinder对象应该是ADT所生成的ICat.Stub的子类的实例。

(6)开发客户端的第一步就是将Service端的AIDL接口文件复制到客户端应用中。

(7)在ServiceConnection的onServiceConnected方法中需要对onBind()方法所返回的对象的代理进行处理:

     private ICat catService = ICat.Stub.asInterface(service);
(8)Android没有直接使用Java提供的序列化机制,而是提供了Parcelable这种轻量级的序列化机制,要求调用远程Service的参数和返回值都必须实现Parcelable接口。


定义Person类,先用AIDL来定义Person类:

     parcelable Person;
然后定义一个实现Parcelable接口的Person类,不仅要求实现该接口里定义的方法,而且要求在实现类中定义一个名为CREATOR、类型为Parcelable.Creator的静态Field以及两个函数:

@Override
public int describeContents() {return 0;
}@Override
public void writeToParcel(Parcel dest, int flags) {..............................................//该方法负责把Person对象的数据写入Parcel中
}public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {@Overridepublic Person createFromParcel(Parcel source) {....................................................}@Overridepublic Person[] newArray(int size) {....................................................}       
};

(9)在AIDL接口中定义方法时,需要指定形参的传递模式,一般都是采用传入参数的方式,因此下面指定为in模式:

interface IPet {List<Pet> getPets(in Person owner);
}
(10)除了由用户自行开发、启动的服务之外,Android系统本身提供了大量的系统服务,只要在程序中调用Context方法即可获得这些系统服务。

9.TelephonyManager是一个管理手机通话状态、电话网络信息的服务类,该类提供了大量的getXxx()方法来获取电话网络的相关信息。
  举例1:获取手机网络和SIM卡信息

  // 获取系统的TelephonyManager对象 TelephonyManager tManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);// 获取设备编号 tManager.getDeviceId();// 获取系统平台的版本tManager.getDeviceSoftwareVersion() != null ? tManager.getDeviceSoftwareVersion() : "未知";// 获取网络运营商代号tManager.getNetworkOperator();// 获取网络运营商名称tManager.getNetworkOperatorName();// 获取手机网络类型 tManager.getPhoneType();// 获取设备所在位置tManager.getCellLocation() != null ? tManager.getCellLocation().toString() : "未知位置";// 获取SIM卡的国别tManager.getSimCountryIso();// 获取SIM卡序列号tManager.getSimSerialNumber();// 获取SIM卡状态 tManager.getSimState();

  TelephonyManager还提供了一个listen(PhoneStateListener listener, int events)方法监听通话状态。
  举例2:监听手机来电信息

  // 创建一个通话状态监听器 PhoneStateListener listener = new PhoneStateListener() {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {// 来电铃响时case TelephonyManager.CALL_STATE_RINGING:OutputStream os = null;try {os = openFileOutput("phoneList", MODE_APPEND);} catch (FileNotFoundException e) {e.printStackTrace();   }PrintStream ps = new PrintStream(os);// 将来电号码记录到文件中ps.printIn(new Date() + "来电:" + incomingNumber);ps.close();break;default:break;}super.onCallStateChanged(state, incomingNumber);}};// 监听电话通话状态的改变tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
  可在data/data/<packagename>/files目录下查看phoneList文件。
  可将此段代码放在后台执行的Service中运行,并且设置Service组件随着系统开机自动运行。

  举例3:黑名单来电自动挂断
  * Android没有对外公开挂断电话的API,如果需要挂断电话,必须使用AIDL与电话管理服务进行通信,并调用服务中的API实现结束通话。
  为了调用远程的AIDL Service,开发者需要将Android源代码中如下两个文件复制到项目的相应位置:
  com.android.internal.telephony包下的ITelephony.aidl。
  android.telephony包下的NeighboringCellInfo.aidl。
  开发者需要在项目中建立对应的包,然后将这两个文件复制到相应的包下。
  接下来就可以在程序中调用ITelephony的endCall方法来挂断电话了。

  // 查询联系人的电话号码final Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);// getView()中对联系人列表的处理cursor.moveToPosition(position);String number = cursor.getString(cursor.getColumnIndex(Contacts.Contract.CommonDataKinds.Phone.NUMBER)).replace("-", "");  // 获取联系人的电话号码,并去掉中间的中划线// 当电话呼入时case TelephonyManager.CAL_STATE_RINGING:// 如果该号码属于黑名单Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);IBinder binder = (IBinder) method.invoke(null, new Object[] { TELEPHONY_SERVICE });   // 获取远程TELEPHONY_SERVICE的IBinder对象的代理ITelephony telephony = ITelephony.Stub.asInterface(binder);   // 将IBinder对象的代理转换为Itelephony对象telephony.endCall();   // 挂断电话 break;


10.短信管理器(SmsManager):
11.可调用AudioManager的常用方法控制手机音频:
  adjustStreamVolume(int streamType, int direction, int flags):调整手机指定类型的声音。
                                 第一个参数指定声音类型:STREAM_ALARM 手机闹铃的声音
STREAM_DTMF DTMF音调的声音
STREAM_MUSIC 手机音乐的声音
STREAM_NOTIFICATION 系统提示的声音 
STREAM_RING 电话铃声的声音
STREAM_SYSTEM 手机系统的声音
STREAM_VOICE_CALL 语音电话的声音
                                 第二个参数指定对声音进行增大、还是减少;
                 第三个参数是调整声音时的标志,例如指定FLAG_SHOW_UI,则指定调整声音时显示音量进度条。
  setMicrophoneMute(boolean on):设置是否让麦克风静音。
  setMode(int mode):设置声音模式,可设置的值有NORMAL、RINGTONE和IN_CALL。
  setRingerMode(int ringerMode):设置手机的电话铃声的模式。
                                                               RINGER_MODE_NORMAL:正常的手机铃声。
RINGER_MODE_SILENT:手机铃声静音。
RINGER_MODE_VIBRATE:手机振动。
  setSpeakerphoneOn(boolean on):设置是否打开扩音器。
  setStreamMute(int streamType, boolean state):将手机的指定类型的声音调整为静音。
  setStreamVolume(int streamType, int index, int flags):直接设置手机的指定类型的音量值。


12.AlarmManager通常用途为开发手机闹钟,本质是一个全局的定时器(退出程序后一样会启动指定组件) ,AlarmManager可在指定时间或指定周期启动其他组件(包括Activity、Service、BroadcastReceiver)。
  获取了AlarmManager对象之后,可调用方法来设置定时启动指定组件:
         void set(int type, long triggerAtTime, PendingIntent operation):设置在triggerAtTime时间启动由operation参数指定的组件。
                 其中第一个参数指定定时服务的类型:
                  ELAPSED_REALTIME 指定从现在开始时间过了一定时间后启动operation所对应的组件。
 ELAPSED_REALTIME_WAKEUP 指定从现在开始时间过了一定时间后启动operation所对应的组件。
                         即使系统关机也会执行operation所对应的组件。
 RTC:指定当系统调用System.currentTimeMillis()方法返回值与triggerAtTime相等时启动operation所对应的组件。
 RTC_WAKEUP 指定当系统调用System.currentTimeMillis()方法返回值与triggerAtTime相等时启动operation所对应的组件。
            即使系统关机也会执行operation所对应的组件。
         void setInexactRepeating(int type, long triggerAtTime, long interval, PendingIntent operation):设置一个非精确的周期性任务。
             例如设置Alarm每个小时启动一次,但系统并一定总在每个小时的开始启动Alarm服务。
         void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation):设置一个周期性执行的定时服务。
 void cancel(PendingIntent operation):取消AlarmManager的定时服务。


  举例1:设置闹钟

  Calendar currentTime = Calendar.getInstance();//  创建一个TimePickerDialog实例,并把它显示出来new TimePickerDialog(Activity.this, new TimePickerDialog.onTimeSetListener() {@Overridepublic void onTimeSet(TimePicker tp, int hourOfDay, int minute) {// 指定启动AlarmActivity组件Intent intent = new Intent(AlarmTest.this, AlarmActivity.class);// 创建PendingIntent对象PendingIntent pi = PendingIntent.getActivity(Activity.this, 0, intent, 0);Calendar c = Calendar.getInstance();c.setTimeInMillis(System.currentTimeMillis());// 根据用户选择时间来设置Calendar对象c.set(Calendar.HOUR, hourOfDay);c.set(Calendar.MINUTE, minute);// 设置AlarmManager将在Calendar对应的时间启动指定组件aManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);}}, currentTime.get(Calendar.HOUR_OF_DAY), currentTime.get(Calendar.MINUTE), false).show();

  举例2:定时更换壁纸
  *WallpaperManager提供了clear()方法来清除壁纸。

 //  设置每隔5秒执行pi代表的组件一次aManager.setRepeating(AlarmManager.RTC_WAKEUP, 0, 5000, pi);//  取消对pi的调度aManager.cancel(pi);//  定义定时更换的壁纸资源int[] wallpapers = new int[] {R.drawable.shuangta,R.drawable.lijiang,R.drawable.qiao,R.drawable.shui};// 重写service的onStart()方法,程序每次启动该Service都会执行onStart()方法中的代码@Overridepublic void onStart(Intent intent, int startId) {// 如果到了最后一张,系统重头开始if (current > = 4)current = 0;try {// 改变壁纸wManager.setResource(wallpapers[current++]);} catch(Exception e) {e.printStackTrace();}			 super.onStart(intent, startId);}


13.实现开机自动运行的Service:(1)让BroadcastReceiver监听Action为ACTION_BOOT_COMPLETED常量的Intent,然后在BroadcastReceiver中启动特定Service既可。
                                                           (2)授予应用程序访问系统开机事件的权限:<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />



http://chatgpt.dhexx.cn/article/IiGKJVIF.shtml

相关文章

大厂地震,疯狂裁员大换血,面试冲击大厂Android移动开发工程师就在此时

前段时间在准备面试跳槽Android高级工程师时&#xff0c;发现各个大厂都在疯狂裁员&#xff0c;对于处于大厂之中的程序员来说&#xff0c;无疑是一场大地震&#xff01;但对于新想要冲击大厂的朋友们来说也是一场非常大的机遇&#xff01; 不过在积极备战大厂时&#xff0c;发…

男子刷机多次拒绝来电 维修师傅的做法被网友怒赞

昨日&#xff0c;一段男子到维修店刷机的视频在抖音上火了&#xff0c;目前已经有18万人点赞。 视频画面中&#xff0c;一男子前往手机维修店&#xff0c;表示忘记密码要刷机。 师傅查看时手机突然来了个电话&#xff0c;维修师问男子要不要接一下电话&#xff0c;男子说“不接…

街电、来电、小电、怪兽们熬出了头?

配图来自Canva可画 近期&#xff0c;共享充电宝涨价的消息甚嚣尘上&#xff0c;一众涨价哀怨声中还夹杂着几条共享充电宝安全隐患的吐槽声。 2015年&#xff0c;共享经济崛起&#xff0c;万物共享的概念深入人心。彼时共享经济正火热&#xff0c;单车、充电宝、雨伞、鲜花等物…

安卓来电归属地_唯一数码带你看WWDC | 数码怪圈,安卓、IOS、WP居然互相抄袭

IOS一直是手机领域的系统高端产品&#xff0c;也一直是其他手机争相模仿的对象&#xff0c;不过这些年来&#xff0c;苹果是否有点“黔驴技穷”&#xff1f;比如这次WWDC2020开完后&#xff0c;网上一度的风评是&#xff1a;“苹果终于实装了这些安卓/WP上的功能。” 其实&…

安卓手机来电防火墙_手机号变“广告号”?来电显示暗藏黑色利益链!你可能也被卷入其中...

微调查&#xff1a;手机号变“广告号”&#xff1f;想取消&#xff0c;先交钱。来电显示暗藏黑色利益链&#xff01;道钉说说你现在还接谁的电话&#xff0c;你的内心独白是什么&#xff1f; 当下&#xff0c;几乎人人手机上都会有“来电显示”。智能手机还会显示特殊的“标注”…

Linux系统安装Nodejs详细教程

前言 第一次在Linux系统上安装Nodejs&#xff0c;我的服务器系统是CentOS 7&#xff0c;找了很多教程&#xff0c;都不是很详细完善&#xff0c;特此记录一下本人详细的安装过程。下面我们就开始吧&#xff01; 下载Node.js 方法一&#xff1a;下载到本地后上传到服务器 下…

Node.js 安装教程(Windows)

什么是Node.js&#xff1f; 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff1b; Node.js使用一个事件驱动、非阻塞式 I/O 的模型&#xff0c;使其轻量且高效&#xff1b; Node.js的软件包生态系统npm是全…

windows安装npm教程(nodejs)

1、在使用之前&#xff0c;先类掌握3个东西&#xff0c;明白它们是用来干什么的&#xff1a; npm: nodejs 下的包管理器。 webpack: 它主要用途是通过CommonJS 的语法把所有浏览器端需要发布的静态资源作相应的准备&#xff0c;比如资源的合并和打包。 vue-cli: 用户生成Vu…

Node.js下载及安装步骤

一、安装环境 1、本机系统&#xff1a;Windows 11&#xff08;64位&#xff09; 2、Node.js&#xff1a;v16.14.2LTS&#xff08;64位&#xff09; 二、安装Node.js步骤 1、下载对应系统的Node.js版本:Download | Node.js 2、选安装目录进行安装 3、环境配置 4、测试 三、前…

nodejs安装及环境配置详细教程

nodejs安装及环境配置一、nodejs安装环境 本机系统:Windows 10 Pro(64位) Node.js : 14.17.5(64位) nodejs安装及环境配置二、安装Node.js步骤 《1》下载对应你系统的Node.js版本: https://nodejs.org/en/download/ 《2》选安装目录进行安装 《3》环境配置 《4》测试 …

NodeJS、NPM安装配置步骤(windows版本)

原文章&#xff1a;NodeJS、NPM安装配置步骤(windows版本) 参考菜鸟教程学习nodeJS&#xff0c;碰到npm安装express&#xff0c;一直提示缺少xx文件之类的&#xff0c;终于找到解决方案了&#xff0c;原来要提前配置好环境变量的。 原文章棒棒哒&#xff0c;下面粘贴一下&…

2023年node.js最新版(18.15.0)详细安装教程(保姆级)

本文章作者本人卸载之后重新安装的完整详细教程, 包含了环境变量的详细配置,以及常见的错误解决方法 一. node.js安装与环境变量配置 1 .node.js下载(包含国内和国外下载地址) 1.国外的官网地址: Node.js (nodejs.org) 下载慢,下面提供国内地址. 可以看到当前的版本 LTS是大多用…

nodejs安装及环境配置

安装环境 本机系统&#xff1a;Windows 10 Pro&#xff08;64位&#xff09; Node.js : 14.17.5&#xff08;64位&#xff09; 安装Node.js步骤 《1》下载对应你系统的Node.js版本: https://nodejs.org/en/download/ 《2》选安装目录进行安装 《3》环境配置 《4》测试 前期准备…

ubuntu安装nodejs

推荐使用方法1进行安装 方法1&#xff1a; curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs如果安装nodejs 9.x版本 curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash - sudo apt-get install -y nodejs方法…

node.js 安装,详细步骤教程

本机环境&#xff1a;Windows 10 专业版 x64 1、下载安装包 Node.js 官方网站下载&#xff1a;https://nodejs.org/en/ 选择操作系统对应的包&#xff1a; 下载完成&#xff0c;安装包如下&#xff1a; 2、安装 打开安装&#xff0c;傻瓜式下一步即可&#xff1a; 选择安装位置…

Centos安装Nodejs简单方式

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。本文主要讲的是如何在Linux即Centos上安装Nodejs的简单方式&#xff0c;有比设置环境变量更加简单的方式&#xff0c;那就是设置软链接&#xff0c;软连接到已经设置环境变量的路径即可&#xff0c;如/usr/bin 1.官网 …

全网最详细的nodejs卸载和安装教程

因为项目需求&#xff0c;重装了3个版本的node.js&#xff0c;记录下完整过程&#xff0c;少走弯路少查资料。 一、卸载 1、Win菜单中找到Node.js的卸载程序&#xff0c;运行卸载程序。 2、点击是。 3、等待卸载完成。 4、删除C:\Users\用户名\AppData\Roaming目录下的npm和…

windows安装npm教程--nodejs

1、在使用之前&#xff0c;先掌握3个东西&#xff0c;明白它们是用来干什么的&#xff1a; npm: nodejs 下的包管理器。 webpack: 它主要用途是通过CommonJS 的语法把所有浏览器端需要发布的静态资源作相应的准备&#xff0c;比如资源的合并和打包。 vue-cli: 用户生成Vue工…

Node.js 下载安装教程

Node.js 下载安装教程 笔者的环境&#xff1a; Node.js 16.14.0&#xff08;npm 8.3.1&#xff09; Windows 10 教育版 【说明】 本教程讲述的是 Windows 下 Node.js 离线安装版的下载与配置。 一般来说&#xff0c;安装一个软件有 3 种方法&#xff1a;离线安装、在线安装、…

node.js安装及环境配置超详细教程【Windows系统安装包方式】

文章目录 Step1&#xff1a;下载安装包Step2&#xff1a;安装程序Step3&#xff1a;查看Step4&#xff1a;环境配置最后补充&#xff1a; Step1&#xff1a;下载安装包 https://nodejs.org/zh-cn/download/ 根据自己电脑系统及位数选择&#xff0c;我的电脑是Windows系统、64…