关于安卓无线定位与定位算法的讨论

来源:互联网 发布:python写入excel 编辑:程序博客网 时间:2024/05/13 21:56

对于手机开发者来说,网络的使用就尤为重要了,在使用网络之前就得做网络的判断,判断当前手机使用的网络是无线网络还是移动网络,告知用户,以免造成一些不必要的麻烦.

1.对网络连接的判断

要对网络进行判断,首先要获取手机系统权限,再运用安卓sdk中的NetworkInfo去获得当前网络,从而获得当前网络连接类型,由于程序在运行中可能会遇到的多种断开网络的情况,所以,在这里就要注册一个广播实时监听网络的链接状态.这个网络监听的作用就是只要程序发生的网络连接的变化,网络监听都可以捕捉到(包括连接wifi,连接移动网络,断开wifi,断开移动网络),由此可见网络监听的重要性

下面来看一段代码:

/**
 * 网络监听
 * @author WYH
 *
 */
public class ConnectionChangeRecevier extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //获取系统权限
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            @SuppressWarnings("deprecation")
            //通过权限获取当前网络状态
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) { //info!= null表示当前有网络连接
                for (int i = 0; i < info.length; i++) {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) { //表示网络连接成功
                        switch (info[i].getType()) { //对连接网络的类型判断
                        case ConnectivityManager.TYPE_WIFI://如果当前连接的是wifi
                            ToastXutil.show("当前是wifi连接"+"--"+info[i].getTypeName());
                            break;
                        case ConnectivityManager.TYPE_MOBILE://如果当前连接的是移动网络
                            ToastXutil.show("当前是移动网络连接"+"--"+info[i].getTypeName());
                            break;
                        default://默认连接其他未知网络
                            ToastXutil.show("未知网络连接");    
                            break;
                        }
                    }
                }
            }
        }
        if (!MainActivity.isNetworkAvailable(context)) {//如果当前没有网络连接
            ToastXutil.show("网断了!");
        }
    }

}

对于编写这个网络监听的广播,上面的注释已经写得很清楚了,考虑到这个广播作为实时监听网络情况,所以在清单文件中使用静态注册的方法:

 <!-- 断网监听 -->
        <receiver
            android:name="com.example.wifitest.ConnectionChangeRecevier"
            android:label="NetworkConnection" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>

另外再附上几个判断网络的算法:

// 检测网络连接
        /** 检查是否有网络 */
        public static boolean isNetworkAvailable(Context context) {
            NetworkInfo info = getNetworkInfo(context);
            if (info != null) {
                return info.isAvailable();
            }
            return false;
        }

        /** 检查是否是WIFI */
        public static boolean isWifi(Context context) {
            NetworkInfo info = getNetworkInfo(context);
            if (info != null) {
                if (info.getType() == ConnectivityManager.TYPE_WIFI)
                    return true;
            }
            return false;
        }

        /** 检查是否是移动网络 */
        public static boolean isMobile(Context context) {
            NetworkInfo info = getNetworkInfo(context);
            if (info != null) {
                if (info.getType() == ConnectivityManager.TYPE_MOBILE)
                    return true;
            }
            return false;
        }
        private static NetworkInfo getNetworkInfo(Context context) {

            ConnectivityManager cm = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            return cm.getActiveNetworkInfo();
        }

最后看下真机运行测试的效果:测试顺序(wifi,移动网络打开----关闭wifi----关闭移动网络----打开移动网络----打开wifi)


首先启动程序


当前wifi和移动网络是正常的


当把wifi关了的瞬间,网络监听广播监听到网络发生变化而且当前网络断开了,就会弹出网断了!提示


在wifi关闭之后程序检测到移动网络还是可用的,接着就会连上移动网络,当连接成功后,网络监听判断到网络连接正常的同时,获取连接网络的类型是否wifi还是移动网络,弹出连接移动网的数据.


当把wifi和移动网络同时关闭,这是网络监听知道当前程序没用网络连接,所以弹出一个网断了的提示.


把移动网络打开,网络监听重新获取到连接的网络并获取连接的网络类型,再弹出提示


打开移动网络的同时再把wifi打开,这是由于wifi的优先级别比移动网络的高,所以此时的网络又会发生变化,只要发生网络变化,网络监听就会捕捉,自然而然会提示是当前是wifi连接.

总结:基于安卓无线和移动网络的API和一些算法,手机程序可判断当前网络连接类型,从而进行一些功能操作,或者强制性基于无线网络下的操作,因为程序已自动识别网络连接状态.

2.基于安卓GPS定位与算法

由于程序某些功能需求,对于实时位置的坐标信息也是必不可少的,如果嫌集成高德地图百度地图麻烦,不妨试一下安卓自带的GPS定位功能

要使用GPS,首先要判断手机是否打开GPS,因为很多用户不习惯长时间打开GPS,如果GPS没打开,定位信息自然获取不了,所以,先写一个判断的方法:

private boolean checkGPS(){    //判断GPS是否正常启动    boolean isOn = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);    if (isOn){//如果打开则不操作        return true;    }else {//如果没有打开则手动打开GPS        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);        startActivityForResult(intent,0);        return false;    }}(这时,也可以对GPS进行监听,防止在定位的过程中被关闭而造成定位的失败)
/** * GPS状态变化时触发 */@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}/** * GPS开启时触发 */@Overridepublic void onProviderEnabled(String provider) {}/** * GPS禁用时触发 */@Overridepublic void onProviderDisabled(String provider) {}这三个方法是重写LocationListener接口的方法

获取位置信息的方法:

/** * 获取位置信息 * @return */private Location getLocation(){    //获取位置管理服务
    locationManager = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);    //查找服务信息
Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); //定位精度: 最高 criteria.setAltitudeRequired(false); //海拔信息:不需要 criteria.setBearingRequired(false); //方位信息: 不需要 criteria.setCostAllowed(false); //是否允许付费 criteria.setPowerRequirement(Criteria.POWER_LOW); //耗电量: 低功耗 String provider = locationManager.getBestProvider(criteria, true); //获取GPS信息 Location location = null; try{ location = locationManager.getLastKnownLocation(provider); locationManager.requestLocationUpdates(provider, 2000, 5, this); }catch (Exception e){ ToastXutil.show("手机缺少用户权限"); } return location;}
接着就是接收位置信息:
/** * 位置信息变化时触发 */@Overridepublic void onLocationChanged(Location location) {    if(location != null) {        lat = location.getLatitude();        lng = location.getLongitude();        ToastXutil.show("纬度:"+lat+",经度:"+lng);    }else {
       //获取位置信息失败
}}
这方法同样来源于LocationListener接口
注意:所获取的坐标(lat,lng)是谷歌地图坐标,与百度,高德,腾讯地图坐标有实际差距
附上转换高德地图的坐标方法:
/** * 根据类型 转换 坐标 */public static LatLng convert(LatLng sourceLatLng, Context context) {    CoordinateConverter converter  = new CoordinateConverter(context);    // CoordType.GPS 待转换坐标类型    converter.from(CoordinateConverter.CoordType.valueOf("GPS"));    // sourceLatLng待转换坐标点    converter.coord(sourceLatLng);    // 执行转换操作    LatLng desLatLng = converter.convert();    return desLatLng;}最后看下真机运行的截图:
无线情况下和移动网络情况下都没有问题.附加内容:说明:基于高德定位API的无线定位和移动网络定位这就是我自己摸索的一点技术,我希望可以跟更多的人去分享,在编写博客过程中有任何不足的地方,希望多多指教,下次我会做得更好的,谢谢!


原创粉丝点击