更踪设备的地理位置(LocationManager)
来源:互联网 发布:tb复刻比较好的淘宝店 编辑:程序博客网 时间:2024/05/29 09:35
地理位置与LocationManager
Android系统中的地理位置数据是由LocationManager系统服务提供的。该系统服务向所有需要地理数据的应用提供数据更新。更新数据的传送通常采用两种方式。
其中,使用LocationListener接口可能是最直接的一种方式。通过onLocationChanged(Location)方法,该接口提供的信息有:地理位置数据更新、状态更新以及定位服务提供者启动状态的通知消息。
如只需将地理位置数据发送给应用中的单个组件,使用LocationListener接口会很方便。提供LocationListener接口实现给LocationManager的requestLocationUpdates(…)或requestSingleUpdate(…)方法即可。
然而,若不管用户界面是否存在(如应用在后台运行),应用都需要持续定位用户地理位置。当然,我们也可以使用stickyService,但stickyService本身复杂难用,而且这种方式也不够轻量级。因此,我们使用自Android 2.3开始引入的PendingIntent。
使用PendingIntent获取地理位置信息更新,我们实际是要求LocationManager在将来某个时点帮忙发送某种类型的Intent。这样,即使应用组件。甚至是整个应用进程都销毁了,LocationManager仍会一直发送Intent,直到要求停止并按需启动新组件响应它们。利用这种优势,即使持续进行设备定位,也可以避免应用消耗过多的资源。
为管理与LocationManager的通讯,创建一个名为RunManager的单例类:
package com.huangfei.runtracker;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.location.Location;import android.location.LocationManager;public class RunManager { public static final String TAG = "RunManager"; public static final String ACTION_LOCATION = "com.huangfei.runtracker.ACTION_LOCATION"; private static RunManager sRunManager; private Context mAppContext; private LocationManager mLocationManager; private RunManager(Context appContext) { mAppContext = appContext; mLocationManager = (LocationManager) mAppContext .getSystemService(Context.LOCATION_SERVICE); } public static RunManager get(Context context) { if (sRunManager == null) { sRunManager = new RunManager(context.getApplicationContext()); } return sRunManager; } private PendingIntent getLocationPeindingIntent(boolean shouldcCreate) { Intent broadcast = new Intent(ACTION_LOCATION); int flags = shouldcCreate ? 0 : PendingIntent.FLAG_NO_CREATE; //flags参数告诉 PendingIntent.getBroadcast方法是否应该在系统中创建新的PendingIntent return PendingIntent.getBroadcast(mAppContext, 0, broadcast, flags); } /** * 启动地理位置更新 */ public void startLocationupdates() { // 要求LocationManager通过GPS定位装置提供实时的定位数据更新 String provider = LocationManager.GPS_PROVIDER; /** * 利用LocationManager的最近一次地理位置(使用于各种定位方式,如GPS、WIFE网络、手机基站等), * 来消除免用户开启定位时的长时间等待。 * * 也可向LocationManager请求来自不同定位服务提供者的最近一次地理位置信息,或使用getAllProviders()方法 * 获知协同工作的定位服务提供者。如遍历查看所有最近一次地理位置信息,应查看其准确性,并确定是否为比较新的时间戳。如较为久远, * 可不采用这些数据信息。 */ Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider); if(lastKnownLocation != null){ lastKnownLocation.setTime(System.currentTimeMillis()); broadcastLocation(lastKnownLocation); } PendingIntent pi = getLocationPeindingIntent(true); /** * requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent) * 四个参数中,最小等待时间(以毫秒为单位)以及最短移动距离(以米为单位)可用与决定发送下一次定位数据更新要移动的距离和要等待的时间 */ mLocationManager.requestLocationUpdates(provider, 0, 0, pi); } /** * 发送最近一次地理位置信息的广播 */ private void broadcastLocation(Location lastKnownLocation) { Intent intent = new Intent(ACTION_LOCATION); intent.putExtra(LocationManager.KEY_LOCATION_CHANGED, lastKnownLocation); mAppContext.sendBroadcast(intent); } /** * 停止地理位置更新 * */ public void stopLocationUpdates() { PendingIntent pi = getLocationPeindingIntent(false); if (pi != null) { mLocationManager.removeUpdates(pi); pi.cancel(); } } /** * 判断地理位置是否更新 */ public boolean isTrackRun() { return getLocationPeindingIntent(false) != null; }}
接收定位数据更新broadcast
package com.huangfei.runtracker;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.location.Location;import android.location.LocationManager;import android.util.Log;public class LocationReceiver extends BroadcastReceiver { public static final String TAG = "LocationReceiver"; @Override public void onReceive(Context context, Intent intent) { /** * LocationManager打包了附加额外信息的intent * LocationManager.KEY_LOCATION_CHANGED键值可指定一个表示最新更新的Location实例 */ Location location = (Location) intent .getParcelableExtra(LocationManager.KEY_LOCATION_CHANGED); if (location != null) { onLocationReceived(context, location); return; } if (intent.hasExtra(LocationManager.KEY_PROVIDER_ENABLED)) { boolean enabled = intent.getBooleanExtra( LocationManager.KEY_PROVIDER_ENABLED, false); onProviderEnabledChanged(enabled); } } protected void onProviderEnabledChanged(boolean enabled) { Log.d(TAG, "Provider " + (enabled ? "enabled" : "disabled")); } protected void onLocationReceived(Context context, Location location) { Log.d(TAG, this + " Got location from " + location.getProvider() + ": " + location.getLatitude() + ", " + location.getLongitude()); }}
<!-- 添加定位的权限以及GPS硬件uses-feature节点的添加 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.location.gps" android:required="true" /><receiver android:name="com.huangfei.runtracker.LocationReceiver" android:exported="false" > <intent-filter> <action android:name="com.huangfei.runtracker.ACTION_LOCATION" /> </intent-filter> </receiver>
使用定位数据刷新UI显示
package com.huangfei.runtracker;import android.content.BroadcastReceiver;import android.content.Context;import android.content.IntentFilter;import android.location.Location;import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;public class RunFragment extends Fragment { private BroadcastReceiver mLocationReceiver = new LocationReceiver(){ protected void onLocationReceived(Context context, Location location) { mLastLocation = location; if(isVisible()) updateUI(); } protected void onProviderEnabledChanged(boolean enabled) { //GPS服务提供者启动或停止时,消息提示 int toastText = enabled ? R.string.gps_enabled : R.string.gps_disabled; Toast.makeText(getActivity(), toastText, Toast.LENGTH_LONG).show(); } }; private RunManager mRunManager; private Run mRun; private Location mLastLocation; private Button mStartButton, mStopButton; private TextView mStartedTextView, mLatitudeTextView, mLongitudeTextView, mAltitudeTextView, mDurationTextView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); mRunManager = RunManager.get(getActivity()); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_run, container, false); mStartedTextView = (TextView) view .findViewById(R.id.run_startedTextView); mLatitudeTextView = (TextView) view .findViewById(R.id.run_latitudeTextView); mLongitudeTextView = (TextView) view .findViewById(R.id.run_longitudeTextView); mAltitudeTextView = (TextView) view .findViewById(R.id.run_altitudeTextView); mDurationTextView = (TextView) view .findViewById(R.id.run_durationTextView); mStartButton = (Button) view.findViewById(R.id.run_startButton); mStartButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mRunManager.startLocationupdates(); mRun = new Run(); updateUI(); } }); mStopButton = (Button) view.findViewById(R.id.run_stopButton); mStopButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mRunManager.stopLocationUpdates(); updateUI(); } }); return view; } @Override public void onStart() { super.onStart(); getActivity().registerReceiver(mLocationReceiver, new IntentFilter(RunManager.ACTION_LOCATION)); } @Override public void onStop() { super.onStop(); getActivity().unregisterReceiver(mLocationReceiver); } private void updateUI(){ boolean started = mRunManager.isTrackRun(); if(mRun != null){ mStartedTextView.setText(mRun.getSartDate().toString()); } int durationSenconds = 0; if(mRun != null && mLastLocation != null){ durationSenconds = mRun.getDurationSeconds(mLastLocation.getTime()); mLatitudeTextView.setText(Double.toString(mLastLocation.getLatitude())); mLongitudeTextView.setText(Double.toString(mLastLocation.getLongitude())); mAltitudeTextView.setText(Double.toString(mLastLocation.getAltitude())); } mDurationTextView.setText(Run.formatDuration(durationSenconds)); mStartButton.setEnabled(!started); mStopButton.setEnabled(started); }}
代码地址
- 更踪设备的地理位置(LocationManager)
- locationManager.getLastKnownLocation(locationProvider);//地理位置获取为null的解决方案
- 安卓LocationManager获取当前地理位置(经纬度)
- 使用LocationManager获取GPS地理位置信息
- 定位 互相发现设备(地理位置共享设备)
- Android 地理位置Location服务之LocationManager,Geocoder详解
- Android 地理位置Location服务之LocationManager,Geocoder详解
- LocationManager 的简单使用
- android LocationManager的使用
- LocationManager的基本用法
- LocationManager的用法
- LocationManager的位置获取
- LocationManager的使用
- iOS获取当前设备的型号、分辨率、运营商以及地理位置
- 客户端的ip、地理位置、浏览器、以及访问设备
- android:LocationManager详解(-)
- LocationManager
- LocationManager
- 智能指针auto_ptr
- C# Datetime.Ticks将时间转换成以秒为单位与格林尼治时间
- PostgreSQL general public partition table trigger
- 你不知道的JavaScript--Item2 浮点数精度
- 九度OJ 1004:Median
- 更踪设备的地理位置(LocationManager)
- PL/SQL Developer 连接Oracle数据库详细配置方法
- 黑马程序员_JAVA笔记之(File类,过滤器,递归练习)
- C++中windwos数据类型和类型转换
- 数据结构-链表
- Prim实现最小生成树
- 笔试题——数据库索引的作用
- 关于java中有符号数转换成无符号数的相关问题
- 黑马程序员_JAVA之IO流的(字节流与字符流)