Android相关小技术代码.doc_第1页
Android相关小技术代码.doc_第2页
Android相关小技术代码.doc_第3页
Android相关小技术代码.doc_第4页
Android相关小技术代码.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

检查网络是否连接上Java代码 1. /* 2. *检测网络是否连接(注:需要在配置文件即AndroidManifest.xml加入权限) 3. * 4. *paramcontext 5. *returntrue:网络连接成功 6. *returnfalse:网络连接失败 7. */ 8. publicstaticbooleanisConnect(Contextcontext) 9. /获取手机所有连接管理对象(包括对wi-fi,net等连接的管理) 10. ConnectivityManagerconnectivity=(ConnectivityManager)context 11. .getSystemService(Context.CONNECTIVITY_SERVICE); 12. if(connectivity!=null) 13. /获取网络连接管理的对象 14. NetworkInfoinfo=connectivity.getActiveNetworkInfo(); 15. if(info!=null) 16. /判断当前网络是否已经连接 17. if(info.getState()=NetworkInfo.State.CONNECTED) 18. returntrue; 19. 20. 21. 22. returnfalse; 23. =函数用于判断网络是否可用Java代码 1. /* 2. *returnbooleanreturntrueiftheapplicationcanaccesstheinternet 3. */ 4. privatebooleanhaveInternet() 5. NetworkInfoinfo=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE).getActiveNetworkInfo(); 6. if(info=null|!info.isConnected() 7. returnfalse; 8. 9. if(info.isRoaming() 10. /hereistheroamingoptionyoucanchangeitifyouwanttodisableinternetwhileroaming,justreturnfalse 11. returntrue; 12. 13. returntrue; 14. 需要注意的是有关调用需要加入 这个权限,android开发网提醒大家在真机上Market和Browser程序都使用了这个方法,来判断是否继续,同时在一些网络超时的时候也可以检 查下网络连接是否存在,以免浪费手机上的电力资源。浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制=libs/android_runtime/android_net_wifi_Wifi.cpp部分jni接口static JNINativeMethod gWifiMethods = loadDriver, ()Z, (void *)android_net_wifi_loadDriver , setPowerModeCommand, (I)Z, (void*) android_net_wifi_setPowerModeCommand ,/电源管理 connectToSupplicant, ()Z, (void *)android_net_wifi_connectToSupplicant , waitForEvent, ()Ljava/lang/String;, (void*) android_net_wifi_waitForEvent , disconnectCommand, ()Z, (void *)android_net_wifi_disconnectCommand , .;int register_android_net_wifi_WifiManager(JNIEnv* env) . return AndroidRuntime:registerNativeMethods(env, WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods);/登记jnilibs/android_runtime/AndroidRuntime.cppstatic const RegJNIRec gRegJNI = . REG_JNI(register_android_net_wifi_WifiManager), .;int AndroidRuntime:startReg(JNIEnv* env) . register_jni_procs(gRegJNI, NELEM(gRegJNI), env); .AndroidRuntime:start=startReg(env)即调用方法int AndroidRuntime:startReg(JNIEnv* env)=wifi_load_driverwifi_start_supplicant=ensure_config_file_exists/检查/data/misc/wifi/wpa_supplicant.conf文件是否存在,如果不存在,那么从/system/etc/wifi/wpa_supplicant.conf动态拷贝一份android_net_wifi_connectToSupplicant=wifi_connect_to_supplicant= ctrl_conn = wpa_ctrl_open(ifname); monitor_conn = wpa_ctrl_open(ifname); wpa_ctrl_attach(monitor_conn);android_net_wifi_waitForEvent=wifi_wait_for_event=wpa_ctrl_recv(monitor_conn, buf, &nread);=recv(ctrl-s, reply, *reply_len, 0);/阻塞等待wpa_supplicant的netlink数据过来=如果接收的buf数据区,buf0为,那么说明有level级别信息,所以将数据剔除,然后wifi_wait_for_event函数返回luther.gliethttp.java/android/android/net/wifi/WifiMonitor.javapublic class WifiMonitor . public void startMonitoring() new MonitorThread().start();/启动java线程 class MonitorThread extends Thread public MonitorThread() super(WifiMonitor); public void run() for (;) ensureSupplicantConnection();/=WifiNative.connectToSupplicant调用jni函数android_net_wifi_connectToSupplicant String eventStr = WifiNative.waitForEvent();/=调用jni函数android_net_wifi_waitForEvent /private static final int CONNECTED = 1; /private static final int DISCONNECTED = 2; /private static final String eventPrefix = CTRL-EVENT-; /private static final int eventPrefixLen = eventPrefix.length(); /private static final String connectedEvent = CONNECTED; /private static final String disconnectedEvent = DISCONNECTED; String eventName = eventStr.substring(eventPrefixLen);/去掉CTRL-EVENT-字符串 int nameEnd = eventName.indexOf( );/找到随后的空格位置,这在wpa_supplicant发送时/#define WPA_EVENT_CONNECTED CTRL-EVENT-CONNECTED 中,已经内置空格了. if (nameEnd != -1) eventName = eventName.substring(0, nameEnd); int event; if (eventName.equals(connectedEvent)/检测netlink过来的字符串action类型 event = CONNECTED; else if (eventName.equals(disconnectedEvent) event = DISCONNECTED; . int ind = eventStr.indexOf( - );/CTRL-EVENT-CONNECTED - Connection to . if (ind != -1) eventData = eventStr.substring(ind + 3);/剔除前导控制字符,将 - 后面的描述字符串作为真实数据,继续处理 . if (event = STATE_CHANGE) handleSupplicantStateChange(eventData); else if (event = DRIVER_STATE) handleDriverEvent(eventData); else handleEvent(event, eventData);/对于CONNECTED和DISCONNECTED等netlink事件将执行此操作来处理luther.gliethttp / If supplicant is gone, exit the thread if (event = TERMINATING) break; . void handleEvent(int event, String remainder) switch (event) case DISCONNECTED: handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder); break; 本篇文章来源于:开发学院 原文链接:/2009/1231/19239.phpcase CONNECTED: handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);/控制界面显示 break; .public class WifiStateTracker extends NetworkStateTracker . public void startEventLoop() mWifiMonitor.startMonitoring();/启动上面的MonitorThread线程 .java/services/com/android/server/WifiService.javapublic class WifiService extends IWifiManager.Stub . private boolean setWifiEnabledBlocking(boolean enable) final int eventualWifiState = enable ? WIFI_STATE_ENABLED : WIFI_STATE_DISABLED; . if (enable) if (WifiNative.loadDriver() Log.e(TAG, Failed to load Wi-Fi driver.); updateWifiState(WIFI_STATE_UNKNOWN); return false; if (WifiNative.startSupplicant() WifiNative.unloadDriver(); Log.e(TAG, Failed to start supplicant daemon.); updateWifiState(WIFI_STATE_UNKNOWN); return false; mWifiStateTracker.startEventLoop();/启动MonitorThread线程,等待wpa_supplicant将netlink数据转发过来,然后根据netlink动作类型,进一步影响界面显示luther.gliethttp. .java/android/android/net/wifi/WifiStateTracker.java电源管理private void handleConnectedState() . mDhcpTarget.obtainMessage(EVENT_DHCP_START).sendToTarget();/传递到下面的handleMessage方法 .public void onChange(boolean selfChange) . handleConnectedState(); .public class WifiStateTracker extends NetworkStateTracker . public void handleMessage(Message msg) switch (msg.what) case EVENT_SUPPLICANT_CONNECTION: case EVENT_NETWORK_STATE_CHANGED: handleConnectedState();/调用 . private class DhcpHandler extends Handler private Handler mTarget; public DhcpHandler(Looper looper, Handler target) super(looper); mTarget = target; public void handleMessage(Message msg) int event; /private static final int DRIVER_POWER_MODE_AUTO = 0; /private static final int DRIVER_POWER_MODE_ACTIVE = 1; switch (msg.what) case EVENT_DHCP_START: synchronized (this) WifiNative.setPowerModeCommand(DRIVER_POWER_MODE_ACTIVE);/设置电源模式,调用android_net_wifi_setPowerModeCommand Log.d(TAG, DhcpHandler: DHCP request started);/libs/android_runtime/android_net_NetUtils.cpp/static JNINativeMethod gNetworkUtilMethods = / runDhcp, (Ljava/lang/String;Landroid/net/DhcpInfo;)Z, (void *)android_net_utils_runDhcp ,/ ./; 本篇文章来源于:开发学院 原文链接:/2009/1231/19239_2.phpif (NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo) /执行dhcp申请ip地址操作 event = EVENT_INTERFACE_CONFIGURATION_SUCCEEDED; if (LOCAL_LOGD) Log.v(TAG, DhcpHandler: DHCP request succeeded); else event = EVENT_INTERFACE_CONFIGURATION_FAILED; Log.i(TAG, DhcpHandler: DHCP request failed: + NetworkUtils.getDhcpError();/如果dhcpcd分配ip失败,那么Message.obtain(mTarget, event).sendToTarget();将执行/WifiNative.disconnectCommand();即:static JNINativeMethod gWifiMethods = /android_net_wifi_disconnectCommand发送DISCONNECT字符串luther.gliethttp/然后在wpa_supplicant服务端执行wpa_supplicant_ctrl_iface_process/wpa_supplicant_disassociate synchronized (this) WifiNative.setPowerModeCommand(DRIVER_POWER_MODE_AUTO); Message.obtain(mTarget, event).sendToTarget(); break; . /* * Send the tracker a notification that a connection to the supplicant * daemon has been established. */在上面的public class WifiMonitor=ensureSupplicantConnection/=/while (!supplicantConnected) / boolean connected;/synchronized (mWifiStateTracker) /connected = WifiNative.connectToSupplicant();/如果没有连接成功,那么while循环尝试,直到尝试成功,或者定义了oneShot,仅一次尝试/=mWifiStateTracker.notifySupplicantConnection();/如果WifiNative.connectToSupplicant()成功,那么将执行/mWifiStateTracker.notifySupplicantConnection();的调用. void notifySupplicantConnection() /向对象发送message Message.obtain(this, EVENT_SUPPLICANT_CONNECTION).sendToTarget(); void notifyStateChange(SupplicantState newState) Message.obtain(this, EVENT_SUPPLICANT_STATE_CHANGED, newState).sendToTarget(); .static jboolean android_net_wifi_setPowerModeCommand(JNIEnv* env, jobject clazz, jint mode) char cmdstr256; sprintf(cmdstr, DRIVER POWERMODE %d, mode); return doBooleanCommand(cmdstr, OK);android_net_wifi_setPowerModeCommand=doBooleanCommand=doCommand=wifi_command=wifi_send_command=wpa_ctrl_request=send给wpa_supplicant然后wpa_supplicant将做如下接收操作:system/extra/wpa_supplicant/main.c=wpa_supplicant_add_iface=wpa_supplicant_init_iface2=wpa_supplicant_ctrl_iface_init=注册ctrl_conn控制端口和monitor_conn监听端口的处理函数 eloop_register_read_sock(priv-sock, wpa_supplicant_ctrl_iface_receive, wpa_s, priv);/ctrl_conn端口的handler处理函数 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);/monitor_conn端口的回调处理函数,处理netlink数据到所有monitor_conn监听端口=wpa_supplicant_ctrl_iface_receive/对于unix通信方式=wpa_supplicant_ctrl_iface_process=如果wpa_cli发送的是wpa_cli driver xxx形式的命令,那么调用这个函数if (os_strncmp(buf, DRIVER , 7) = 0) /掠过前7个,直接将命令传过去reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, reply_size);=wpa_supplicant_driver_cmd=wpa_drv_driver_cmd=自定义DRIVER扩展处理函数,所以对于java传递过来的power电源管理命令,wpa_drv_driver_cmd将收到POWERMODE 0或者POWERMODE 1字符串luther.gliethttp=jni=runDhcp=android_net_utils_runDhcplibs/netutils/dhcp_utils.c=dhcp_do_request= static const char DAEMON_NAME = dhcpcd; static const char DAEMON_PROP_NAME = init.svc.dhcpcd; static const char DHCP_PROP_NAME_PREFIX = dhcp; const char *ctrl_prop = ctl.start; const char *desired_status = running; snprintf(result_prop_name, sizeof(result_prop_name), %s.%s.result, DHCP_PROP_NAME_PREFIX, interface); property_set(result_prop_name, );/设置dhcp.eth0.result=;等到成功完成dhcp之后, property_set(ctrl_prop, DAEMON_NAME);/向名字为dhcpcd的service,发送ctrl.start启动命令字,该service在init.rc中/init.rc中dhcpcd服务进程命令字/service dhcpcd /system/bin/dhcpcd eth0/ disabled/ oneshot wait_for_property(DAEMON_PROP_NAME, desired_status, 10);/init.c=init进程/=handle_property_set_fd因为是ctrl.start命令字,所以调用handle_control_message处理控制信息/=handle_control_message/=msg_start/=/ struct service *svc = service_find_by_name(name);/ service_start(svc);/启动svc,即执行:/system/bin/dhcpcd eth0/=service_start/=pid = fork();/ if(pid = 0)execve(svc-args0, (char*) svc-args, (char*) ENV);子进程执行execve运行/system/bin/dhcpcd,参数为eth0/=否则父进程,即init进程将/=notify_service_state(svc-name, running);设置该svc的状态prop/ snprintf(pname, sizeof(pname), init.svc.%s, name);/ property_set(pname, state);/所以这样上面wait_for_property(DAEMON_PROP_NAME, desired_status, 10);也才能够正常passluther.gliethttp. wait_for_property(result_prop_name, NULL, 15);/等待dhcp.eth0.result=非空=system/extra/dhcpcd-4.0.0-beta9/dhcpcd.cdhcpcd=main# define SYSCONFDIR /system/etc/dhcpcd#define PACKAGE dhcpcd# define CONFIG SYSCONFDIR / PACKAGE .conf# define LIBEXECDIR /system/etc/dhcpcd# define SCRIPT LIBEXECDIR / PACKAGE -run-hooks=strlcpy(options-script, SCRIPT, sizeof(options-script);/默认的options-script=/system/etc/dhcpcd/dhcpcd-run-hooks=f = fopen(cf ? cf : CONFIG, r);/如果没有指定.conf文件,那么使用默认.conf文件=parse_config_line/解析/system/etc/dhcpcd/dhcpcd.conf默认配置文件=parse_option=如果在/system/etc/dhcpcd/dhcpcd.conf有script这个节=那么执行strlcpy(options-script, oarg, sizeof(options-script);直接拷贝/*script, required_argument, NULL, c,option, required_argument, NULL, o,/system/etc/dhcpcd/dhcpcd.conf中的部分内容如下:.option domain_name_servers, domain_name, domain_search, host_name.*/=dhcp_run=handle_dhcp_packet=handle_dhcp=bind_dhcp reason = TIMEOUT;reason = BOUND;reason = REBIND;reason = RENEW;system/extra/dhcpcd-4.0.0-beta9/configure.c= configure(iface, reason, state-new, state-old, &state-lease, options, 1);/如果dhcp超时或者dhcp成功,都会调用exec_script来执行脚本,/执行setprop dhcp.$interface.result failed或者/执行setprop dhcp.$interface.result ok=exec_script(options, iface-name, reason, NULL, old);=然后configure_env通过环境变量将reason传递到脚本中int exec_script(const struct options *options, const char *iface, const char *reason, const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo)=pid = fork();=if(pid = 0)execve(options-script, argv, env);/子进程执行脚本,默认/system/etc/dhcpcd/dhcpcd-run-hooks/dhcpcd-run-hooks脚本会根据level值,决定是否执行system/etc/dhcpcd/dhcpcd-hook/*目录下的相应文件/我们的系统在该system/etc/dhcpcd/dhcpcd-hook/*目录下有如下3个文件/95-configured/20-dns.conf/01-test=父进程返回while (waitpid(pid, &status, 0) = -1)等待子进程脚本执行完成本篇文章来源于:开发学院 原文链接:/2009/1231/19239_3.phpsystem/extra/dhcpcd-4.0.0-beta9/dhcpcd-hooks/20-dns.confsystem/extra/dhcpcd-4.0.0-beta9/dhcpcd-hooks/95-configured . setprop dhcp.$interface.ipaddress $new_ip_address setprop dhcp.$interface.result ok/设置属性为ok setprop dhcp.$interface.result failed .=inet_init、tcp_protsock-ops-sendmsg(iocb, sock, msg, size);=inetsw_array=inet_stream_ops=tcp_sendmsg=wpa_cli.c=main=wpa_cli_interactive=wpa_cli_recv_pending(monitor_conn, 0, 0);/阻塞等待wpa_supplicant发送数据过来=如果action_monitor为true,那么将执行一些简单加工操作,否则将直接将wpa_supplicant发过来的数据打印到console上luther.gliethttp. 本篇文章来源于:开发学院 原文链接:/2009/1231/19239_4.phpAndroid操作系统并没有提供任务管理器程序,无从得知后台有哪些程序正在运行。本范例是通过ActivityManager.getRunningTasks方法来取得正在运行中的工作程序,并使用ListView将之罗列出来。 这里说的“正在运行”是指单击“按钮”时所获取到的信息,如果放在ListView里的工作已经结束,或者被操作系统回收(Garbage Collection,GC),此时是不会更新运行列表的,而由于没有其他运行中工作的访问权限,因此也不能通过本程序关闭。 在以下范例的Layout里,设计一个TextView、一个ListView以及一个按钮,通过按钮单击的事件,同时向系统ActivityManager取出正在运行的Activity Tasks。 范例程序 src/irdc.ex05_21/EX05_21.java 在访问系统Activity的运行工作时,必须指定要取得的工作数量,因为资源有限,所以在类成员中设置了最多取出30笔的Activity运行工作。 单击按钮之后,便会使得私有类成员mActivityManager重新向系统

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论