roi

阅读 / 问答 / 标签

谷歌平板android 5.0系统升级体验如何呢?

日前,谷歌已经发布消息称系统要更新为谷歌android 5.0,对于谷歌Nexus系列手机来说,谷歌android 5.0性能更佳,那么谷歌android 5.0究竟如何?我们体验一下吧! 谷歌平板电脑   性能:没什么太大问题 Nexus 10发布于2012年末,搭载了当时最先进的硬件,如2560*1600像素的超清屏幕,三星Exynos 5250双核处理器、2GB RAM+16GB ROM,整体性能介意iPad 3和iPad 4之间。同时,Nexus 10也是目前谷歌Nexus平板中唯一的一款10英寸机型,并且没有获得硬件更新。那么,它的性能是否能够满足Android 5.0的需求呢? 谷歌平板电脑 经过实际测试,我们发现Nexus 10运行Android 5.0的效果还是可以接受的。当然,你会偶尔遇到动画卡顿和应用程序无响应的问题,这也是意料之中。不过,使用省电模式,续航力表现还是不错的。   软件体验:有点浪费的宽屏 谷歌此次为Nexus 9配备了4:3比例的屏幕,还是令人略感意外的。一直以来,Android平板都采用了16:9或16:10的宽屏比例,但似乎用户们更喜欢4:3屏幕的使用体验,比如iPad系列,可以更好地应对阅读、网页、视频播放等体验。不过,这也导致16:10的Nexus 10存在一些界面兼容性问题。 有点浪费的宽屏 比如在主屏幕,我们可以看到大量的两侧空白区域,而这种现象不仅仅存在于主屏,包括谷歌的原生应用也都存在这种问题,更不用说第三方应用了,体验不是很好。 存在大量空白 谷歌针对软件厂商发布了Android 5.0平板界面的界面设计指导方针,可以看到主要是解决16:9屏幕侧面大量空白的问题。但从目前来看,大部分应用都存在这个明显的问题,用户在横向显示模式时的操作十分费力。 Material Design界面设计 当然,也有一些应用厂商先人一步,针对Android 5.0进行了优化,比如印象笔记、Sky Weather以及原生的Gmail等,都采用了三列式的Material Design界面设计,可以更好地满足Nexus 10 16:10屏幕的需求。   总结:

nexus4 android 5.0 怎么线刷

线刷升级步骤:1.电脑上下在刷机大师。2.手机用数据线连上电脑,安装驱动。3.下载适配rom包。4.rom包下载完成后点击一键刷机5.等待自动刷机完成。6.手机重启完成升级。刷机大师下载地址:http://soft2.mgyun.com/files/products/romasterlab/1023/2015/67174912/ROMaster_4.1.2_cid1023_140df15d.exe

如何向android添加内核驱动模块

1,同目录下的makefile,如## Makefile for industrial I/O Magnetometer sensors#obj-$(CONFIG_SENSORS_AK8975) += ak8975.oobj-$(CONFIG_SENSORS_HMC5843) += hmc5843.o2,同目录下的kconfig## Magnetometer sensors#comment "Magnetometer sensors"config SENSORS_AK8975 tristate "Asahi Kasei AK8975 3-Axis Magnetometer" depends on I2C help Say yes here to build support for Asahi Kasei AK8975 3-Axis Magnetometer. To compile this driver as a module, choose M here: the module will be called ak8975.3,总的config(配置变量为Y)各项目配置文件的位置不同,coffee:kernel/arch/arm/configs/M7023Q-debug-perf_defconfigjuice:common/customer/configs配置信息如下:# CONFIG_CFG80211 is not setCONFIG_EXPERIMENTAL=yCONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"CONFIG_SWAP=yCONFIG_ZRAM=mCONFIG_SYSVIPC=yCONFIG_SENSORS_AK8975=y ......查看变量是否在编译时配置成功:out/target/product/m7023q/obj/KERNEL_OBJ/include/generated/Autoconf.h查找CONFIG_SENSORS_AK8975若在编译时有配置成功,将找到这一行:#define CONFIG_SENSORS_AK8975 14、修改板级文件:4.0及后续项目统一在:kernel/arch/arm/mach-msm/board-qrd7627a.c注意juice中,很多配置(如tp)写在kernel/arch/arm/mach-msm/board-msm7627a-io.c在代码中增加新模块的内容,应该有两处,第一处设置函数和结构体,第二处实际调用,注意引用上述第3步新增的编译开关将代码限制起来。这些内容大多可以拷贝其它模块,但是名字要和driver中的相同,注意要改的地方除了名字之外,还有中断脚和I2C脚。其中固定模块的中断脚大部分时候不会改变(如tp就是int:48,reset:26),除非板子的datasheet特别注明才需要改变。但是I2C脚是会随着slaver device的改变而改变的,需要查清楚。配置platform_data:一般需要初始化一个xxx_platform_data结构体(这个结构体的声明应该让驱动文件可视,probe中才知道去读某个platformdata.yyy),并在i2c_board_info结构体中用.platform_data指向它,然后这个i2c_board_info将在板级文件中被注册(作为函数i2c_register_board_info()的参数)。而这个.platform_data很有可能在驱动的probe函数中调用到,例如:static struct msg2133_ts_platform_data msg2133_platformdata= { .irq = 0, .reset = GPIO_TP_RESET, };static struct i2c_board_info i2c_info_msg2133_dpt = { I2C_BOARD_INFO("msg2133", 0x27), .platform_data = &msg2133_platformdata,};i2c_info_msg2133_dpt.platform_data->irq = gpio_to_irq(GPIO_TP_INT);//结构体初始化的时候只能以常量赋值,因为此处需要做GPIO到irq的映射,所以要在此处赋值。i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID, &i2c_info_msg2133_dpt, 1);在驱动的probe中:pdata =client->dev.platform_data;    ...... = pdata.yyy; ......//(msg2133_ts_platform_data在该文件中可见)

怎么消除Android7.1.1中的Wi-Fi和移动网络上的X号

操作步骤1. 首先我们需要下载 ADB 工具包到电脑系统的根目录,现在你可以直接从Google 官方下载到这些工具,将其下载后解压缩至系统根目录。2. 进入工具包目录,按住 Shift 键,同时在文件夹空白处点击鼠标右键,选择「在此处打开命令窗口」,打开命令控制程序。3. 将手机通过 USB 连接至电脑,打开手机的 USB 调试选项,并选择在「允许使用此台电脑进行调试」中选择确定。4. 回到电脑桌面,在命令控制程序中,输入 adb shell。如果出现 $ 标志说明 adb 服务已经开启。如果没有看到可以反复尝试。5. 直接在 $ 标志后面输入以下命令:settings put global captive_portal_https_urlhttps://captive.v2ex.co/generate_2046. 输入完毕之后等命令控制行的光标回到 $ 后,直接输入 reboot 重启设备,开机之后再看设备的 Wi-Fi 和移动网络上那个小小叉号就没有了!备选方案:完全关闭网络检查服务如果你想一劳永逸,可以直接使用 ADB 命令关闭系统网络检查服务:adb shell settings put global captive_portal_detection_enabled 0需要说明的是,当遇到需要使用 portal 验证的网络(例如星巴克的免费无线网络)可能会无法连接。

Android8.1原生系统网络感叹号消除的方法

这是Android 5.0引入的网络评估机制:就是当你连上网络后,会给目标产生204响应的服务器发送给一个请求,如果服务器返回的是状态码为204的响应,那么就被认为网络可以访问;否则,如返回的是其他状态码,那么将被视为网络访问需要登录操作等;没有响应的话,就被认为是网络不可访问。这里的情况就是,目标服务器不能正常访问 加粗网址亲测可行,其余未测试,但可作为一个参考 http://connect.rom.miui.com/generate_204 http://www.v2ex.com/generate_204 https://captive.v2ex.co/generate_204 http://www.noisyfox.cn/generate_204 http://www.google.cn/ 测试系统:Android 8.1。默认使用https来验证,如要使用http,需要先写入关闭https验证的配置,再填写http服务器。然后开启飞行模式,再打开感叹号即可消失。其中,xxxxx即服务器的URL。 按照上述方法,设置captive_portal_mode的值如下: 0:彻底禁用检测 1:检测到需要登录则弹窗提醒(默认值) 2:检测到需要登录则自动断开此热点并不再自动连接

android 什么情况会导致wpa

plans for Chinese people.

android 优先级对无序广播生效?

同一优先级的广播接收器,动态的要比静态注册的早。动态注册:即由代码注册的广播接收器静态注册:即在 AndroidManifest.xml 中注册的广播接收器 优先级: 当广播为有序发送的时候,要按这个排序并顺序发送。 sendBroadcast 发送的是无序广播。sendOrderedBroadcast 发送的是有序广播。 好了,现在寻找问题原因,在找原因前肯定有这样的想法,一个有序队列,既然允许有相同的优先级存在,那么在同优先级内要不然有排序子因素,要不基就是按照某种操作可能影响顺序。后者可能性很大。 打开源码,顺着 动态注册广播接受器 找,最后是 ActivityManagerService.java 这个文件找到了 registerReceiver 的实现。同地也看到,存储的广播接收器列表是 HashMap mRegisteredReceivers 这个变理。 里面有一段代码为: ReceiverList rl = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); if (rl == null) { rl = new ReceiverList(this, callerApp, Binder.getCallingPid(), Binder.getCallingUid(), receiver); if (rl.app != null) { rl.app.receivers.add(rl); } else { try { receiver.asBinder().linkToDeath(rl, 0); } catch (RemoteException e) { return sticky; } rl.linkedToDeath = true; } mRegisteredReceivers.put(receiver.asBinder(), rl); } 在里面查找有没有这个 Receiver , 如果没有 put 进去。 看到这里貌似没有对广播的顺序做处理。是不是有别的地方做排序呢,找找成员变理,发现一个可疑的变量:final ArrayList mOrderedBroadcasts没错,感觉就应该是它了。 找找对它的操作,只有一处 mOrderedBroadcasts.set ,把代码摘录一下: BroadcastRecord r = new BroadcastRecord(intent, callerApp,callerPackage, callingPid, callingUid, requiredPermission,sticky, false); mOrderedBroadcasts.set(i, r);在这里放入了一个 BroadcastRecord 对像,而这个对像中主要的东西其实是 receivers向上跟踪 int NT = receivers != null ? receivers.size() : 0; int it = 0; ResolveInfo curt = null; BroadcastFilter curr = null; while (it < NT && ir < NR) { if (curt == null) { curt = (ResolveInfo)receivers.get(it); } if (curr == null) { curr = registeredReceivers.get(ir); } if (curr.getPriority() >= curt.priority) { // Insert this broadcast record into the final list. receivers.add(it, curr); ir++; curr = null; it++; NT++; } else { // Skip to the next ResolveInfo in the final list. it++; curt = null; } } 发现了一段 对 receivers 排序的代码,并且判断也是 priority 的值,用的是 >= 方式 感觉的找到了地方,但是对 Activity Manager Service 这个模块却更加的不懂了,以后有机会一定要分析一下这块是怎样设计的,才能确定本文的问题所在。暂时记录,以后分析!

android有序广播和无序广播的区别

同一优先级的广播接收器,动态的要比静态注册的早。动态注册:即由代码注册的广播接收器静态注册:即在 AndroidManifest.xml 中注册的广播接收器 优先级: 当广播为有序发送的时候,要按这个排序并顺序发送。 sendBroadcast 发送的是无序广播。sendOrderedBroadcast 发送的是有序广播。 好了,现在寻找问题原因,在找原因前肯定有这样的想法,一个有序队列,既然允许有相同的优先级存在,那么在同优先级内要不然有排序子因素,要不基就是按照某种操作可能影响顺序。后者可能性很大。 打开源码,顺着 动态注册广播接受器 找,最后是 ActivityManagerService.java 这个文件找到了 registerReceiver 的实现。同地也看到,存储的广播接收器列表是 HashMap mRegisteredReceivers 这个变理。 里面有一段代码为: ReceiverList rl = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); if (rl == null) { rl = new ReceiverList(this, callerApp, Binder.getCallingPid(), Binder.getCallingUid(), receiver); if (rl.app != null) { rl.app.receivers.add(rl); } else { try { receiver.asBinder().linkToDeath(rl, 0); } catch (RemoteException e) { return sticky; } rl.linkedToDeath = true; } mRegisteredReceivers.put(receiver.asBinder(), rl); } 在里面查找有没有这个 Receiver , 如果没有 put 进去。 看到这里貌似没有对广播的顺序做处理。是不是有别的地方做排序呢,找找成员变理,发现一个可疑的变量:final ArrayList mOrderedBroadcasts没错,感觉就应该是它了。 找找对它的操作,只有一处 mOrderedBroadcasts.set ,把代码摘录一下: BroadcastRecord r = new BroadcastRecord(intent, callerApp,callerPackage, callingPid, callingUid, requiredPermission,sticky, false); mOrderedBroadcasts.set(i, r);在这里放入了一个 BroadcastRecord 对像,而这个对像中主要的东西其实是 receivers向上跟踪 int NT = receivers != null ? receivers.size() : 0; int it = 0; ResolveInfo curt = null; BroadcastFilter curr = null; while (it < NT && ir < NR) { if (curt == null) { curt = (ResolveInfo)receivers.get(it); } if (curr == null) { curr = registeredReceivers.get(ir); } if (curr.getPriority() >= curt.priority) { // Insert this broadcast record into the final list. receivers.add(it, curr); ir++; curr = null; it++; NT++; } else { // Skip to the next ResolveInfo in the final list. it++; curt = null; } } 发现了一段 对 receivers 排序的代码,并且判断也是 priority 的值,用的是 >= 方式 感觉的找到了地方,但是对 Activity Manager Service 这个模块却更加的不懂了,以后有机会一定要分析一下这块是怎样设计的

android有序广播和无序广播的区别

同一优先级的广播接收器,动态的要比静态注册的早。动态注册:即由代码注册的广播接收器静态注册:即在 AndroidManifest.xml 中注册的广播接收器 优先级: 当广播为有序发送的时候,要按这个排序并顺序发送。 sendBroadcast 发送的是无序广播。sendOrderedBroadcast 发送的是有序广播。 好了,现在寻找问题原因,在找原因前肯定有这样的想法,一个有序队列,既然允许有相同的优先级存在,那么在同优先级内要不然有排序子因素,要不基就是按照某种操作可能影响顺序。后者可能性很大。 打开源码,顺着 动态注册广播接受器 找,最后是 ActivityManagerService.java 这个文件找到了 registerReceiver 的实现。同地也看到,存储的广播接收器列表是 HashMap mRegisteredReceivers 这个变理。 里面有一段代码为: ReceiverList rl = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); if (rl == null) { rl = new ReceiverList(this, callerApp, Binder.getCallingPid(), Binder.getCallingUid(), receiver); if (rl.app != null) { rl.app.receivers.add(rl); } else { try { receiver.asBinder().linkToDeath(rl, 0); } catch (RemoteException e) { return sticky; } rl.linkedToDeath = true; } mRegisteredReceivers.put(receiver.asBinder(), rl); } 在里面查找有没有这个 Receiver , 如果没有 put 进去。 看到这里貌似没有对广播的顺序做处理。是不是有别的地方做排序呢,找找成员变理,发现一个可疑的变量:final ArrayList mOrderedBroadcasts没错,感觉就应该是它了。 找找对它的操作,只有一处 mOrderedBroadcasts.set ,把代码摘录一下: BroadcastRecord r = new BroadcastRecord(intent, callerApp,callerPackage, callingPid, callingUid, requiredPermission,sticky, false); mOrderedBroadcasts.set(i, r);在这里放入了一个 BroadcastRecord 对像,而这个对像中主要的东西其实是 receivers向上跟踪 int NT = receivers != null ? receivers.size() : 0; int it = 0; ResolveInfo curt = null; BroadcastFilter curr = null; while (it < NT && ir < NR) { if (curt == null) { curt = (ResolveInfo)receivers.get(it); } if (curr == null) { curr = registeredReceivers.get(ir); } if (curr.getPriority() >= curt.priority) { // Insert this broadcast record into the final list. receivers.add(it, curr); ir++; curr = null; it++; NT++; } else { // Skip to the next ResolveInfo in the final list. it++; curt = null; } } 发现了一段 对 receivers 排序的代码,并且判断也是 priority 的值,用的是 >= 方式 感觉的找到了地方,但是对 Activity Manager Service 这个模块却更加的不懂了,以后有机会一定要分析一下这块是怎样设计的,才能确定本文的问题所在。暂时记录,以后分析!

skype Android版怎么发起视频通话

大家都应该知道skype是一款通讯软件,具备了IM的所需功能,skype能语音通话、文字聊天、传送文件、视频通话等功能。那么大家就有疑问了,skype这么多版本中,所有版本的功能都是一样的操作吗?下面小编就针对skypeAndroid版中的视频通话来给大家详细详解一下。Skype(网络电话)V7.27.0.101绿色便携版  人气:12789下载Skype具有IM软件所需的基本功能,高清语音视频通话永久免费。另外可支持Skype好友间24方...大小:31.3MB  更新:08-29  类型:聊天工具  免费软件  简体中文一、skype发起视频通话1.打开skype软件,登录skype后,在skype联系人列表中选择一位您想要视频通话的联系人。2.在您想要视频通话的联系人右边有个视频通话图标,点击“视频通话”(如下图)3.这时候,屏幕发生了变化,应答声直到对方接起来才停止(如下图)注意:在使用skype通话过程中可以打开视频设备,然后在通话过程中点击视频摄像头图标,开始传送视频图像就可以了。您可以在以下摄像头选项中进行选择:(1)前置摄像头:切换至前置摄像头。(2)后置摄像头:切换至后置摄像头。(3)关闭摄像头:选择此选项会关闭您的摄像头(但是,您还可以接收视频)。二、手动设置skype视频通话1.打开skype软件,登录skype后,在运行Android3.0或者更高版本的手机上点击菜单按钮或者点击菜单图标。2.接着选择设置,然后勾选启用视频通话。注意:如果看不到视频通话设置,这说明您的Android手机没有满足skype视频通话的最低要求。三、skype用户和Messenger好友视频通话1.如果您想使用Microsoft账户登录skype之后,就就可以和您的Messenger好友视频通话,就像与您的skype联系人视频通话一样。2.如果您的Messenger好友需要安装skype插件才能接听您的视频通话。当您第一次视频通话他们的时候,他们会看到skype插件安装提示。在他们升级到skype之后,你们就能一起享受所有skype功能带来的乐趣了。四、skype保证视频通话质量首先,大家要注意视频通话的质量取决于可用网络的条件。如果您的数据连接传输速度越快,那么您的视频通话的质量就越好。我们建议您不要在视频通话的同时运行许多其它应用程序,因为这些应用程序会占用您手机的内存。五、设置skype视频通话1.打开skype软件,登录skype后,在运行Android3.0或者更高版本的手机上点击菜单按钮或者菜单图标。2.选择设置,下拉之启用视频通话设置,通过视频通话设置修改隐私选项和通话质量选项。3.您可以通过以下的选项中进行设置:(1)通话接听管理:您可以选择接听谁发起的skype视频通话。您可以使用此选项阻止陌生人发起的视频通话。(2)技术信息:如果想查看有关您的通话的技术信息您可以选择此选项。(3)视频质量:选择您的视频通话质量。视频通话质量越高,使用的流量就越多。(4)自动接听通话:如果希望自动接听呼入的语音和视频通话,您可以选择此选项。看了小编给大家带来的文章,大家还满意吗?这么好用的软件,没用过的网友们,你们还在犹豫什么呢?快来下载吧!还想要知道更多关于skype的精彩文章吗?想要知道的网友们请关注!在这里会有很多skype精彩文章等着大家来看哦!下面小编给大家推荐一些相关阅读:skypewin8怎么快速找联系人skype怎么接受联系人的请求

如何在 Android 手机上实现抓包

千锋扣丁学堂Android开发为您解答:  tcpdump是最快捷方便的抓包方式,还可以加深对网络协议的理解。android下可以通过如下方式抓包:  1 Android上启动tcpdump  Android设备可以把tcpdump的可执行文件上传到android设备上,然后通过mac远程登录android设备运行tcpdump,前提是这台android设备必须已经root过。步骤如下:  下载android版本的tcpdump为android系统编译的tcpdump版本。  通过adb将tcpdump上传到android设备  通过adb push将tcpdump文件上传到特定的目录,这里我们选择/sdcard/data目录。  在android设备上运行tcpdump  通过adb shell登陆设备,并执行tcpdump,最后一步执行./tcpdump即可。  2. 分析tcpdump输出  经过上面的步骤成功运行tcpdump之后,接下来就可以分析输出的网络包内容了,iOS设备和Android设备的输出是一致的。我们先来解析下几个基本的格式:  图中红色方框内的部分是一个ip包的详细记录,类似的纪录还有好几条。这里我们着重分析第一条的各部分字段含义。  14:37:41.615018 很简单,是该包接收到的时间。  17.143.164.37.5223 是发送方的ip地址及端口号(5223是端口号)。  10.29.44.140.58036 是我android的ip地址及端口号。  Flags [P.] 是tcp包header部分的第14个字节的P位。这个字节所包含的几个flag很重要,后面我会单独详细讲解。这里P位表示接受方需要马上将包push到应用层。  seq 1:54 tcp包的seq号,1是起始值,54结束值。tcp之所以被认为是流,是因为tcp包所携带的每一个字节都有标号(seq号)。1:54表明总共有54个字节被接受,其中一个字节是三次握手阶段所使用,所以一共发送的长度是53字节。  ack 101 tcp包的ack号,ack 101表明seq号为100的字节已被确认收到,下一个期望接收的seq号从101开始。  win 255 win表示的是tcp包发送方,作为接受方还可以接受的字节数。这里win 255表明ip为17.143.164.37的主机还可以接受255个字节。  options [nop,nop,…] options[…]表示的是该tcp包的options区域,nop是no opertion的缩写,没什么实际用途,主要是用做padding,因为options区域按协议规定必须是4字节的倍数。  options[… TS val 2381386761] ts val这个值是tcp包的时间戳,不过这个时间戳和设备的系统时间没啥关系,刚开始是随机值,后面随着系统时钟自增长。这个时间戳主要用处是seq序列号越界从0重新开始后,可以确认包的顺序。  options[… ecr 427050796] ts ecr这个值主要用来计算RTT。比如A发送一个tcp包给B,A会在包里带上TS val,B收到之后在ack包里再把这个值原样返回,A收到B的ack包之后再根据本地时钟就可以计算出RTT了。这个值只在ack包里有效,非ack包ecr的值就为0.  length 53 这个length是应用层传过来的数据大小,不包括tcp的header。这个值和我们上面分析的seq 1:54是一致的。  以上就是一个基本的tcp包结构,大家可以按照上面的分析再把其他几个包理解下。我们在做应用的时候面对的更多是http协议,但对一个http请求是怎么通过tcp/ip分解成一个个的packet,然后怎么在网络上稳定可靠的传输,要有个基本的印象。下面我们再看下tcpdump更多的功能,这些功能都是基于对tcp/ip协议的理解,遇到不理解的建议多google下相关的技术概念。  3. tcpdump知识拓展  再继续深入tcpdump之前,先贴上一张tcp header格式图,常看常新。  [https://github.com/music4kid/music4kid.github.io/blob/master/images/tcpheader.png?raw=true](https://github.com/music4kid/music4kid.github.io/blob/master/images/tcpheader.png?raw=true)" width="1056">  3.1 TCP Flags(tcp header第十四个字节)  我们再仔细看下上面提到的flags概念,flags位于tcp header的第十四个字节,包含8个比特位,也就是上图的CWR到FIN。这8个比特位都有特定的功能用途,分别是:CWR,ECE,URG,ACK,PSH,RST,SYN,FIN。  CWR ,ECE 两个flag是用来配合做congestion control的,一般情况下和应用层关系不大。发送方的包ECE(ECN-Echo)为0的时候表示出现了congestion,接收方回的包里CWR(Congestion Window Reduced)为1表明收到congestion信息并做了处理。我们重点看其他六个flag。  URG URG代表Urgent,表明包的优先级高,需要优先传送对方并处理。像我们平时使用terminal的时候经常ctrl+c来结束某个任务,这种命令产生的网络数据包就需要urgent。  ACK 也就是我们所熟悉的ack包,用来告诉对方上一个数据包已经成功收到。不过一般不会为了ack单独发送一个包,都是在下一个要发送的packet里设置ack位,这属于tcp的优化机制,参见delayed ack。  PSH Push我们上面解释过,接收方接收到P位的flag包需要马上将包交给应用层处理,一般我们在http request的最后一个包里都能看到P位被设置。  RST Reset位,表明packet的发送方马上就要断开当前连接了。在http请求结束的时候一般可以看到一个数据包设置了RST位。  SYN SYN位在发送建立连接请求的时候会设置,我们所熟悉的tcp三次握手就是syn和ack位的配合:syn->syn+ack->ack。  FIN Finish位设置了就表示发送方没有更多的数据要发送了,之后就要单向关闭连接了,接收方一般会回一个ack包。接收方再同理发送一个FIN就可以双向关闭连接了。  这8个flag首字母分别是:C E U A P R S F。初看难以记忆,我脑洞了下,把它们组合成 supr cafe,当然少了super少了个e,我可以将就下。我们在使用tcpdump的时候会经常看到这几个flag,[S],[P],[R],[F],[.]。其他几个都好理解,[.]特殊点,是个占位符,没有其他flag被设置的时候就显示这个占位符,一般表示ack。  3.2 tcpdump 更多使用参数  这部分我们来看下tcpdump常用的一些命令参数。文章最开始部分的tcpdump命令是这样的:sudo tcpdump -i rvi0 -AAl。 -i rvi0 -AAl都是属于参数部分。常见的有这些:  -i, 要监听的网卡名称,-i rvi0监听虚拟网卡。不设置的时候默认监听所有网卡流量。  -A, 用ASCII码展示所截取的流量,一般用于网页或者app里http请求。-AA可以获取更多的信息。  -X,用ASCII码和hex来展示包的内容,和上面的-A比较像。-XX可以展示更多的信息(比如link layer的header)。  -n,不解析hostname,tcpdump会优先暂时主机的名字。-nn则不展示主机名和端口名(比如443端口会被展示成https)。  -s,截取的包字节长度,默认情况下tcpdump会展示96字节的长度,要获取完整的长度可以用-s0或者-s1600。  -c,只截取指定数目的包,然后退出。  -v,展示更多的有用信息,还可以用-vv -vvv增加信息的展示量。  src,指明ip包的发送方地址。  dst,指明ip包的接收方地址。  port,指明tcp包发送方或者接收方的端口号。  and,or,not,操作法,字面意思。  上面几个是我个人比较常用的,更多的参数可以参考这个详细文档。有兴趣的可以分析下面几个例子练习下:  tcpdump ‘tcp[13] & 16!=0"  tcpdump src port 80 and tcp  tcpdump -vv src baidu and not dst port 23  tcpdump -nnvvS src 192.0.1.100 and dst port 443  4. 用tcpdump分析http完整请求  说了这么多,我们再来实战下,看一个完整的http请求流程。sudo tcpdump -i rvi0 -AAl src 60.28.215.123 or dst 60.28.215.123  列出了6个前面的packet,10.29.44.240是我android的ip地址,60.28.215.123是知乎server的ip地址,红色方框内是android发出的packet,白色方框内是server发出的packet。packet1是android三次握手的第一个syn包,packet2是server ack+syn的包,packet3是android ack的包。这3个packet之后tcp的三次握手就完成了。  packet4是android发出的http request。长度只有240个字节,所以一个packet就发过去了,当然还设置了flags的P位,request需要马上被应用层处理。包里面出现了spdy,点赞。  packet5是server ack刚收到的包,长度位0,所以这仅仅是一个ack包。  packet6是server返回http的response了,1388个字节。packet5和packet6都ack了seq为241的包,当然是为了增加ack的成功率。  中间还有好几个packet就不仔细分析了,最后再看下请求完成的最后几个包:  最后两个packet比较简单,android发送个FIN+ACK的包就断开连接了,server直接发送了一个RST包后也断开连接了。

为什么我这么写Android的通知点击按钮的时候通知发不出来?附代码

//注册按钮广播privatevoidsetButtonBroadCast(){finalStringSTATUS_BAR_COVER_CLICK_ACTION="download";getDownNotification().contentView.setViewVisibility(R.id.downloadCancle,View.VISIBLE);BroadcastReceiveronClickReceiver=newBroadcastReceiver(){privatebooleanflag=false;@OverridepublicvoidonReceive(Contextcontext,Intentintent){if(intent.getAction().equals(STATUS_BAR_COVER_CLICK_ACTION)){//在这里处理点击事件interceptFlag=true;//取消通知栏}}};IntentFilterfilter=newIntentFilter();filter.addAction(STATUS_BAR_COVER_CLICK_ACTION);mContext.registerReceiver(onClickReceiver,filter);IntentbuttonIntent=newIntent(STATUS_BAR_COVER_CLICK_ACTION);PendingIntentpendButtonIntent=PendingIntent.getBroadcast(mContext,0,buttonIntent,0);getDownNotification().contentView.setOnClickPendingIntent(R.id.downloadCancle,pendButtonIntent);//R.id.trackname为你要监听按钮的id//mRemoteViews.setOnClickPendingIntent(R.id.trackname,pendButtonIntent);});

android收到推送通知消息会不会启动application

首先是开机自启动的功能实现,代码如下:1. AndroidManifest.xml中添加如下代码:复制代码 1 <!-- 抓取系统启动事件 --> 2 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 3 4 <application> 5 ….. 6 <service 7 android:name="com.demo.notification.NotificationService" 8 android:icon="@drawable/icon" 9 android:label="@string/app_name" >10 </service>11 12 <receiver android:name="com.demo.notification.MyScheduleReceiver" >13 <intent-filter>14 <action android:name="android.intent.action.BOOT_COMPLETED" />15 </intent-filter>16 </receiver>17 </application>复制代码2. 接着是实现MyScheduleReceiver代码,这是当Android启动后会自动启动的程序。复制代码1 public class MyScheduleReceiver extends BroadcastReceiver {2 3 @Override4 public void onReceive(Context context, Intent intent) {5 6 Intent service = new Intent(context, NotificationService.class);7 context.startService(service);8 }9 }复制代码3. 实现NotificationService代码,用来接收推送消息复制代码 1 public class NotificationService extends Service { 2 private final IBinder mBinder = new MyBinder(); 3 4 @Override 5 public int onStartCommand(Intent intent, int flags, int startId) { 6 // 将接收推送消息任务放入后台执行 7 new ZeroMQMessageTask().execute(); 8 9 return Service.START_STICKY;10 }11 12 @Override13 public IBinder onBind(Intent arg0) {14 return mBinder;15 }16 17 public class MyBinder extends Binder {18 public NotificationService getService() {19 return NotificationService.this;20 }21 }22 23 private class ZeroMQMessageTask extends AsyncTask<String, Void, String> {24 25 public ZeroMQMessageTask() {26 }27 28 @Override29 protected String doInBackground(String... params) {30 31 ZMQ.Context context = ZMQ.context(1);32 ZMQ.Socket subscriber = context.socket(ZMQ.SUB);33 subscriber.subscribe(ZMQ.SUBSCRIPTION_ALL);34 subscriber.connect("tcp://x.x.x.x:xxxx");35 while (true) { // 通过不终止的循环来保证接收消息36 message = subscriber.recvStr();37 if (!message.equals("0")) { // 0是由我自己定义的空消息标识,可以替换成自定义的其它标识38 39 // 显示推送消息40 String ns = Context.NOTIFICATION_SERVICE;41 NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);42 43 int icon = R.drawable.icon;44 CharSequence tickerText = "Demo - " + message;45 long when = System.currentTimeMillis();46 47 Notification notification = new Notification(icon,48 tickerText, when);49 notification.flags |= Notification.FLAG_AUTO_CANCEL;50 Context uiContext = getApplicationContext();51 CharSequence contentTitle = "Demo";52 CharSequence contentText = message;53 Intent notificationIntent = new Intent(uiContext,54 NotificationService.class);55 PendingIntent contentIntent = PendingIntent56 .getActivity(uiContext, 0, notificationIntent, 0);57 58 notification.setLatestEventInfo(uiContext, contentTitle,59 contentText, contentIntent);60 61 mNotificationManager.notify(1, notification);62 }63 }64 }65 66 @Override67 protected void onPostExecute(String result) {68 }69 }70 }

android 注册广播有几种方式,这些方式有何优缺点

一般来说,一种是动态注册,即 用java代码直接注册, 如oncreate(){ this.registerreceiver(new yourbroadcast, Intenfilter i);}当然你也在其他如onstart里注册,看你的业务是什么要求了。取消注册在对应的方法里。一般是对应的,oncreate-onDestroy onstart-onstop另一种就是xml文件注册了。

Android 中如何在server 中动态注册广播。

54735+5145=

Android 开发,Launch开机自启动APP总是出现提示框,设置了之后还是会出现,说是要求回

android如何实现开机自动启动Service或app(转)第一步:首先创建一个广播接收者,重构其抽象方法 onReceive(Context context, Intent intent),在其中启动你想要启动的Service或app。 import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class BootBroadcastReceiver extends BroadcastReceiver { //重写onReceive方法 @Override public void onReceive(Context context, Intent intent) { //后边的XXX.class就是要启动的服务 Intent service = new Intent(context,XXXclass); context.startService(service); Log.v("TAG", "开机自动服务自动启动....."); //启动应用,参数为需要自动启动的应用的包名 Intent intent = getPackageManager().getLaunchIntentForPackage(packageName); context.startActivity(intent ); } } 第二步:配置xml文件,在receiver接收这种添加intent-filter配置 第三步:添加权限 2、自启动失败的原因接收不到BOOT_COMPLETED广播可能的原因(1)、BOOT_COMPLETED对应的action和uses-permission没有一起添加(2)、应用安装到了sd卡内,安装在sd卡内的应用是收不到BOOT_COMPLETED广播的(3)、系统开启了Fast Boot模式,这种模式下系统启动并不会发送BOOT_COMPLETED广播(4)、应用程序安装后重来没有启动过,这种情况下应用程序接收不到任何广播,包括BOOT_COMPLETED、ACTION_PACKAGE_ADDED、CONNECTIVITY_ACTION等等。Android3.1之后,系统为了加强了安全性控制,应用程序安装后或是(设置)应用管理中被强制关闭后处于stopped状态,在这种状态下接收不到任何广播。直到被启动过(用户打开或是其他应用调用)才会脱离这种状态,所以Android3.1之后(1)、应用程序无法在安装后自己启动(2)、没有ui的程序必须通过其他应用激活才能启动,如它的Activity、Service、Content Provider被其他应用调用。存在一种例外,就是应用程序被adb push you.apk /system/app/下是会自动启动的,不处于stopped状态。具体说明见:http://developer.android.com/about/versions/android-3.1.html#launchcontrolshttp://commonsware.com/blog/2011/07/13/boot-completed-regression-confirmed.html 3、adb发送BOOT_COMPLETED我们可以通过1adb shell am broadcast -aandroid.intent.action.BOOT_COMPLETED命令发送BOOT_COMPLETED广播,而不用重启测试机或模拟器来测试BOOT_COMPLETED广播,这条命令可以更精确的发送到某个package,如下:1adb shell am broadcast -aandroid.intent.action.BOOT_COMPLETED-candroid.intent.category.HOME-npackage_name/class_name

android 环信怎么接收透传消息

注册透传消息广播如下:// 透传广播 IntentFilter cmdIntentFilter = new IntentFilter(EMChatManager.getInstance().getCmdMessageBroadcastAction()); CMDBroadcastReceiver cmdMessageReceiver = new CMDBroadcastReceiver(); appContext.registerReceiver(cmdMessageReceiver, cmdIntentFilter); 发送透传消息如下:EMMessage cmdMsg = EMMessage.createSendMessage(EMMessage.Type.CMD);// 透传消息 //支持单聊和群聊,默认单聊,如果是群聊添加下面这行 // cmdMsg.setChatType(ChatType.GroupChat); //action可以自定义,在广播接收时可以收到 CmdMessageBody cmdBody = new CmdMessageBody(action); cmdMsg.addBody(cmdBody); // 给自己的好友发送通知 if (IMHelper.getInstance().getImUserList() != null && IMHelper.getInstance().getImUserList().size() > 0) { for(IMUser imUser:IMHelper.getInstance().getImUserList()){ if(!imUser.getUid().equals(curUsername)){// 不给自己发送这条消息 cmdMsg.setReceipt(imUser.getUid());// 接收这条通知的人id cmdMsg.setAttribute("ToUsername",curUsername);// 需要修改当前用户的头像id cmdMsg.setAttribute(key,obj);//支持自定义扩展 sendCMDMessage(cmdMsg); } } }private static void sendCMDMessage(EMMessage cmdMsg){ EMChatManager.getInstance().sendMessage(cmdMsg,new EMCallBack() { @Override public void onSuccess() { // 发送成功 } @Override public void onProgress(int arg0, String arg1) { // 发送进度 } @Override public void onError(int arg0, String arg1) { // 发送失败 } }); }接收透传的广播如下:public class CMDBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Log.d("ME", "进入到广播啦"); if(intent!=null){ //获取cmd message对象 String msgId = intent.getStringExtra("msgid"); EMMessage message = intent.getParcelableExtra("message"); //获取消息body CmdMessageBody cmdMsgBody = (CmdMessageBody) message.getBody(); String aciton = cmdMsgBody.action;//获取自定义action if(IMConstants.ACTION_UPDATE_USER_AVATAR.equals(aciton)){// 更新头像指令 updateAvatar(message); }else if(IMConstants.ACTION_UPDATE_USER_NICK.equals(aciton)){// 更新昵称 updateNick(message); } } }

android 中 自己写的activity 的优先级怎么才能大于系统的 譬如来电 自己已经获取号码并写了一个activity

Google Android平台在设计程序声明周期上比较特殊,可能是考虑到第二次加载时保证速度的原因而没有强制加入内存释放问题,所有的资源回收由Dalvik GC自动完成,所以在设计开发时一定要注意Activity和 Service类的生命周期问题,显示在最上层的窗口将有最高的优先级,当Android操作系统内存不够用时自动将会根据历史栈按优先级强制杀掉进程。

如何使Android应用开机时自动启动

在主配置文件里面是有一个权限的就是开机启动的,会发送一个广播通知的

android fragemnt已经onstop为什么还能接受广播

这个流程,一个service附带数据发送广播到这个fragment,然后在fragment里面绑定service注册广播,在里面建一个广播类他有一个方法onreceive,这里用来处理service发送的数据,我在这里面接受数据然后发给handlemessage然后刷新adapter,这一切在activity里面没问题,但是在fragment里面他也接收数据,但是他到了刷新适配器的时候,直接空指针,他这什么机制 ,在fragment里面不刷新广播发送的数据?在广播和handlemessage里面直接对ui可以操作,但是adapter.notify就完蛋

如何实现android蓝牙开发 自动配对连接,并不弹出提示框

这个还是一样回弹出来

为什么android alarmmanager 也会睡眠

  AlarmManager实质是一个全局的定时器,是Android中常用的一种系统级别的提示服务,在指定时间或周期性启动其它组件(包括Activity,Service,BroadcastReceiver)。  概述:  该类提供一种访问系统闹钟服务的方式,允许你去设置在将来的某个时间点去执行你的应用程序。当你的闹钟响起(时间到)时,在它上面注册的一个意图(Intent)将会被系统以广播发出,然后自动启动目标程序,如果它没有正在运行。注册的闹钟会被保留即使设备处于休眠中(如果闹钟在给定时间响起可以选择是否唤醒设备)。如果闹钟关闭或者重启,闹钟将被清除。  只要广播的onReceive()方法正在执行,这闹钟管理者(AlarmManager)会持有一个CPU唤醒锁,这是为了保证手机不会休眠直到处理完该广播,一旦onReceive()返回,那么闹钟管理者将会释放唤醒锁。这意味着只要OnReceive()方法完成,你的手机可能在某些情况下进入休眠,如果你的闹钟广播接收者调用的是Context.startService(),那么手机有可能在被请求的服务执行之前进入休眠,为了防止这种情况,你的BroadcastReceiver和服务需要实现一个单独的唤醒锁策略以确保手机继续运行,直到服务可用。  注:该类适用于你想让应用程序在将来某个指定时间点执行的情况,即使你的应用程序现在没有运行。对一般的时间操作,使用Handler是更容易和更有效率的。

如何判断android 短信发送是否成功

private void mySendMessage(String phoneNum, String content) { String SENT_SMS_ACTION = "SENT_SMS_ACTION"; Intent sentIntent = new Intent(SENT_SMS_ACTION); PendingIntent sentPI = PendingIntent.getBroadcast( context.getApplicationContext(), 0, sentIntent, 0); // register the Broadcast Receivers context.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context _context, Intent _intent) { switch (getResultCode()) { case Activity.RESULT_OK: handler.sendEmptyMessage(Mark.SMS_SUCCESS); //成功 下面的都是不成功 break; case SmsManager.RESULT_ERROR_GENERIC_FAILURE: case SmsManager.RESULT_ERROR_RADIO_OFF: case SmsManager.RESULT_ERROR_NULL_PDU: handler.sendEmptyMessage(Mark.SMS_FAIL); break; default: handler.sendEmptyMessage(Mark.SMS_FAIL); break; } } }, new IntentFilter(SENT_SMS_ACTION)); // 直接调用短信接口发短信 SmsManager smsManager = SmsManager.getDefau

怎么用android获取bluetooth的信号强度

1.oncreate面增加 注册扫描广播 public void onCreate(Bundle savedInstanceState) { // 注册始发现广播 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED); this.registerReceiver(mReceiver, filter); } 2.新建BroadcastReceiver广播象并实现面onreceive,onreceiverssi(信号强度) private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //设备始扫描 if (BluetoothDevice.ACTION_FOUND.equals(action)) { //IntentblueDevice象 BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device.getBondState() != BluetoothDevice.BOND_BONDED) { //信号强度 short rssi = intent.getExtras().getShort( BluetoothDevice.EXTRA_RSSI); } } } };

android广播机制的Android广播机制简介

在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理。这个广播跟我们传统意义中的电台广播有些相似之处。之所以叫做广播,就是因为它只负责“说”而不管你“听不听”,也就是不管你接收方如何处理。另外,广播可以被不只一个应用程序所接收,当然也可能不被任何应用程序所接收。广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。Android中广播的是操作系统中产生的各种各样的事件。例如,收到一条短信就会产生一个收到短信息的事件。而Android操作系统一旦内部产生了这些事件,就会向所有的广播接收器对象来广播这些事件。1.1 广播接收器BroadcastReceiverBroadcastReceiver(广播接收器)是为了实现系统广播而提供的一种组件,并且广播事件处理机制是系统级别的。比如,我们可以发出一种广播来测试是否收到短信,这时候就可以定义一个BraodcastReceiver来接受广播,当收到短信时提示用户。我们既可以用Intent来启动一个组件,也可以用sendBroadcast()方法发起一个系统级别的事件广播来传递消息。我们也可以在自己的应用程序中开发BroadcastReceiver,然后把广播接收器这个类或者对象注册到Android操作系统上去,让操作系统知道现在有这样一个广播接收器正在等待接收Android操作系统的广播,即在自己的应用程序中实现BroadcastReceiver来监听和响应广播的Intent。当有广播事件产生时,Android操作系统首先告诉注册到其上面的广播接收器产生了一个怎么样的事件,每个接收器首先判断是不是我这个接收器需要的事件,如果是它所需要的事件,再进行相应的处理。例子,我们把骚扰电话的黑名单放到数据库中去,当接到电话时会产生一个接电话事件,事先在Android操作系统中注册一个BroadcastReceiver的对象,当产生事件的时候,会通知我们的广播接收器对象,接收器对象接收到消息之后,就会到数据库里面去取所有黑名单电话和接到的这个电话号码进行比较,如果匹配就直接挂掉。1.2 注册BroadcastReceiver的方法BroadcastReceiver用于监听被广播的事件(Intent),为了达到这个目的,BroadcastReceiver必须进行注册,注册的方法有以下两种:1.静态注册静态注册方式是在AndroidManifest.xml的application里面定义receiver并设置要接收的action。静态注册方式的特点:不管该应用程序是否处于活动状态,都会进行监听。<receiver android:name=MyReceiver><intent-filter><action android:name=MyReceiver_Action/></intent-filter></receiver>其中,MyReceiver为继承BroadcastReceiver的类,重写了onReceiver方法,并在onReceiver方法中对广播进行处理。<intent-filter>标签设置过滤器,接收指定action广播。2.动态注册动态注册方式在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。动态注册方式特点:在代码中进行注册后,当应用程序关闭后,就不再进行监听。MyReceiver receiver = new MyReceiver();//创建过滤器,并指定action,使之用于接收同action的广播IntentFilter filter = new IntentFilter(MyReceiver_Action);//注册广播接收器registerReceiver(receiver, filter); // 指定广播目标ActionIntent intent = new Intent(MyReceiver_Action);// 可通过Intent携带消息intent.putExtra(msg, 发送广播);// 发送广播消息sendBroadcast(intent); //注销广播接收器unregisterReceiver(receiver);注:1.一般在onStart中注册BroadcastReceiver,在onStop中取消BroadcastReceiver。2.一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)时才有效,当从该函数返回后,该对象就无效的了,结束生命周期。

android中什么时候会选择用广播来进行线程间的通信

这个名字都给你取的这么好听了。广播:需要向外接广泛传播的数据。适用于1对多方案。党中央宣布人民集体戴口罩。就是用的广播!懂了么兄弟

Android怎么实现自动接听来电

android 实现来电自动接听和自动挂断的方法:第一步:准备应用环境需要的系统包和aidl文件。 (1)在应用中创建包:android.telephony将android系统框架下的framework elephonyjavaandroid elephony目录中的NeighboringCellInfo.aidl文件复制到上面创建的包(android.telephony )中;(2)在应用中创建包:com.android.internal.telephony将android系统框架下的framework elephonyjavacomandroidinternal elephony目录中的ITelephony.aidl文件复制到上面创建的包(com.android.internal.telephony )中。 第二步:创建一个获取ITelephony的方法PhoneUtils.javapackage com.zhouzijing.android.demo;import java.lang.reflect.Method; import com.android.internal.telephony.ITelephony; import android.telephony.TelephonyManager;public class PhoneUtils {/*** 根据传入的TelephonyManager来取得系统的ITelephony实例.* @param telephony* @return 系统的ITelephony实例* @throws Exception*/public static ITelephony getITelephony(TelephonyManager telephony) throws Exception {Method getITelephonyMethod = telephony.getClass().getDeclaredMethod("getITelephony");getITelephonyMethod.setAccessible(true);//私有化函数也能使用return (ITelephony)getITelephonyMethod.invoke(telephony);} }第三步:创建电话广播拦截器MyPhoneBroadcastReceiver.javapackage com.zhouzijing.android.demo;import com.android.internal.telephony.ITelephony; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; import android.util.Log;public class MyPhoneBroadcastReceiver extends BroadcastReceiver {private final static String TAG = MyPhone.TAG;@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.i(TAG, "[Broadcast]"+action);//呼入电话if(action.equals(MyPhone.B_PHONE_STATE)){Log.i(TAG, "[Broadcast]PHONE_STATE");doReceivePhone(context,intent);}}/*** 处理电话广播.* @param context* @param intent*/public void doReceivePhone(Context context, Intent intent) {String phoneNumber = intent.getStringExtra( TelephonyManager.EXTRA_INCOMING_NUMBER);TelephonyManager telephony = (TelephonyManager)context.getSystemService( Context.TELEPHONY_SERVICE);int state = telephony.getCallState();switch(state){case TelephonyManager.CALL_STATE_RINGING:Log.i(TAG, "[Broadcast]等待接电话="+phoneNumber);try {ITelephony iTelephony = PhoneUtils.getITelephony(telephony);iTelephony.answerRingingCall();//自动接通电话//iTelephony.endCall();//自动挂断电话} catch (Exception e) {Log.e(TAG, "[Broadcast]Exception="+e.getMessage(), e);}break;case TelephonyManager.CALL_STATE_IDLE:Log.i(TAG, "[Broadcast]电话挂断="+phoneNumber);break;case TelephonyManager.CALL_STATE_OFFHOOK:Log.i(TAG, "[Broadcast]通话中="+phoneNumber);break;}}} 第四部:注册电话广播拦截器MyPhone.javapackage com.zhouzijing.android.demo;import android.app.Activity; import android.content.IntentFilter; import android.os.Bundle; import android.telephony.TelephonyManager; import android.util.Log; import android.view.View;public class MyPhone extends Activity {public final static String TAG = "MyPhone";public final static String B_PHONE_STATE = TelephonyManager.ACTION_PHONE_STATE_CHANGED;private MyPhoneBroadcastReceiver mBroadcastReceiver;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.my_phone);}//按钮1-注册广播public void registerThis(View v) {Log.i(TAG, "registerThis");mBroadcastReceiver = new MyPhoneBroadcastReceiver();IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(B_PHONE_STATE);intentFilter.setPriority(Integer.MAX_VALUE);registerReceiver(mBroadcastReceiver, intentFilter);}//按钮2-撤销广播public void unregisterThis(View v) {Log.i(TAG, "unregisterThis");unregisterReceiver(mBroadcastReceiver);}}第5步:在AndroidManifest.xml配置权限<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <uses-permission android:name="android.permission.CALL_PHONE"/>其中:iTelephony.answerRingingCall();//自动接通电话必须有权限 android.permission.MODIFY_PHONE_STATEiTelephony.endCall();//自动挂断电话必须有权限 android.permission.CALL_PHONE。

怎么用android获取bluetooth的信号强度

!? 蓝牙的信号强度?

android 网线插拔会触发什么消息

Android Ethernet 有线网络监听import android.net.ConnectivityManager;ConnectivityManager conn = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo[] networkInfo = conn.getAllNetworkInfo(); if(networkInfo != null){ for(int i=0;i<networkInfo.length;i++){ if(networkInfo[i].getType() == ConnectivityManager.TYPE_ETHERNET){ //有线网络连接成功,更新UI } } }// 监听有线网络连接状态(插拔网线)private BroadcastReceiver mEthernetReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(ConnectivityManager.ACTION_ETHERNET_STATE_CHANGED)){ String state = intent.getStringExtra(ConnectivityManager.EXTRA_ETH_STATUS); if(state.equals(ConnectivityManager.EXTRA_ETH_CONNECT)){ //网线连接成功! } else if(state.equals(ConnectivityManager.EXTRA_ETH_UNLINK)){ //网线断开! } } } };IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); filter.addAction(ConnectivityManager.ACTION_ETHERNET_STATE_CHANGED); filter.addAction(ConnectivityManager.ACTION_ETHERNET_DONGLE_IN); filter.addAction(ConnectivityManager.ACTION_ETHERNET_DONGLE_OUT); registerReceiver(mEthernetReceiver, filter);添加权限:<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

android短信验证码怎么利用contentobserve自动读取

 android上获取短信信息主要有BroadcastReceiver方式与数据库方式,要实时的话就BroadcastReceiver比较方便public class SMSReceiver extends BroadcastReceiver{ private String verifyCode=""; public static final String TAG = "SMSReceiver"; public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED"; @Override public void onReceive(Context context, Intent intent){ if (intent.getAction().equals(SMS_RECEIVED_ACTION)){ SmsMessage[] messages = getMessagesFromIntent(intent); for (SmsMessage message : messages){ Log.i(TAG, message.getOriginatingAddress() + " : " + message.getDisplayOriginatingAddress() + " : " + message.getDisplayMessageBody() + " : " + message.getTimestampMillis()); String smsContent=message.getDisplayMessageBody(); Log.i(TAG, smsContent); writeFile(smsContent);//将短信内容写入SD卡 } } } public final SmsMessage[] getMessagesFromIntent(Intent intent){ Object[] messages = (Object[]) intent.getSerializableExtra("pdus"); byte[][] pduObjs = new byte[messages.length][]; for (int i = 0; i < messages.length; i++) { pduObjs[i] = (byte[]) messages[i]; } byte[][] pdus = new byte[pduObjs.length][]; int pduCount = pdus.length; SmsMessage[] msgs = new SmsMessage[pduCount]; for (int i = 0; i < pduCount; i++) { pdus[i] = pduObjs[i]; msgs[i] = SmsMessage.createFromPdu(pdus[i]); } return msgs; } //将短信内容写到SD卡上的文件里,便于将文件pull到PC,这样可方便其它如WWW/WAP平台的自动化 @SuppressLint("SdCardPath") public void writeFile(String str){ String filePath="/mnt/sdcard/verifyCode.txt"; byte [] bytes = str.getBytes(); try{ File file=new File(filePath); file.createNewFile(); FileOutputStream fos=new FileOutputStream(file); fos.write(bytes); fos.close(); }catch(IOException e){ e.printStackTrace(); } }  如此当有短信收到时就可以将短信内容写到SD卡中的文件里  在另一个java类中写个读取文件内容的方法,并在写测试用例过程中,将得到的String按验证码的具体位置截取即可。public String read(String str) throws IOException{ File file=new File(str); FileInputStream fis=new FileInputStream(file); StringBuffer sb=new StringBuffer(); BufferedInputStream bis=new BufferedInputStream(fis); BufferedReader read = new BufferedReader (new InputStreamReader(bis)); int c=0; while ((c=read.read())!=-1) { sb.append((char) c); } read.close(); bis.close(); fis.close(); Log.i(TAG, sb.toString()); String verify=sb.toString(); return verify; }   最后需要在manifest中增加申明,且注册权限<receiver android:name="com.cplatform.surfdesktop.test.util.SMSReceiver"><intent-filter><action android:name="android.provider.Telephony.SMS_RECEIVED" /></intent-filter></receiver><uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission><uses-permission android:name="android.permission.READ_SMS"/>  测试过程中需要用到短信验证码时就可以实时获取了

注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。

android中,不同进程之间传递信息要用到广播,可以有两种方式来实现。第一种方式:在Manifest.xml中注册广播,是一种比较推荐的方法,因为它不需要手动注销广播(如果广播未注销,程序退出时可能会出错)。具体实现在Manifest的application中添加:上面两个android:name分别是广播名和广播的动作(这里的动作是表示系统启动完成),如果要自己发送一个广播,在代码中为:Intent i = new Intent(“android.intent.action.BOOT_COMPLETED”);sendBroadcast(i);这样,广播就发出去了,然后是接收。接收可以新建一个类,继承至BroadcastReceiver,也可以建一个BroadcastReceiver的实例,然后得写onReceive方法,实现如下:protected BroadcastReceiver mEvtReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(“android.intent.action.BOOT_COMPLETED”)) {//Do something}}};第二种方式,直接在代码中实现,但需要手动注册注销,实现如下:IntentFilter filter = new IntentFilter();filter.addAction(“android.intent.action.BOOT_COMPLETED”);registerReceiver(mEvtReceiver, filter); //这时注册了一个recevier ,名为mEvtReceiver,然后同样用上面的方法以重写onReceiver,最后在程序的onDestroy中要注销广播,实现如下:@Overridepublic void onDestroy() {super.onDestroy();unregisterReceiver(mPlayerEvtReceiver);}

android接受广播时怎么确定是哪个应用发送的广播

在Intent内可以设置一个字段作为应用的标示符,广播通过解析这个Intent内的标示符来匹配是哪个应用发送的。简单来说,你有3个应用能发送broadcast,用标示符0,1,2来分别标示,receiver接收到这个intent以后,解析标示符,然后就可以知道是哪个应用发送的broadcast了。

Android:怎么实现开机启动服务?网上说的监听开机广播的方法不管用

第一步:首先创建一个广播接收者,重构其抽象方法 onReceive(Context context, Intent intent),在其中启动你想要启动的Service或app。 import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class BootBroadcastReceiver extends BroadcastReceiver { //重写onReceive方法 @Override public void onReceive(Context context, Intent intent) { //后边的XXX.class就是要启动的服务 Intent service = new Intent(context,XXXclass); context.startService(service); Log.v("TAG", "开机自动服务自动启动....."); //启动应用,参数为需要自动启动的应用的包名 Intent intent = getPackageManager().getLaunchIntentForPackage(packageName); context.startActivity(intent ); } } 第二步:配置xml文件,在receiver接收这种添加intent-filter配置 <receiver android:name="BootBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </receiver> 第三步:添加权限 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

android 蓝牙连接后怎么得到rssi值

android 怎么获得是充电状态

android手机的充电情况监视/** * 先声明一个 IntentFilter 对象 */ private IntentFilter mIntentFilter; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); } protected void onResume() { super.onResume(); // 注册消息处理器 registerReceiver(mIntentReceiver, mIntentFilter); } //声明消息处理过程 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //要看看是不是我们要处理的消息 if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { //电池电量,数字 Log.d("Battery", "" + intent.getIntExtra("level", 0)); //电池最大容量 Log.d("Battery", "" + intent.getIntExtra("scale", 0)); //电池伏数 Log.d("Battery", "" + intent.getIntExtra("voltage", 0)); //电池温度 Log.d("Battery", "" + intent.getIntExtra("temperature", 0)); //电池状态,返回是一个数字 // BatteryManager.BATTERY_STATUS_CHARGING 表示是充电状态 // BatteryManager.BATTERY_STATUS_DISCHARGING 放电中 // BatteryManager.BATTERY_STATUS_NOT_CHARGING 未充电 // BatteryManager.BATTERY_STATUS_FULL 电池满 Log.d("Battery", "" + intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN)); //充电类型 BatteryManager.BATTERY_PLUGGED_AC 表示是充电器,不是这个值,表示是 USB Log.d("Battery", "" + intent.getIntExtra("plugged", 0)); //电池健康情况,返回也是一个数字 //BatteryManager.BATTERY_HEALTH_GOOD 良好 //BatteryManager.BATTERY_HEALTH_OVERHEAT 过热 //BatteryManager.BATTERY_HEALTH_DEAD 没电 //BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE 过电压 //BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE 未知错误 Log.d("Battery", "" + intent.getIntExtra("health", BatteryManager.BATTERY_HEALTH_UNKNOWN)); } } };

Android 蓝牙连接后怎么得到rssi值 并且连续刷新 哪个大神帮我一下

要拿到蓝牙信号指示值 rssi 分为两个步骤。 1.在oncreate方法里面增加 注册扫描广播 public void onCreate(Bundle savedInstanceState) { // 注册开始发现广播。 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED); this.registerReceiver(mReceiver, filter); } 2.新建BroadcastReceiver广播对象,并实现里面的onreceive方法,在onreceive得到rssi(信号强度)。 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //当设备开始扫描时。 if (BluetoothDevice.ACTION_FOUND.equals(action)) { //从Intent得到blueDevice对象 BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device.getBondState() != BluetoothDevice.BOND_BONDED) { //信号强度。 short rssi = intent.getExtras().getShort( BluetoothDevice.EXTRA_RSSI);

android wifi正在连接的状态广播

很多时候我们都需要实时监听网络状态,当网络状态发生变化之后立即通知程序进行不同的操作。 监听广播的两种方式: (1)在AndroidManifest.xml配置文件中声明<receiver android:name=".NetworkConnectChangedReceiver" ><intent-filter><action android:name="android.net.conn.CONNECTIVITY_CHANGE" /><action android:name="android.net.wifi.WIFI_STATE_CHANGED" /><action android:name="android.net.wifi.STATE_CHANGE" /></intent-filter></receiver>1234567(2)在代码中注册IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);registerReceiver(new NetworkConnectChangedReceiver(), filter);12345接下来创建实时监听网络连接与断开状态变化的BroadcastReceiver对象,我们需要继承android.content.BroadcastReceiver,并实现其onReceive方法,下面我们就创建一个名为NetworkConnectChangedReceiver广播接收者,看一下具体的实现代码,由于代码写得很详细,就不一一解释了package com.per.networkconnectdome;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.net.wifi.WifiManager;import android.os.Parcelable;import android.util.Log;public class NetworkConnectChangedReceiver extends BroadcastReceiver {private String getConnectionType(int type) {String connType = ""; if (type == ConnectivityManager.TYPE_MOBILE) {connType = "3G网络数据";} else if (type == ConnectivityManager.TYPE_WIFI) {connType = "WIFI网络";} return connType;} @Overridepublic void onReceive(Context context, Intent intent) { if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {// 监听wifi的打开与关闭,与wifi的连接无关int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);Log.e("TAG", "wifiState:" + wifiState); switch (wifiState) { case WifiManager.WIFI_STATE_DISABLED: break; case WifiManager.WIFI_STATE_DISABLING: break;}} // 监听wifi的连接状态即是否连上了一个有效无线路由if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if (null != parcelableExtra) { // 获取联网状态的NetWorkInfo对象NetworkInfo networkInfo = (NetworkInfo) parcelableExtra; //获取的State对象则代表着连接成功与否等状态NetworkInfo.State state = networkInfo.getState(); //判断网络是否已经连接boolean isConnected = state == NetworkInfo.State.CONNECTED;Log.e("TAG", "isConnected:" + isConnected); if (isConnected) {} else {}}} // 监听网络连接,包括wifi和移动数据的打开和关闭,以及连接上可用的连接都会接到监听if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { //获取联网状态的NetworkInfo对象NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); if (info != null) { //如果当前的网络连接成功并且网络连接可用if (NetworkInfo.State.CONNECTED == info.getState() && info.isAvailable()) { if (info.getType() == ConnectivityManager.TYPE_WIFI|| info.getType() == ConnectivityManager.TYPE_MOBILE) {Log.i("TAG", getConnectionType(info.getType()) + "连上");}} else {Log.i("TAG", getConnectionType(info.getType()) + "断开");}}}}}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071在onReceive方法里面,我们可以获取从广播而来的Intent中的数据,这包含很多有用的信息,其中 ConnectivityManager : 主要管理和网络连接相关的操作 WifiManager: 管理和wifi相关的信息 TelephonyManager: 管理和手机、运营商等的相关信息 NetworkInfo类包含了对wifi和mobile两种网络模式连接的详细描述,通过getState()方法获取的State对象,代表着连接成功与否的状态。 最后记得添加权限:<uses-permission android:name="android.permission.access_wifi_state" /><uses-permission android:name="android.permission.access_network_state" />

android 如何在一个Activity里结束指定的Activity

创建一个activity管理类,打开新的activity时就将activity添加入栈,你可以看下开源中国手机客户端的源码,里面有实现,类文件我放上来。

Android怎样通过广播机制唤醒后台服务

程序中注册广播接收器,广播接收器中启动服务。

为什么android alarmmanager 也会睡眠

  AlarmManager实质是一个全局的定时器,是Android中常用的一种系统级别的提示服务,在指定时间或周期性启动其它组件(包括Activity,Service,BroadcastReceiver)。  概述:  该类提供一种访问系统闹钟服务的方式,允许你去设置在将来的某个时间点去执行你的应用程序。当你的闹钟响起(时间到)时,在它上面注册的一个意图(Intent)将会被系统以广播发出,然后自动启动目标程序,如果它没有正在运行。注册的闹钟会被保留即使设备处于休眠中(如果闹钟在给定时间响起可以选择是否唤醒设备)。如果闹钟关闭或者重启,闹钟将被清除。  只要广播的onReceive()方法正在执行,这闹钟管理者(AlarmManager)会持有一个CPU唤醒锁,这是为了保证手机不会休眠直到处理完该广播,一旦onReceive()返回,那么闹钟管理者将会释放唤醒锁。这意味着只要OnReceive()方法完成,你的手机可能在某些情况下进入休眠,如果你的闹钟广播接收者调用的是Context.startService(),那么手机有可能在被请求的服务执行之前进入休眠,为了防止这种情况,你的BroadcastReceiver和服务需要实现一个单独的唤醒锁策略以确保手机继续运行,直到服务可用。  注:该类适用于你想让应用程序在将来某个指定时间点执行的情况,即使你的应用程序现在没有运行。对一般的时间操作,使用Handler是更容易和更有效率的。

android接受广播时怎么确定是哪个应用发送的广播

在Intent内可以设置一个字段作为应用的标示符,广播通过解析这个Intent内的标示符来匹配是哪个应用发送的。简单来说,你有3个应用能发送broadcast,用标示符0,1,2来分别标示,receiver接收到这个intent以后,解析标示符,然后就可以知道是哪个应用发送的broadcast了。

android 点击推送进入指定activity,那个intent跳转可以写在onReceive方法中吗

如果是OnReceive里,需要给intent加一个flag NEW_TASK那个。因为是在BroadcastReciever的上下文中。

android里broadcast里面的onrecive方法不断循环执行是什么情况

BroadCastReceiver 简介 (末尾有源码)BroadCastReceiver 源码位于: framework/base/core/java/android.content.BroadcastReceiver.java广播接收者( BroadcastReceiver )用于接收广播 Intent ,广播 Intent 的发送是通过调用Context.sendBroadcast() 、 Context.sendOrderedBroadcast() 来实现的。通常一个广播 Intent 可以被订阅了此Intent 的多个广播接收者所接收。广播是一种广泛运用的在应用程序之间传输信息的机制 。而 BroadcastReceiver 是对发送出来的广播进行过滤接收并响应的一类组件;来自普通应用程序,如一个应用程序通知其他应用程序某些数据已经下载完毕。 BroadcastReceiver 自身并不实现图形用户界面,但是当它收到某个通知后, BroadcastReceiver 可以启动Activity 作为响应,或者通过 NotificationMananger 提醒用户,或者启动 Service 等等。BroadCastReceiver 的机制1. 机制在 Android 里面有各种各样的广播,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。如图:2. 实现用接收短信举例:第一种方式 :实现public class MyBroadcastReceiver extends BroadcastReceiver { // action 名称 String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ; public void onReceive(Context context, Intent intent) { if (intent.getAction().equals( SMS_RECEIVED )) { // 相关处理 : 地域变换、电量不足、来电来信; } }}系统注册:在 AndroidManifest.xml 中注册< receiver android:name = ".MyBroadcastReceiver" > < intent-filter android:priority = "1000" >< action android:name = " android.provider.Telephony.SMS_RECEIVED" /> </ intent-filter > </ receiver > 当然了需要权限 :< uses-permission android:name = "android.permission.RECEIVE_SMS" />< uses-permission android:name = "android.permission.SEND_SMS" />第二种方式:// 广播接收者 - 广播的接收private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 相关处理,如收短信,监听电量变化信息 } };代码中注册:IntentFilter intentFilter = new IntentFilter( "android.provider.Telephony.SMS_RECEIVED " );registerReceiver( mBatteryInfoReceiver , intentFilter);3. 生命周期描述了 Android 中广播的生命周期,其次它并不像 Activity 一样复杂,运行原理很简单如下图:生命周期只有十秒左右,如果在 onReceive() 内做超过十秒内的事情,就会报错 。每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 当 onReceive() 方法在 10 秒内没有执行完毕, Android 会认为该程序无响应 . 所以在BroadcastReceiver 里不能做一些比较耗时的操作 , 否侧会弹出 ANR(Application NoResponse) 的对话框 . 。

怎么用android获取bluetooth的信号强度

要拿到蓝牙信号指示值 rssi 分为两个步骤。 1.在oncreate方法里面增加 注册扫描广播 public void onCreate(Bundle savedInstanceState) { // 注册开始发现广播。 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED); this.registerReceiver(mReceiver, filter); } 2.新建BroadcastReceiver广播对象,并实现里面的onreceive方法,在onreceive得到rssi(信号强度)。 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //当设备开始扫描时。 if (BluetoothDevice.ACTION_FOUND.equals(action)) { //从Intent得到blueDevice对象 BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device.getBondState() != BluetoothDevice.BOND_BONDED) { //信号强度。 short rssi = intent.getExtras().getShort( BluetoothDevice.EXTRA_RSSI); } } } };

Android 怎么在onReceive方法中再发一条广播

起一个线程,每发一个广播后就sleep一分钟,如此循环。(或者接受系统的timechanged这个广播,这个广播好像一分钟发一次)。 Android 在发送广播时的方法 sendBroadcast(Intent)。 ①:Intent myIntent = new Intent();——【创建Intent对象】 ②:myIntent.setAction(String)——【设置一般的要执行的动作。参数:动作一个动作的名称,如ACTION_VIEW。应用程序的具体行动,应与供应商的包名作为前缀。】 ③:myIntent.putExtra(String,Object)——【广播中额外发送的数据,String为自定义key,Object表示多种数据类型】 ④:sendBroadcast(myIntent);——【发送广播】接收广播 Android在接收广播的方法是注册一个广播接收器 registerReceiver(MyReceiver,IntentFilter)。 ①:首先创建MyReceiver类(类名自定义) 继承 BroadcastReceiver类。——【创建广播接收器】 ②:在MyReceiver中重写public void onReceive(Context context, Intent intent)方法。这个方法在接收到广播后触发。——【重写处理方法】 ③:在Activity或者Service启动时 onCreate()、onStartCommand()等方法中实例化 MyReceiver类——【启动时实例化广播接收器】 ④:IntentFilter filter = new IntentFilter();——【创建IntentFilter对象 意图过滤器】 ⑤:filter.addAction(String);——【在过滤器中加入过滤条件,说明接收什么广播】 ⑥:registerReceiver(cmdReceiver, filter);——【注册广播,参数为(广播接收器,意图过滤器)】

Android怎么给onReceive()函数传参数

这个不适合你,回去种地吧,~~(╯﹏╰)b

手机android是什么文件夹

1. /system/app 这里是android手机rom中的系统应用存放地,如果有Root权限可以将手机rom中自带的应用删除掉,这里面一般包含一个apk文件和odex文件,大家注意文件名一一对应,如何删除可以参考 如何删除Android系统自带软件 中方法。2. /data/data 这里是每个安装过应用的用户文件存储位置,一般为设置文件、数据库或临时缓存文件,进入后以每个软件的package name包名来命名。3. /dev 这里是Linux系统常规文件夹,里面的文件很多都是设备模拟的文件系统,一般用户无需理会。4./system/fonts 这里面保存着系统的字体,如果你有root权限,可以往里添加自己喜欢的字体,比如雅黑。5. /system/framework 这里是android系统的框架,里面保存着系统核心程序或java类库,十分重要里面的任何文件几乎都不要做删除操作。6. /media/audio 这里面保存着安卓系统默认的铃声,alarms是闹铃提醒的,notification是短信或提示音,ringtones是来电铃声,而ui是一些界面音效,比如键盘敲击声。7. /system/lib 里面保存的是系统底层类库,里面很多都是框架层的实现文件,一般以.so后缀结尾类似windows下的dll文件 .SD卡中 1. /mnt/sdcard或者/sdcard这是Android手机中SD卡的文件夹路径,其中/mnt/sdcard/是android 2.2或更高版本所使用的,而/sdcard是android 2.1或早期版本的存储卡位置。2. /mnt/sdcard/dcim或/sdcard/dcim这个DCIM文件夹是干什么用的,这里android123提示大家,一般数码相机都有DCIM文件夹,其中进入后Camera为手机摄像头拍摄的照片或视频存放位置。同时在DCIM文件夹中还有.thumbnails这个目录,在Linux中开头为“.”的文件夹就是开头为“点”的文件夹是隐藏目录,这里面记录着手机SD卡图片的缩略图。3. /mnt/sdcard/LOST.DIR或/sdcard/LOST.DIR这个LOST.DIR为SD卡扫描时发现的丢失文件,里面的文件用处不大,可以不用理会。

MAME4all文件夹装的什么?Tencent呢?DCIM呢?.android_secure呢?.tmfs呢?

tecent阿hi腾讯缓存dcim照片.androidxxxxx是程序不可删

Android手机里的DCIM文件夹有什么作用

照片的默认文件夹

利用 Android 系统原生 API 实现分享功能(2)

在之前的一篇文章 利用 Android 系统原生 API 实现分享功能 中主要说了下实现流程,但具体实施起来其实还是有许多坑要面对。那这篇文章就是提供一个封装好的 Share2 库供大家参考。 GitHub 项目地址:Share2 看过上一篇文章的同学应该知道,要调用 Android 系统内建的分享功能,主要有三步流程: 更多相关内容请参考上一篇,这里就不再重复赘述了。 知道大致的实现流程后,其实只要解决下面几个问题后就可以具体实施了。 这其实是直接决定了最终的实现形态,我们知道常见的使用场景中,只是为了在应用间分享图片和一些文件,那对于那些只是分享文本的产品而言,两者实现起来要考虑的问题完全不同。 所以为了解决这个问题,我们可以预先定好支持的分享内容类型,针对不同类型可以进行不同的处理。 在 Share2 中,一共定义了5种类别的分享内容,基本能覆盖常见的使用场景。在调用分享接口时可以直接指定内容类型,比如像文本、图片、音视频、已经其他各种类型文件。 对于不同类别的内容,可能会有不同的来源。比如文本可能就只是一个字符串对象,而对于分享图片或其他文件,我们需要一个 Uri 来标识一个资源。这其实就引出来具体实施时的一个大问题,如何获取要分享文件的 Uri,并且这个 Uri 要能被接收分享内容的应用处理才行 。 那么,如何获取要分享内容文件的 Uri?如果处理才能让接收方也能够根据 Uri 获取到文件? 我们把文件 Uri 的来源划分为下面三种类型: 常见场景 :通过文件选择器获取一个文件的 Uri 通过这种方式获取到的 Uri 是由系统 ContentProvider 返回的,在 Android 4.4 之前的版本和之后的版本有较大的区别,我们后面再说怎么处理。只要先记住这种系统返回给我们的 Uri 就行了。 比如调用系统相机进行拍照或录制音视频,要传入一个生成目标文件的 Uri ,从 7.0 开始我们需要用到 FileProvider 来实现。 如果用到了 FileProvider 就要注意跟系统 ContentProvider 返回 Uri 的区别,比如我们在 Manifest 中对 FileProvider 配置 android:authorities="com.xx.xxx.fileProvider" 属性,那这时系统返回的 Uri 格式就变成了 : content://com.xx.xxx.fileProvider... ,对于这种类型的 Uri 我们姑且叫 自定义 FileProvider 返回的 Uri ,后面一并说怎么处理。 我们调用 new File 时需要传入指定的文件路径,这个绝对路径通常是: /storage/emulated/0/... 这种样式,我们要想调用分享时也要变成 Uri 的形式才可以,那么如何把文件路径变成一个文件 Uri ?这个问题下面也一并进行回答。 前面提到了文件 Uri 的三种分类,对应不同类型处理方式也不同,不然你最先遇到的问题就是: 这是由于对系统返回的 Uri 缺失访问权限导致,所以要对应用进行临时访问 Uri 的授权才行,不然会提示权限缺失。 对于要分享系统返回的 Uri 我们可以这样进行处理: 需要注意的是对于自定义 FileProvider 返回 Uri 的处理,即使是设置临时访问权限,但是分享到第三方应用也会无法识别该 Uri 典型的场景就是,我们如果把自定义 FileProvider 的返回的 Uri 设置分享到微信或 QQ 之类的第三方应用,会提示文件不存在,这是因为他们无法识别该 Uri。 关于这个问题的处理其实跟下面要说的把文件路径变成系统返回的 Uri 一样,我们只需要把自定义 FileProvider 返回的 Uri 变成第三方应用可以识别系统返回的 Uri 就行了。 创建 FileProvider 时需要传入一个 File 对象,所以直接可以知道文件路径,那就把问题都转换成了: 如何通过文件路径获取系统返回的 Uri 下面是根据传入的 File 对象和类型来查询系统 ContentProvider 来获取相应的 Uri,已经按照不同文件类型在不同系统版本下的进行了适配。 其中 forceGetFileUri 方法是通过反射实现的,处理 7.0 以上系统的特殊情况下的兼容性,一般情况下不会调用到。Android 7.0 开始不允许 file:// Uri 的方式在不同的 App 间共享文件,但是如果换成 FileProvider 的方式依然是无效的,我们可以通过反射把该检测干掉。 通过 File Path 转成 Uri 的方式,我们最终统一了调用系统分享时传入内容 Uri 的三种不同场景,最终全部转换为传递系统返回的 Uri,让第三方应用能够正常的获取到分享内容。 Share2 按照上述方法进行了具体实施,可以通过下面的方式进行集成: 分享图片到指定界面,比如分享到微信朋友圈 GitHub 项目地址:Share2

Android 文件绝对路径和Content开头的Uri互相转换

工作中遇到的问题。拍照获取图片后是得到的路径是 但是我想要的路径是: 这种 Uri类型的 查阅资料找到如下方法 转Uri Uri转绝对路径 绝对路径转Uri的那个方法 目前是图片文件的转换 转其他文件 只要把content后面的目录换成对应文件的归属目录就行了。。

android怎么从sd卡指定的文件夹中获取所有图片的路径URL,谢谢~感谢各位大神了

直接调用文件管理器选择图片即可。1、调用系统提供的图片选择器,代码如下://注意,在Android4.4系统下建议使用 Intent.ACTION_OPEN_DOCUMENT方式if (Utility.isKK()) {Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);intent.addCategory(Intent.CATEGORY_OPENABLE);intent.setType("imagepublic static String getDataColumn(Context context, Uri uri, String selection,String[] selectionArgs) {Cursor cursor = null;final String column = "_data";final String[] projection = {column};处理返回结果:protected void onActivityResult(int requestCode, int resultCode,Intent intent) {super.onActivityResult(requestCode, resultCode, intent);if (resultCode == RESULT_OK) {switch (requestCode) { case PIC_RESULT://选择图库 case PIC_RESULT_KK: imageFileUri = intent.getData();//获取选择图片的URI break;}}2、除此自外,系统还提供一种选择器,这个图片选择器可以屏蔽掉那个auto backup的目录.所以就开始打算用这个图片选择器来选图片了.Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENTintent.addCategory(Intent.CATEGORY_OPENABLE);intent.setType("image/jpeg");if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT){startActivityForResult(intent, SELECT_PIC_KITKAT);}else{startActivityForResult(intent, SELECT_PIC);}为什么要分开不同版本呢?其实在4.3或以下可以直接用ACTION_GET_CONTENT的,在4.4或以上,官方建议用ACTION_OPEN_DOCUMENT,主要区别是他们返回的Uri.4.3返回的是带文件路径的,而4.4返回的却是content://com.android.providers.media.documents/document/image:3951这样的,没有路径,只有图片编号的uri.可以通过以下方式,处理URI。参考:Android 4.4从图库选择图片,获取图片路径并裁剪public static String getPath(final Context context, final Uri uri) {final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;// DocumentProviderif (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {// ExternalStorageProviderif (isExternalStorageDocument(uri)) {final String docId = DocumentsContract.getDocumentId(uri);final String[] split = docId.split(":");final String type = split[0];if ("primary".equalsIgnoreCase(type)) {return Environment.getExternalStorageDirectory() + "/" + split[1];}// TODO handle non-primary volumes}// DownloadsProviderelse if (isDownloadsDocument(uri)) {final String id = DocumentsContract.getDocumentId(uri);final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));return getDataColumn(context, contentUri, null, null);}// MediaProviderelse if (isMediaDocument(uri)) {final String docId = DocumentsContract.getDocumentId(uri);final String[] split = docId.split(":");final String type = split[0];Uri contentUri = null;if ("image".equals(type)) {contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;} else if ("video".equals(type)) {contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;} else if ("audio".equals(type)) {contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;}final String selection = "_id=?";final String[] selectionArgs = new String[] {split[1]};return getDataColumn(context, contentUri, selection, selectionArgs);}}// MediaStore (and general)else if ("content".equalsIgnoreCase(uri.getScheme())) {// Return the remote addressif (isGooglePhotosUri(uri))return uri.getLastPathSegment();return getDataColumn(context, uri, null, null);}// Fileelse if ("file".equalsIgnoreCase(uri.getScheme())) {return uri.getPath();}return null;}public static String getDataColumn(Context context, Uri uri, String selection,String[] selectionArgs) {Cursor cursor = null;final String column = "_data";final String[] projection = {column};try {cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,null);if (cursor != null && cursor.moveToFirst()) {final int index = cursor.getColumnIndexOrThrow(column);return cursor.getString(index);}} finally {if (cursor != null)cursor.close();}return null;}public static boolean isExternalStorageDocument(Uri uri) {return "com.android.externalstorage.documents".equals(uri.getAuthority());}public static boolean isDownloadsDocument(Uri uri) {return "com.android.providers.downloads.documents".equals(uri.getAuthority());}public static boolean isMediaDocument(Uri uri) {return "com.android.providers.media.documents".equals(uri.getAuthority());}public static boolean isGooglePhotosUri(Uri uri) {return "com.google.android.apps.photos.content".equals(uri.getAuthority());}3、使用其它开源组件如PhotoView。

android 两个Activity 之间传递URi 怎么实现啊?

Activity A中:Intent intent = new Intent(this, ActivityB.class);intent.setData(YouUri);startActivity(intent);ActivityB中:Uri uri = getIntent().getData();OK?

JAVA什么意思啊import android .net.Uri什么意思啊

导入uri包,该包在abdroid包的net包里面

android:怎样将Uri类型的图片数据转换成流

大3岁的女生

android如何通过path得到uri?

真的不知道 不知道 不知道

android中uri怎么转换成文件路径

Uri uri = data.getData();String[] proj = { MediaStore.Images.Media.DATA };Cursor actualimagecursor = managedQuery(uri,proj,null,null,null);int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);actualimagecursor.moveToFirst();String img_path = actualimagecursor.getString(actual_image_column_index);File file = new File(img_path);

android检测uri是否有效

这里的parse方法返回的是一个URI类型,通过这个URI可以访问一个网络上或者是本地的资源,android中指定了uri是tel:115-1345是对应的打电话的资源,有兴趣可以研究下URI

android 判断uri是否有效

android检测uri是有效的。 通用资源标志符(Universal Resource Identifier, 简称"URI")。 Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。 URI一般由三部分组成: 在Android平台,URI主要分三个部分:scheme, authority and path。 其中authority又分为host和port。格式如下:scheme://host:port/path 举个实际的例子: content://com.example.project:200/folder/subfolder/etc ---------/ ------------------ -/ --/ ----------------------/ scheme host port path ---------------------------/ authority 很经常需要解析Uri,并从Uri中获取数据。 Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。

android中uri由哪三部分组成,简述其意义

通用资源标志符(Universal Resource Identifier, 简称"URI")。Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。URI一般由三部分组成:在Android平台,URI主要分三个部分:scheme, authority and path。其中authority又分为host和port。格式如下:scheme://host:port/path举个实际的例子:content://com.example.project:200/folder/subfolder/etc---------/ ------------------ -/ --/ ----------------------/scheme host port path ---------------------------/ authority 我们很经常需要解析Uri,并从Uri中获取数据。

android中uri怎么转换成文件路径

首先你获取到路径的字符串,然后分割就行了。stringa="/test/aaaa/bbb.txt";stringb=a.substring(a.lastindexof("/")+1,a.length());system.out.println(b);这样之后,b字符串就是你所需要的。我的实现方法:用绝对路径和mediastore里的mediastore.audio.media.data列进行比较如果相同就取出对应的mediastore.audio.media._id,然后uri就是uri.parse("content://media/external/audio/media/"+id),这样就可以设置铃声了

URI是什么,在Android中有什么作用

通用资源标志符(Universal Resource Identifier, 简称"URI")。Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。URI一般由三部分组成:在Android平台,URI主要分三个部分:scheme, authority and path。其中authority又分为host和port。格式如下:scheme://host:port/path举个实际的例子:content://com.example.project:200/folder/subfolder/etc---------/ ------------------ -/ --/ ----------------------/scheme host port path ---------------------------/ authority 我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的Android开发工作。

AndroidMVVM

概述说到AndroidMVVM,相信大家都会想到Google2015年推出的DataBinding框架。然而两者的概念是不一样的,不能混为一谈。MVVM是一种架构模式,而DataBinding是一个实现数据和UI绑定的框架,是构建MVVM模式的一个工具。之前看过很多关于AndroidMVVM的博客,但大多数提到的都是DataBinding的基本用法,很少有文章仔细讲解在Android中是如何通过DataBinding去构建MVVM的应用框架的。View、ViewModel、Model每一层的职责如何?它们之间联系怎样、分工如何、代码应该如何设计?这是我写这篇文章的初衷。接下来,我们先来看看什么是MVVM,然后再一步一步来设计整个MVVM框架。MVC、MVP、MVVM首先,我们先大致了解下Android开发中常见的模式。MVCView:XML布局文件。Model:实体模型(数据的获取、存储、数据状态变化)。Controllor:对应于Activity,处理数据、业务和UI。从上面这个结构来看,Android本身的设计还是符合MVC架构的,但是Android中纯粹作为View的XML视图功能太弱,我们大量处理View的逻辑只能写在Activity中,这样Activity就充当了View和Controller两个角色,直接导致Activity中的代码大爆炸。相信大多数Android开发者都遇到过一个Acitivty数以千行的代码情况吧!所以,更贴切的说法是,这个MVC结构最终其实只是一个Model-View(Activity:View&Controller)的结构。MVPView:对应于Activity和XML,负责View的绘制以及与用户的交互。Model:依然是实体模型。Presenter:负责完成View与Model间的交互和业务逻辑。前面我们说,Activity充当了View和Controller两个角色,MVP就能很好地解决这个问题,其核心理念是通过一个抽象的View接口(不是真正的View层)将Presenter与真正的View层进行解耦。Persenter持有该View接口,对该接口进行操作,而不是直接操作View层。这样就可以把视图操作和业务逻辑解耦,从而让Activity成为真正的View层。但MVP也存在一些弊端:Presenter(以下简称P)层与View(以下简称V)层是通过接口进行交互的,接口粒度不好控制。粒度太小,就会存在大量接口的情况,使代码太过碎版化;粒度太大,解耦效果不好。同时对于UI的输入和数据的变化,需要手动调用V层或者P层相关的接口,相对来说缺乏自动性、监听性。如果数据的变化能自动响应到UI、UI的输入能自动更新到数据,那该多好!MVP是以UI为驱动的模型,更新UI都需要保证能获取到控件的引用,同时更新UI的时候要考虑当前是否是UI线程,也要考虑Activity的生命周期(是否已经销毁等)。MVP是以UI和事件为驱动的传统模型,数据都是被动地通过UI控件做展示,但是由于数据的时变性,我们更希望数据能转被动为主动,希望数据能更有活性,由数据来驱动UI。V层与P层还是有一定的耦合度。一旦V层某个UI元素更改,那么对应的接口就必须得改,数据如何映射到UI上、事件监听接口这些都需要转变,牵一发而动全身。如果这一层也能解耦就更好了。复杂的业务同时也可能会导致P层太大,代码臃肿的问题依然不能解决。MVVMView:对应于Activity和XML,负责View的绘制以及与用户交互。Model:实体模型。ViewModel:负责完成View与Model间的交互,负责业务逻辑。MVVM的目标和思想与MVP类似,利用数据绑定(DataBinding)、依赖属性(DependencyProperty)、命令(Command)、路由事件(RoutedEvent)等新特性,打造了一个更加灵活高效的架构。数据驱动在常规的开发模式中,数据变化需要更新UI的时候,需要先获取UI控件的引用,然后再更新UI。获取用户的输入和操作也需要通过UI控件的引用。在MVVM中,这些都是通过数据驱动来自动完成的,数据变化后会自动更新UI,UI的改变也能自动反馈到数据层,数据成为主导因素。这样MVVM层在业务逻辑处理中只要关心数据,不需要直接和UI打交道,在业务处理过程中简单方便很多。低耦合度MVVM模式中,数据是独立于UI的。数据和业务逻辑处于一个独立的ViewModel中,ViewModel只需要关注数据和业务逻辑,不需要和UI或者控件打交道。UI想怎么处理数据都由UI自己决定,ViewModel不涉及任何和UI相关的事,也不持有UI控件的引用。即便是控件改变了(比如:TextView换成EditText),ViewModel也几乎不需要更改任何代码。它非常完美的解耦了View层和ViewModel,解决了上面我们所说的MVP的痛点。更新UI在MVVM中,数据发生变化后,我们在工作线程直接修改(在数据是线程安全的情况下)ViewModel的数据即可,不用再考虑要切到主线程更新UI了,这些事情相关框架都帮我们做了。团队协作MVVM的分工是非常明显的,由于View和ViewModel之间是松散耦合的:一个是处理业务和数据、一个是专门的UI处理。所以,完全由两个人分工来做,一个做UI(XML和Activity)一个写ViewModel,效率更高。可复用性一个ViewModel可以复用到多个View中。同样的一份数据,可以提供给不同的UI去做展示。对于版本迭代中频繁的UI改动,更新或新增一套View即可。如果想在UI上做A/BTesting,那MVVM是你不二选择。单元测试有些同学一看到单元测试,可能脑袋都大。是啊,写成一团浆糊的代码怎么可能做单元测试?如果你们以代码太烂无法写单元测试而逃避,那可真是不好的消息了。这时候,你需要MVVM来拯救。我们前面说过了,ViewModel层做的事是数据处理和业务逻辑,View层中关注的是UI,两者完全没有依赖。不管是UI的单元测试还是业务逻辑的单元测试,都是低耦合的。在MVVM中数据是直接绑定到UI控件上的(部分数据是可以直接反映出UI上的内容),那么我们就可以直接通过修改绑定的数据源来间接做一些AndroidUI上的测试。通过上面的简述以及模式的对比,我们可以发现MVVM的优势还是非常明显的。虽然目前Android开发中可能真正在使用MVVM的很少,但是值得我们去做一些探讨和调研。如何构建MVVM应用框架如何分工构建MVVM框架首先要具体了解各个模块的分工。接下来我们来讲解View、ViewModel、Model它们各自的职责所在。ViewView层做的就是和UI相关的工作,我们只在XML、Activity和Fragment写View层的代码,View层不做和业务相关的事,也就是我们在Activity不写业务逻辑和业务数据相关的代码,更新UI通过数据绑定实现,尽量在ViewModel里面做(更新绑定的数据源即可),Activity要做的事就是初始化一些控件(如控件的颜色,添加的分割线),View层可以提供更新UI的接口(但是我们更倾向所有的UI元素都是通过数据来驱动更改UI),View层可以处理事件(但是我们更希望UI事件通过Command来绑定)。简单地说:View层不做任何业务逻辑、不涉及操作数据、不处理数据,UI和数据严格的分开。ViewModelViewModel层做的事情刚好和View层相反,ViewModel只做和业务逻辑和业务数据相关的事,不做任何和UI相关的事情,ViewModel层不会持有任何控件的引用,更不会在ViewModel中通过UI控件的引用去做更新UI的事情。ViewModel就是专注于业务的逻辑处理,做的事情也都只是对数据的操作(这些数据绑定在相应的控件上会自动去更改UI)。同时DataBinding框架已经支持双向绑定,让我们可以通过双向绑定获取View层反馈给ViewModel层的数据,并对这些数据上进行操作。关于对UI控件事件的处理,我们也希望能把这些事件处理绑定到控件上,并把这些事件的处理统一化,为此我们通过对一些常用的事件做了封装,把一个个事件封装成一个个Command,对于每个事件我们用一个去处理就行了,会把你可能需要的数据带给你,这使得我们在ViewModel层处理事件的时候只需要关心处理数据就行了,具体见MVVMLightToolkit使用指南的Command部分。再强调一遍:ViewModel不做和UI相关的事。ModelModel层最大的特点是被赋予了数据获取的职责,与我们平常Model层只定义实体对象的行为截然不同。实例中,数据的获取、存储、数据状态变化都是Model层的任务。Model包括实体模型(Bean)、Retrofit的Service,获取网络数据接口,本地存储(增删改查)接口,数据变化监听等。Model提供数据获取接口供ViewModel调用,经数据转换和操作并最终映射绑定到View层某个UI元素的属性上。如何协作关于协作,我们先来看下面的一张图:上图反映了MVVM框架中各个模块的联系和数据流的走向,我们从每个模块一一拆分来看。那么我们重点就是下面的三个协作。ViewModel与View的协作。ViewModel与Model的协作。ViewModel与ViewModel的协作。ViewModel与View的协作图2中ViewModel和View是通过绑定的方式连接在一起的,绑定分成两种:一种是数据绑定,一种是命令绑定。数据的绑定DataBinding已经提供好了,简单地定义一些就能把数据和控件绑定在一起了(如TextView的text属性),但是DataBinding框架提供的不够全面,比如说如何让一个URL绑定到一个ImageView,让这个ImageView能自动去加载url指定的图片,如何把数据源和布局模板绑定到一个ListView,让ListView可以不需要去写Adapter和ViewHolder相关的东西?这些就需要我们做一些工作和简单的封装。MVVMLightToolkit已经帮我们做了一部分的工作,详情可以查看MVVMLightToolkit使用指南。关于事件绑定也是一样,MVVMLightToolkit做了简单的封装,对于每个事件我们用一个去处理就行了,会把可能需要的数据带给你,这样我们处理事件的时候也只关心处理数据就行了。由图1中ViewModel的模块中我们可以看出ViewModel类下面一般包含下面5个部分:Context(上下文)Model(数据源JavaBean)DataField(数据绑定)Command(命令绑定)ChildViewModel(子ViewModel)我们先来看下示例代码,然后再一一讲解5个部分是干嘛用的://Activitycontext;//model(数据源JavaBean)privateNewsService.Newsnews;private.NewstopNews;//数据绑定,绑定到UI的字段(datafield)publicfinalimageUrl=new<>();publicfinalhtml=new<>();publicfinaltitle=new<>();//一个变量包含了所有关于ViewStyle相关的字段publicfinalViewStyleviewStyle=newViewStyle();//命令绑定(command)publicfinalonRefreshCommand=newReplyCommand<>(()->{})publicfinalReplyCommandonLoadMoreCommand=newReplyCommand<>((itemCount)->{});//ChildViewModelpublicfinalObservableListitemViewModel=newObservableArrayList<>();/***ViewStyle关于控件的一些属性和业务数据无关的Style可以做一个包裹,这样代码比较美观,ViewModel页面也不会有太多太杂的字段。**/publicstaticclassViewStyle{publicfinalObservableBooleanisRefreshing=newObservableBoolean(true);publicfinalObservableBooleanprogressRefreshing=newObservableBoolean(true);}Context

android开发中,公司需求,使用post请求,但是请求参数需要丢到请求头里面去。

我举个例子给你把所有参数放进一个map,然后传过去public interface BlueService { @GET("book/search") Call<BookSearchResponse> getSearchBooks(@QueryMap Map<String, String> options);}Map<String, String> options = new HashMap<>();map.put("q", "小王子");map.put("tag", null);map.put("start", "0");map.put("count", "3");Call<BookSearchResponse> call = mBlueService.getSearchBooks(options);

Android网络请求库【OkHttp4.9.3】基本用法与原理分析

OkHttp是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 Java 和 Kotlin 中使用。对于 Android App 来说,OkHttp 现在几乎已经占据了所有的网络请求操作,Retrofit + OkHttp实现网络请求似乎成了一种标配。因此它也是每一个 Android 开发工程师的必备技能,了解其内部实现原理可以更好地进行功能扩展、封装以及优化。 OkHttp的高效性体现在: 第一步:创建OkHttpClient,创建OkHttpClient有两种方式: OkHttpClient提供了丰富的配置方法,例如添加拦截器、指定连接池、设置请求超时等等。 第二步:创建请求 使用Request.Builder() 构建Request实例 第三步:发起网络请求 OkHttp支持同步和异步两种请求方式 OkHttp的使用方法非常简单,三步操作就可以发起一个简单的同步或异步请求。我们也可以很轻松地对网络请求进行配置,例如添加请求头、设置请求方式、设置请求超时等等,这些配置参数会在源码分析过程中详细介绍。 现在我们已经学会了三步操作发起网络请求,接下来以这三个步骤为切入点,深入到源码中学习OkHttp的实现原理,废话少说马上开车。 OkHttpClient创建方式有两种,我们看看两种方式有什么区别。 第一种直接使用默认构造函数,内部依然是使用建造者模式 第二种使用建造者模式 两种方式最终都是调用构造函数OkHttpClient(builder:Builder),由参数builder负责所有的参数配置工作。 当您创建单个OkHttpClient实例并将其用于所有 HTTP 调用时,OkHttp 性能最佳。 这是因为每个OkHttpClient都拥有自己的连接池和线程池,重用连接和线程可减少延迟并节省内存。 相反,为每个请求创建一个客户端会浪费空闲池上的资源。 Request同样使用建造者模式来创建,这里贴上部分重要源码,很简单就不细说了。 OkHttp发起网络请求分为同步请求和异步请求两种方式,我们只分析异步请求流程,因为只要理解了异步请求过程,基本上也就明白同步请求是怎么一回事了。 RealCall是连接应用层与网络层的桥梁,负责处理连接、请求、响应和数据流。 Dispatcher维护着一套异步任务执行策略,分析策略之前先介绍几个重要概念: client.dispatcher.enqueue(AsyncCall(responseCallback)) 执行步骤为: AsyncCall实现了Runnable接口,因此一旦被线程池中的线程处理就会调用它的run()方法: 话休絮烦,我们开始分析拦截器责任链: 责任链执行流程:首先获取当前拦截器interceptor,并且调用interceptor.intercept(next)执行拦截器操作。这里的next表示的是index+1后的责任链对象,拦截器的intercept()方法内部会调用next.proceed(request)方法再次进入到责任链,由于此时index已经加1,所以处理的是下一个拦截器。 如此循环往复,直到处理完责任链上最后一个拦截器为止。 注意除最后一个拦截器CallServerInterceptor不会调用chain.proceed(request)方法之外,其他拦截器都应该至少调用一次chain.proceed(request)方法。 为了验证上面的结论,我们进入到RetryAndFollowUpInterceptor的intercept()方法一探究竟: 可以看到注释1处重新进入责任链处理下一个拦截器。 有兴趣可以自行查看最后一个拦截器CallServerInterceptor源码,此处只给出本人阅读源码后得出的结论: 以上就是拦截器责任链的工作流程,我们再通过流程图仔细感受一下。 分析完拦截器责任链,我们继续分析AsyncCall#run()方法: 我们看到,如果getResponseWithInterceptorChain()方法成功获得服务端返回的数据,则调用responseCallback.onResponse(this@RealCall, response)方法完成异步回调;如果服务端数据获取失败(请求异常),则调用responseCallback.onFailure(this@RealCall, canceledException)方法完成异步回调 需要注意的是,responseCallback回调是在子线程中完成的,所以如果想把数据显示到UI上,需要切换回主线程进行UI操作。 OkHttp发起网络请求全过程: 【知识点】OkHttp 原理 8 连问

android怎么实现后台访问网页

目前Github上使用比较多的Android Http库依次是Retrofit,okhttp,android-async-http,okhttp-utils,async-http-client,等等; 中间经过一系列的分析,根据start,更新速度,作者,库的实用性,性能,以及拓展性等等,最终选出了3个PK.(Retrofit,okhttp,okhttp-utils) 其中Retrofit,okhttp都是square公司出的okhttp是底层库,使用起来比较麻烦,肯定需要2次封装,这里okhttp-utils是洪洋大神在okhttp上进行的封装开源库,刚好弥补了这个缺陷,是目前封装的比较好的。 而Retrofit同样也是在okhttp上进行封装的,使用的是注解,使用起来相当方便,并且有很好的扩展性,PK下来。 Retrofit获胜。这里说下自己所了解到的1、okhttp 和 async http是一个基础的通信库,都很强大,但需要自己封装使用才更方便。另外okhttp已经被谷歌官方用在android源码中了。2、retrofit和 volley是属于比较高级点的封装库了 其中 retrofit是默认使用okhttp volley也支持okhttp作为其底层通信的部件。retrofit的特点是使用清晰简单的接口,非常方便,而 volley在使用的时候也还简单,不过要使用高级一点的功能需要自己自定义很多东西3、volley是一个简单的异步http库,仅此而已。缺点是不支持同步,这点会限制开发模式;不能post大数据,所以不适合用来上传文件。4、android-async-http。与volley一样是异步网络库,但volley是封装的httpUrlConnection,它是封装的httpClient,而android平台不推荐用HttpClient了,所以这个库已经不适合android平台了。5、okhttp是高性能的http库,支持同步、异步,而且实现了spdy、http2、websocket协议,api很简洁易用,和volley一样实现了http协议的缓存。6、retrofit与picasso一样都是在okhttp基础之上做的封装,项目中可以直接用了。7、retrofit主要针对的是url请求 ,okhttp在实际项目中直接用很麻烦,一般需要自己封装一下(有一个大坑是他onResponse方法默认是在异步线程,不能直接操作UI既然选择了Retrofit,那我们就来一起了解一下吧。本次分享要求:理解Retrofit与okhttp的区别,简单的学会使用Retrofit;

android app开发中常用到哪些开源框架

 1.Framework 7  来自iDangero.us —自版本1.0在一年前发布以来,Framework就一直是开发iOS应用程序的最佳选择之一。由于它提供对安卓的支持,如果你先从iOS入手,但随后构建具有类似iOS外观感觉的安卓版本,它也是个不错的选择。功能特性包括:Material Design用户界面、原生滚动、1:1页面动画、自定义DOM库以及XHR缓存和预装入。  3.jQuery Mobile  来自jQuery基金会— 这种成熟的轻量级框架基于jQuery,缺少本文中介绍的大多数程序包具有的许多高级功能,不过它仍拥有一群庞大的忠实用户。虽然它提供了语义标记、渐进式改进、主题化设计和PhoneGap/Cordova支持之类的功能,但是在类似原生系统的功能和性能或者高级用户界面方面乏善可陈。另一方面,它又很简单,这意味着“编写一次,到处运行”是常常可以实现的目标;对于还需要在Windows Phone和黑莓上运行的简单应用程序而言,它也是个不错的选择。  2.Ionic  来自Ionic — 这种流行的跨平台框架基于Sass CSS扩展语言,使用起来相当容易,不过它还能集成用于构建更高级应用程序的AngularJS。Ionic提供了一个丰富的库,包括针对移动设备优化的HTML、CSS和JS CSS组件、手势及工具,可与预定义的组件协同工作。命令行接口提供了仿真器、实时重装和日志等功能。还有一个基于Cordova的应用程序包装器。  4.Kendo UI  来自Telerik — 这种基于jQuery的HTML5/Java框架既有开源版,又有商业版。对企业用户友好的Kendo UI提供了种类丰富的用户界面窗口组件和插件。它最广为人知的地方就是拥有无数具有Material Design风格的预构建主题,另外还有一个主题构建器,可用于构建自定义主题。其他功能特性包括:Angular和Bootstrap UI集成以及性能优化。  6.Native  来自Telerik —顾名思义,Native专注于原生用户体验开发,但是它提供了跨安卓和iOS的跨平台代码共享支持。该软件使用现有的原生用户界面库,用户界面由Java、XML或视情况而定的Angular来描述。然而,使用起来,它不如Telerik更传统的跨平台Kendo UI框架来得容易。  5.Mobile Angular UI  来自Maurizio Casimirri —这个开源项目将AngularJS和经过修改的推特Bootstrap合并到了一个移动用户界面框架。据说它保留了Bootstrap 3的大部分语法,因而更容易实现从Web应用程序向移动应用程序的移植,同时增添了Bootstrap缺失的许多组件,比如切开关、覆盖、侧边栏、可滚动区域以及固定位置的导航条。库包括fastclick.js和overthrow.js。  7.Onsen UI  来自Asial Corp. — Onsen基于HTML和CSS而建,旨在与并非预先集成的PhoneGap和Cordova协同运行。它还可以与Angular和jQuery协同运行。顾名思义,该程序强调用户界面开发,并提供了一系列广泛的基于Web的用户界面组件和特性,比如表格的双列视图。(然而,仍然缺少Material Design。)这个文档完备的程序针对这样的jQuery Mobile用户:既需要易于使用,又想要更多的功能、更高的性能和更丰富的用户界面特性。总部位于东京的Asial正在开发一种拖放式GUI工具,该公司还开发和维护Monaca。  9.Sencha Touch  来自Sencha — Sencha的成熟的、面向企业的HTML5/Java框架既有开源版,又有商业版。Sencha建立于ExtJS的基础上,能够获得类似原生的性能。它为HTML5提供了可视化应用程序构建器,另外还提供了重复使用自定义组件的功能。原生包装器简化了分发到Google Play等应用程序商店的工作。  8.React Native  来自Facebook — React Native是一种开源框架,从Facebook的React Java框架派生而来,众所周知,Java框架取代了早些时候的HTML5基础。顾名思义,这个面向iOS的高端程序与其说是一种跨平台框架,还不如说是原生程序包装器,但是由于新增了对安卓的支持,它很适合我们的要求,因为你实际上只要用Java编写一次代码,就能移植到这两个平台。目前,只有OS X桌面得到全面支持,不过也有试验性的Linux和Windows版本面向安卓开发。  10.Titanium  来自Appcelerator —不像那些比较偏向Web的框架,Titanium使用Java来构建原生代码,声称有望提升性能。这种基于Node.js的软件开发工具包(SDK)为iOS、安卓、Windows、黑莓和HTML5提供了5000多个API。Titanium更广为人知的地方是性能和丰富的功能特性,而不是易用性。软件是开源,不过只要你不发布你的应用程序,功能齐全的免费版可以免费享用,眼下你每月至少得支付39美元。

android retrofit 上传进度requestbody writeto 为什么会调用两次

用Retrofit发送网络请求和解析json的实例Retrofit是Android的一个非常好用的开源HTTPRequest。现在介绍一下Retrofit是如何使用的。。。。首先是导入Retrofit包,dependencies{compilefileTree(dir:"libs",include:["*.jar"])compile

android retrofit 2.0怎么post一个map

@FormUrlEncoded@POST("Comments/{newsId}")Call<Comment> reportComment(@Path("newsId") String commentId,@Field("reason") String reason);1234512345需要补全URL,问号后加入access_token,post的数据只有一条reason

android retrofit requestbody怎么传boolean类型

想传递boolean比较简单,可以用Bundle直接putBoolean对于List类型,需要E是继承了parcelable接口并且List实际类型要是ArrayList才可以.调用putParcelableArrayList(String key, ArrayList<? extends Parcelable> list);关于继承Parcelable接口需要完成以下内容:1,声明该类class MyParcelable implements Parcelable;2,创建Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>(){需要实现public MyParcelable createFromParcel(Parcel source){//例如MyParcelable有String name;MyParcelable p = new MyParcelable();p.name = source.readString();//所有成员都要处理.}public MyParcelable[] newArray(int size){return new MyParcelable[size];//这样就可以了}}

android retrofit上传二进制流 byte[] img

以下是图片上传方式:接口写法:Java code?123 @Multipart @POST("/user/addLicenseInfo") void addLicenseInfo(@QueryMap Map<String, Object> options, @Part("file") TypedFile file, Callback<JsonElement> response);实现写法:Java code?12345 API api = mRegisterActivity.createAPI(); Map<String, Object> options = new HashMap<String, Object>(); options.put("mobile",photoNumber); TypedFile typedImage = new TypedFile(getMIMEType(pictureFile), pictureFile); api.addLicenseInfo(options,typedImage,new Callback<JsonEleme

okhttp,retrofit,android-async-http,volley应该选择哪一个

个人认为okhttp是android平台最好的网络库。volley是一个简单的异步http库,仅此而已。缺点是不支持同步,这点会限制开发模式;不能post大数据,所以不适合用来上传文件。android-async-http,与volley一样是异步网络库。但volley是封装的httpUrlConnection,它是封装的httpClient,而android平台不推荐用HttpClient了,所以这个库已经不适合android平台了。okhttp是高性能的http库,支持同步、异步,而且实现了spdy、http2、websocket协议,api很简洁易用,和volley一样实现了http协议的缓存。picasso就是利用okhttp的缓存机制实现其文件缓存,实现的很优雅,很正确,反例就是UIL(universal image loader),自己做的文件缓存,而且不遵守http缓存机制。retrofit与picasso一样都是在okhttp基础之上做的封装,项目中可以直接用了。另外AndroidAsync这个网络库使用了nio的方式实现的。okhttp没有提供nio的方式,不过nio更适合大量连接的情况,对于移动平台有点杀鸡用牛刀的味道。picasso、uil都不支持inbitmap,项目中有用到picasso的富图片应用需要注意这点。

android retrofit post怎么传boby数据啊,后台接收不到

以下是我们在Api接口中的定义方法//以前我们使用我们定义好的POJO或javabean类作为callback的泛型,以便Retrofit帮我们解析@POST("/interface/xxxxxx")void getCouponList(Callback<Coupon> reponse);//但如果我们想获得JSON字符串,Callback的泛型里就不能写POJO类了,要写Response(retrofit.client包下)@POST("/interface/xxxxxx")void getCouponList(Callback<Response> reponse);那么在我们请求接口的时候,只需简单一行代码,就能拿到服务器返回的JSON字符串了ZhixueApiUtil.getInstance().getZhixueApi().getCouponList(new Callback<Response>() {@Overridepublic void success(Response response, Response response1) {//注意这里用第一个Response参数的String jsonString = new String(((TypedByteArray) response.getBody()).getBytes());//再使用Retrofit自带的JSON解析(或者别的什么)Coupon coupon = new Gson().fromJson(jsonString, Coupon.class);}@Overridepublic void failure(RetrofitError error) {}});至此,我们就能拿到JSON字符串了,在需要的时候可以用这种办法。

android 用rxjava和retrofit时怎么解决返回数据类型不一致

1 这种方法有两大步第一步是拼接需要的json数据,第二步是用servlet的内置对象response返回到前台。 2 String 类型的数据可以不用借助任何工具直接返回,只要把它拼接对了就可以。如我需要返回一个{“success”:true,“msg”:“修改失败!”}的json,就可以如下图这样写。(注意,java里的引号要用的转义字符“”) 3 如果需要返回的是一个list或者别的类的化,需要用到JSONArray的辅助工具类,然后使用response.getWriter().print(),返回到打到前台。具体代码如下图。 END 方法2:用Spring框架 如果你使用了Spring框架那就更简单了,你只需要在你的方法返回的时候加一个@ResponseBody的注解就可以了。就这么简单。

Android代理模式基础讲解

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。 静态代理的代理类持有被代理者的引用,在方法调用时,代理对象调用了被代理对象去执行真正的实现。 2.1 简单示例 假如对于一个日志处理功能,可通过代理类代理实例日志处理类: 这样,在使用过程中,可以按如下方式使用: 2.2 AIDL AIDL中也用到了代理模式,在Android Studio中新建一个AIDL文件,如下所示: 在点击make project后,会自动生成AIDL接口对应的代码,即对应的Stub和Proxy,可以看到AIDL的Proxy是通过静态代理实现,自动生成的代码如下所示: 在2.1的静态代理代码中,如果现在需要扩展一个新的接口,那就需要分别在接口层、实际处理类、代理类中分别改动,如下所示: 当代理一个新的接口时可见,新的代理类与其他代理类代码是高度相似的,因此可以采用动态代理的方式来完成类似的功能。 3.1 基础用法 与静态代理不同,动态代理类的class是在运行过程中动态生成的。 3.1.1 基础用法 首先定义接口层: 然后使用Proxy.newProxyInstance完成动态代理如下: 其中,InvocationHandler就是将静态代理中需要实现的部分抽离了出来,即动态生成的Proxy代理了InvocationHandler。 3.1.2 动态生成的class 动态生成的代理类的方法实际调用都到了InvocationHandler的invoke方法,动态生成的代理类class伪代码如下: 3.1.3 源码分析 下面分析Proxy.newProxyInstance的源码: 3.2 Retrofit动态代理 Retrofit是一个开源网络库,其源码中也使用到了动态代理模式。简单介绍如下: 3.2.1 基础用法 首先,新建网络请求对应的接口: 然后,使用Retrofit动态代理生成请求: 3.2.2 Retrofit动态代理实现 接下来分析Retrofit内部是如何使用动态代理模式的:

Android网络实战篇——OkHttp3(Retrofit2)五种缓存模式的实现

网上有许多写OKhttp3缓存的文章,例如: 【Okhttp3结合Retrofit2 实现缓存】 https://www.jianshu.com/p/74d2c10c3eba?from=timeline 【使用Retrofit和Okhttp3实现网络缓存】 https://www.jianshu.com/p/34f73e571ecb 【okhttp3缓存实践】 http://blog.csdn.net/wuhengde/article/details/54927096 这些文章都很不错,但还是有一些小小的瑕疵,这里我参考他们的文章结合自己的实践简单封装了Okhttp3的五种缓存方式供大家参考,如有错误还请不吝赐教。 主要知识点: public class OkHttpUtil { } 后记:如有不同见解或疑惑,欢迎留言,如果觉得不错可以来个赞!点个赞!

在Android中使用retrofit时,怎样获取响应的头信息

如何让你的电脑通过安卓手机上网 (本人用的是三星GT-S5830,USB连接方式) 准备工作: 1.下载手机的usb驱动 2.下载PDANet,, 选择Version 2.45 installer for 32-bit Windows 7/Vista/

android 网络请求Retrofit+Rxjava报错

检查项目依赖的retrofit和rxjava版本是否一致,大多数java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.都是由于这个问题造成的2. compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"compile "com.squareup.retrofit2:retrofit:2.1.0"把版本调成一样的,重新gradle一下应该就阔以了

【Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMap...

对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了。 下面分为GET、POST、DELETE还有PUT的请求,说明@Path、@Query、@QueryMap、@Body、@Field的用法。 http://102.10.10.132/api/News http://102.10.10.132/api/News/1 http://102.10.10.132/api/News/ {资讯id} 或 http://102.10.10.132/api/News/1/ 类型1 http://102.10.10.132/api/News/ {资讯id}/{类型} http://102.10.10.132/api/News?newsId=1 http://102.10.10.132/api/News?newsId= {资讯id} 或 http://102.10.10.132/api/News?newsId=1&type= 类型1 http://102.10.10.132/api/News?newsId= {资讯id}&type={类型} http://102.10.10.132/api/News?newsId=1&type= 类型1... http://102.10.10.132/api/News?newsId= {资讯id}&type={类型}... 也可以 http://102.10.10.132/api/Comments/1 http://102.10.10.132/api/Comments/ {newsId} http://102.10.10.132/api/Comments/1?access_token=1234123 http://102.10.10.132/api/Comments/ {newsId}?access_token={access_token} http://102.10.10.132/api/Comments/1?access_token=1234123 http://102.10.10.132/api/Comments/ {newsId}?access_token={access_token} http://102.10.10.132/api/Comments/1 http://102.10.10.132/api/Comments/ {commentId} http://102.10.10.132/api/Comments/1?access_token=1234123 http://102.10.10.132/api/Comments/ {commentId}?access_token={access_token} http://102.10.10.132/api/Comments CommentBody :需要提交的内容,与 Post 中的 Body 相同 http://102.10.10.132/api/Accounts/1 http://102.10.10.132/api/Accounts/ {accountId} @Path:所有在网址中的参数(URL的问号前面),如: http://102.10.10.132/api/Accounts/ {accountId} @Query:URL问号后面的参数,如: http://102.10.10.132/api/Comments?access_token= {access_token} @QueryMap:相当于多个@Query @Field:用于POST请求,提交单个数据 @Body:相当于多个@Field,以对象的形式提交 Tips

在Android中使用retrofit时,怎样获取响应的头信息

获取方法有两种获取Response Headers的方法直接在定义接口是让接口返回Retrofit的Response对象,在Response对象中可以获取到Headers2. 在构建Retrofit的APIService时,在OkHttpClient中加入Interceptor,用以拦截请求和响应获取请求头和响应头。此方法可用于Retrofit2和OKHttp3.Interceptor必须在OkHttpClient构建时加入,OKHttpClient的interceptors()方法返回的是一个不可编辑的列表,
 首页 上一页  1 2 3 4 5 6 7 8 9 10  下一页  尾页