12 .Android Location的使用

本文介绍了一个简单的Android应用示例,用于获取设备的位置信息,并显示经纬度坐标。通过使用LocationManager和Location服务,开发者可以轻松地集成GPS和网络定位功能。

大家好,今天说说Android Location,Location在Android开发中还是经常用到的,比如通过经纬度获取天气,根据Location获取所在地区详细地址(比如Google Map开发)等。而在Android中通过LocationManager来获取Location,通常获取Location有GPS获取、WIFI获取。

我今天做一个简单的小Demo,来教大家如何获取Location,从而获取经纬度。下一节将教大家通过Location来获取Address。

第一步:创建一个Android工程命名为LocationDemo

第二步:修改main.xml代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<? xml version = "1.0" encoding = "utf-8" ?>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     android:orientation = "vertical"
     android:layout_width = "fill_parent"
     android:layout_height = "fill_parent" >
     < TextView
         android:id = "@+id/longitude"
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:text = "longitude:"
         />
     < TextView
         android:id = "@+id/latitude"
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:text = "latitude:"
         />
</ LinearLayout >

第三步:修改LocationDemo.java,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.android.tutor;
 
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
 
public class LocationDemo extends Activity {
 
     private TextView longitude;
     private TextView latitude;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
 
         longitude = (TextView) findViewById(R.id.longitude);
         latitude = (TextView) findViewById(R.id.latitude);
 
         Location mLocation = getLocation( this );
 
         longitude.setText( "Longitude: " + mLocation.getLongitude());
         latitude.setText( "Latitude: " + mLocation.getLatitude());
     }
 
     // Get the Location by GPS or WIFI
     public Location getLocation(Context context) {
         LocationManager locMan = (LocationManager) context
                 .getSystemService(Context.LOCATION_SERVICE);
         Location location = locMan
                 .getLastKnownLocation(LocationManager.GPS_PROVIDER);
         if (location == null ) {
             location = locMan
                     .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
         }
         return location;
     }
}

第四步:增加权限,修改AndroidManifest.xml代码如下(第14行为所增行):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<? xml version = "1.0" encoding = "utf-8" ?>
< manifest xmlns:android = "http://schemas.android.com/apk/res/android"
     package = "com.android.tutor" android:versionCode = "1"
     android:versionName = "1.0" >
     < application android:icon = "@drawable/icon" android:label = "@string/app_name" >
         < activity android:name = ".LocationDemo" android:label = "@string/app_name" >
             < intent-filter >
                 < action android:name = "android.intent.action.MAIN" />
                 < category android:name = "android.intent.category.LAUNCHER" />
             </ intent-filter >
         </ activity >
     </ application >
     < uses-sdk android:minSdkVersion = "7" />
     < uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
</ manifest >

第五步:运行LocationDemo工程,所得效果如下(真机深圳测试):

LocationDemo


<think> 我们被要求分析一个调用堆栈,特别是关于`excom.android.server.am.OplusBootPressureHolder.delayStartProcessForBindService`函数的调用路径。这个堆栈描述了从`HandlerThread.run`开始一直到`delayStartProcessForBindService`的调用过程。 ### 调用堆栈解析(从下往上): 1. **最底层**:`com.android.server.location.thread.OplusLocationThread.run` -> 这是一个线程的入口,应该是自定义的线程类(可能是HandlerThread的子类)的run方法。 2. 然后进入`android.os.HandlerThread.run` -> HandlerThread是Android中的一种线程,它内部有Looper,可以处理消息。 3. `android.os.Looper.loop` -> 开始循环处理消息队列。 4. `android.os.Looper.loopOnce` -> 在API 23+中,loopOnce是实际处理单条消息的方法(但注意,在公开的API中,我们通常看到的是loop方法循环调用loopOnce,但loopOnce是隐藏方法)。 5. `android.os.Handler.dispatchMessage` -> 当Looper从消息队列中取出一条消息,就会调用Handler的dispatchMessage来处理。 6. `com.android.server.location.common.debugreport.DebugReportListener$1.handleMessage` -> 这是一个匿名内部类(第1个)的handleMessage方法,处理特定的消息。 7. `com.android.server.location.common.debugreport.DebugReportListener.-$$Nest$mhandleStart` -> 这里看起来是编译器生成的访问外部类私有方法的语法(可能是为了lambda或嵌套类访问)。实际调用`DebugReportListener`的私有方法`handleStart`。 8. `com.android.server.location.common.debugreport.DebugReportListener.handleStart` -> 这是处理开始的方法。 9. `com.android.server.location.common.debugreport.MtkDebugReportManager.startMtkDebugReport` -> 开始MtkDebugReport。 10. `com.android.server.location.common.debugreport.MtkDebugReportManager.bindService` -> 在这个方法中调用了绑定服务。 11. `android.app.ContextImpl.bindService` -> 这是绑定服务的入口,内部会调用`bindServiceCommon`。 12. `android.app.ContextImpl.bindServiceCommon` -> 绑定服务的通用逻辑。 13. `com.android.server.am.ActivityManagerService.bindServiceInstance` -> 这里调用了两次,可能是重载或者递归?但堆栈显示两次相同的调用,可能是堆栈打印的问题或者确实连续调用了两次?实际上,在ActivityManagerService中,bindServiceInstance方法可能会被递归调用,但通常不会。这里我们按堆栈顺序理解。 14. `com.android.server.am.ActiveServices.bindServiceLocked` -> ActiveServices是AMS中管理服务绑定的辅助类,bindServiceLocked是在锁内执行绑定服务的操作。 15. `com.android.server.am.ActiveServicesExtImpl.interceptBindServiceLockedBeforeConnection` -> 这是扩展实现(可能是厂商定制),在建立连接之前拦截绑定服务操作。 16. 最后调用到`excom.android.server.am.OplusBootPressureHolder.delayStartProcessForBindService` -> 这是Oppo(或一加)定制的方法,用于在启动压力大的时候延迟启动进程以绑定服务。 ### 关键点: - 这个调用链描述了从位置服务相关的线程(OplusLocationThread)发起的一个绑定服务的请求,最终被OplusBootPressureHolder拦截处理,可能会延迟启动进程。 - 堆栈中出现了厂商定制类(如OplusBootPressureHolder、ActiveServicesExtImpl)和MTK(联发科)相关的类(MtkDebugReportManager),说明这是特定设备(可能是Oppo/一加使用MTK平台)上的调用流程。 ### 作用: - `delayStartProcessForBindService`方法的作用可能是为了在系统启动压力较大时(例如,同时启动大量服务),延迟某些服务的启动绑定,以避免系统资源过度竞争,从而优化启动性能。 §§相关问题§§ 1.Android系统中,`HandlerThread`和`Looper`如何协同工作来处理异步消息? 2. `ActiveServices.bindServiceLocked`方法在服务绑定过程中扮演什么角色? 3. 厂商定制如`OplusBootPressureHolder.delayStartProcessForBindService`通常会在哪些场景下被触发? 4. 在服务绑定过程中,`ContextImpl.bindServiceCommon`方法主要完成了哪些关键步骤? 5. 为什么在绑定服务的过程中需要调用两次`ActivityManagerService.bindServiceInstance`? </think> ### 调用链分析:`delayStartProcessForBindService` 的触发路径 该调用链描述了 **OPPO 定制系统**(ColorOS)中服务绑定的延迟启动逻辑,核心是 `OplusBootPressureHolder.delayStartProcessForBindService` 方法。以下是关键节点解析: #### 1. **延迟启动的入口** - **`OplusBootPressureHolder.delayStartProcessForBindService`** OPPO 系统在**高启动负载**时延迟服务绑定的优化接口。 **作用**:当系统启动阶段资源紧张时,暂缓非关键服务的进程启动。 #### 2. **拦截层(厂商定制)** - **`ActiveServicesExtImpl.interceptBindServiceLockedBeforeConnection`** OPPO 扩展的拦截点,在标准绑定流程前插入检查: ```java if (系统启动压力高) { OplusBootPressureHolder.delayStartProcessForBindService(); // 触发延迟 return; // 中断标准绑定流程 } ``` #### 3. **标准 Android 绑定流程** - **`ActiveServices.bindServiceLocked`** Android 原生服务绑定的核心方法(线程安全)。 - **`AMS.bindServiceInstance`** 通过 Binder 跨进程调用,最终执行到 `ContextImpl.bindServiceCommon`。 - **`ContextImpl.bindServiceCommon`** 应用侧绑定服务的通用实现,向系统服务发起请求。 #### 4. **触发源头(位置服务)** - **`MtkDebugReportManager.startMtkDebugReport()`** 联发科位置调试模块的初始化方法。 - **`DebugReportListener.handleMessage()`** 通过 `HandlerThread` 异步处理启动请求: ```java public void handleMessage(Message msg) { if (msg.what == START_REPORT) { handleStart(); // 调用绑定服务 } } ``` - **线程载体**:`OplusLocationThread`(OPPO 定制的位置服务线程)。 ### 流程意义 该调用链展示了: 1. **厂商优化**:OPPO 通过扩展 `ActiveServicesExtImpl` 实现在系统高负载时**智能延迟服务绑定**,避免启动卡顿。 2. **模块耦合**:联发科位置调试模块依赖系统服务绑定,但被厂商拦截层动态调控。 3. **异步触发**:通过 `HandlerThread` 实现绑定操作的线程隔离,防止阻塞位置服务。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值