zoukankan      html  css  js  c++  java
  • GPS

    1.申请用户权限

      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    2.Java代码

    import java.util.Iterator;
    
    import android.app.Activity;
    import android.content.Context;
    import android.location.Criteria;
    import android.location.GpsSatellite;
    import android.location.GpsStatus;
    import android.location.Location;
    import android.location.LocationListener;
    import android.location.LocationManager;
    import android.location.LocationProvider;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.EditText;
    import android.widget.TextView;
    
    /**
     * 获取到位置服务以后,同时请求网络和gps定位更新,然后就会同时上报网络和gps的Location 信息。
     * 在没有gps信号的时候,会自动获取网络定位的位置信息,如果有gps信号,则优先获取gps提供的位置信息。
     * 使用 .isBetterLocation 根据时间、准确性、定位方式等判断是否更新当前位置信息,
     * 该方法来源于开发指南的Obtaining User Location。
     * 
     * 
     * @author THINK
     * 
     */
    public class MainActivity extends Activity {
        private EditText editText;
        private LocationManager lm;
        private Location currentlocation;  // 当前位置
        private static final String TAG = "h_bl";
        private TextView tv_show_log;
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            // 不要用的时候,移出监听器,不然会一直在获取
            lm.removeUpdates(locationListener);
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv_show_log=(TextView) findViewById(R.id.tv_show_log);
            editText = (EditText) findViewById(R.id.editText);
            // 1.创建LocationManager
            lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    
    /*         // 判断GPS是否正常启动
             if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
             Toast.makeText(this, "请开启GPS导航...", Toast.LENGTH_SHORT).show();
             // 返回开启GPS导航设置界面
             Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
             startActivityForResult(intent, 0);
             return;
             }*/
    
            // 为获取地理位置信息时设置查询条件
    //        String bestProvider = lm.getBestProvider(getCriteria(), true);
            // 获取位置信息
            // 如果不设置查询要求,getLastKnownLocation方法传人的参数为LocationManager.GPS_PROVIDER
            // getLastKnownLocation返回一个给定Provider提供的最后一个已知位置,提前提供,防止用户等待,但数据不精确
            currentlocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            tv_show_log.append("原始缓存数据:
    ");
            if (currentlocation!=null) {
                tv_show_log.append("时间:" + currentlocation.getTime()+"  经度:" + currentlocation.getLongitude()+"  纬度:" + currentlocation.getLatitude()+"  海拔:" + currentlocation.getAltitude()+"
    ");
            }
            updateView(currentlocation);
            // 监听状态
            lm.addGpsStatusListener(listener);
            // 绑定监听,有4个参数
            // 参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种
            // 参数2,位置信息更新周期,单位毫秒
            // 参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息
            // 参数4,监听
            // 备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新
    
            // 1秒更新一次,或最小位移变化超过1米更新一次;
            // 注意:此处更新准确度非常低,推荐在service里面启动一个Thread,在run中sleep(10000);然后执行handler.sendMessage(),更新位置
            // 同时启用net和gps
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 1, locationListener);
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 1, locationListener);
        }
    
        // 2.LocationListener位置监听
        private LocationListener locationListener = new LocationListener() {
    
            /**
             * 位置信息变化时触发
             */
            public void onLocationChanged(Location location) {
    //            tv_show_log.append("数据提供者:"+location.getProvider()+"
    ");
                // 判断位置是否更好
                if (isBetterLocation(location, currentlocation))
                {
                    tv_show_log.append("数据提供者:"+location.getProvider()+"
    ");
                    Log.d(TAG, "刷新位置");
                    tv_show_log.append("刷新位置
    ");
                    updateView(location);  // 更新ui数据
                    currentlocation=location; // 当前位置 替换为 更新获得的位置
                }else {
    //                updateView(currentlocation);  // 更新ui数据
                    Log.d(TAG, "未刷新位置");
                    tv_show_log.append("未刷新位置
    ");
                }
                Log.i(TAG, "时间:" + location.getTime());
                Log.i(TAG, "经度:" + location.getLongitude());
                Log.i(TAG, "纬度:" + location.getLatitude());
                Log.i(TAG, "海拔:" + location.getAltitude());
                tv_show_log.append("时间:" + location.getTime()+"  经度:" + location.getLongitude()+"  纬度:" + location.getLatitude()+"  海拔:" + location.getAltitude()+"
    ");
            }
    
            /**
             * GPS状态变化时触发
             */
            public void onStatusChanged(String provider, int status, Bundle extras) {
                switch (status) {
                // GPS状态为可见时
                case LocationProvider.AVAILABLE:
                    Log.i(TAG, "当前GPS状态为可见状态");
                    tv_show_log.append("当前GPS状态为可见状态
    ");
                    break;
                // GPS状态为服务区外时
                case LocationProvider.OUT_OF_SERVICE:
                    Log.i(TAG, "当前GPS状态为服务区外状态");
                    tv_show_log.append("当前GPS状态为服务区外状态
    ");
                    break;
                // GPS状态为暂停服务时
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    Log.i(TAG, "当前GPS状态为暂停服务状态");
                    tv_show_log.append("当前GPS状态为暂停服务状态
    ");
                    break;
                }
            }
    
            /**
             * GPS开启时触发
             */
            public void onProviderEnabled(String provider) {
                Location location = lm.getLastKnownLocation(provider);
                updateView(location);
            }
    
            /**
             * GPS禁用时触发
             */
            public void onProviderDisabled(String provider) {
                updateView(null);
            }
    
        };
    
        // 状态监听
        GpsStatus.Listener listener = new GpsStatus.Listener() {
            public void onGpsStatusChanged(int event) {
                switch (event) {
                // 第一次定位
                case GpsStatus.GPS_EVENT_FIRST_FIX:
                    Log.i(TAG, "第一次定位");
                    tv_show_log.append("第一次定位
    ");
                    break;
                // 卫星状态改变
                case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                    Log.i(TAG, "卫星状态改变");
                    tv_show_log.append("卫星状态改变
    ");
                    // 获取当前状态
                    GpsStatus gpsStatus = lm.getGpsStatus(null);
                    // 获取卫星颗数的默认最大值
                    int maxSatellites = gpsStatus.getMaxSatellites();
                    // 创建一个迭代器保存所有卫星
                    Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
                    int count = 0;
                    while (iters.hasNext() && count <= maxSatellites) {
                        GpsSatellite s = iters.next();
                        count++;
                    }
                    System.out.println("搜索到:" + count + "颗卫星");
                    tv_show_log.append("搜索到:" + count + "颗卫星
    ");
                    break;
                // 定位启动
                case GpsStatus.GPS_EVENT_STARTED:
                    Log.i(TAG, "定位启动");
                    tv_show_log.append("定位启动
    ");
                    break;
                // 定位结束
                case GpsStatus.GPS_EVENT_STOPPED:
                    Log.i(TAG, "定位结束");
                //    tv_show_log.append("定位结束
    ");
                    break;
                }
            };
        };
    
        /**
         * 实时更新文本内容
         * 
         * @param location
         */
        private void updateView(Location location) {
            if (location != null) {
                editText.setText("设备位置信息
    
    经度:");
                editText.append(String.valueOf(location.getLongitude()));
                editText.append("
    纬度:");
                editText.append(String.valueOf(location.getLatitude()));
            } else {
                // 清空EditText对象
                editText.getEditableText().clear();
            }
        }
    
        /**
         * 返回查询条件,暂时不用这个
         * 
         * @return
         */
        private Criteria getCriteria() {
            Criteria criteria = new Criteria();
            // 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细
            criteria.setAccuracy(Criteria.ACCURACY_FINE);
            // 设置是否要求速度
            criteria.setSpeedRequired(false);
            // 设置是否允许运营商收费
            criteria.setCostAllowed(false);
            // 设置是否需要方位信息
            criteria.setBearingRequired(false);
            // 设置是否需要海拔信息
            criteria.setAltitudeRequired(false);
            // 设置对电源的需求
            criteria.setPowerRequirement(Criteria.POWER_LOW);
            return criteria;
        }
        
        /**
         * 精度判断,来自Dev Guide
         */
        private static final int TWO_MINUTES = 1000 * 60 * 2; // 2分钟
    
        /** Determines whether one Location reading is better than the current Location fix
         *  确定获取的位置和当前位置,哪个比较好
          * @param location  The new Location that you want to evaluate 你想要评估的新位置
          * @param currentBestLocation  The current Location fix, to which you want to compare the new one 当前位置,你想比较的
          */
        protected boolean isBetterLocation(Location location, Location currentBestLocation) {
            if (currentBestLocation == null) {
                // A new location is always better than no location  有一个新位置总比没有位置要好
                return true;
            }
    
            // Check whether the new location fix is newer or older
            // 检查新地址是更新的还是更旧的
            long timeDelta = location.getTime() - currentBestLocation.getTime();
            boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
            boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
            boolean isNewer = timeDelta > 0;
    
            // If it's been more than two minutes since the current location, use the new location
            // because the user has likely moved
            // 如果从当前位置开始超过两分钟,使用新的位置,因为用户可能移动了
            if (isSignificantlyNewer) {
                return true;
            // If the new location is more than two minutes older, it must be worse
            // 如果从当前位置开始少于两分钟,使用新的位置,一定是因为出错了
            } else if (isSignificantlyOlder) {
                return false;
            }
    
            // Check whether the new location fix is more or less accurate
            // 检查当前地址的精度高了,还是低了。
            int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
            boolean isLessAccurate = accuracyDelta > 0;
            boolean isMoreAccurate = accuracyDelta < 0;
            boolean isSignificantlyLessAccurate = accuracyDelta > 200;
    
            // Check if the old and new location are from the same provider
            // 检查当前地址和旧地址,是否来自同一个provider
            boolean isFromSameProvider = isSameProvider(location.getProvider(),
                    currentBestLocation.getProvider());
    
            // Determine location quality using a combination of timeliness and accuracy
            // 确认位置的质量,通过"及时性和精度的结合"来判断
            if (isMoreAccurate) {
                return true;
            } else if (isNewer && !isLessAccurate) {
                return true;
            } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
                return true;
            }
            return false;
        }
    
        /** Checks whether two providers are the same */
        private boolean isSameProvider(String provider1, String provider2) {
            if (provider1 == null) {
              return provider2 == null;
            }
            return provider1.equals(provider2);
        }
    }

    3.布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <EditText
            android:id="@+id/editText"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:cursorVisible="false"
            android:editable="false" />
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
    
            <TextView
                android:id="@+id/tv_show_log"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" 
                android:text="显示log:
    "
                android:textSize="15sp"/>
        </ScrollView>
    
    </LinearLayout>
  • 相关阅读:
    Java实现 LeetCode 130 被围绕的区域
    Java实现 LeetCode 130 被围绕的区域
    Java实现 LeetCode 130 被围绕的区域
    win32创建控件的一些问题
    win32 sdk绘制ListBox控件
    VC++ WIN32 sdk实现按钮自绘详解 之二.
    win32 sdk 列表视图控件绘制
    win32 sdk树形控件的项拖拽实现
    MFC 用gdi绘制填充多边形区域
    vc 按钮自绘
  • 原文地址:https://www.cnblogs.com/H-BolinBlog/p/5415521.html
Copyright © 2011-2022 走看看