android IOS 定位解决方案

需求是一个简单的社交系统,定位下大概城市信息即可

客户端unity,最早想法用unity的API可以获取GPS信号,获得经纬度通过百度,高德数据库来确认位置,但是GPS耗电快,用户会有抵触心理,反正我看到打开个应用GPS定位在那里闪我就不想用这个APP了,所以决定用适配系统来处理 android ios,

定位有几个途径

1,GPS 耗电块,只能室内信号不有遮挡的地方,有点就是准确率高。

2,基站,安卓有电话卡的机器可以获取到附近营运商的基站信息,基站信息有当前基站的经纬度,就可以获取到当前大概位置。

3,网络定位,WIFI定位,

IOS 解决方案 https://blog.csdn.net/qq_18709863/article/details/84573686 请跳转

android解决方法

首先要解决权限问题,动态申请定位权限,我使用的https://github.com/getActivity/XXPermissions 这个库很好用

下面是android java代码 

package com.example.location_test;

import java.util.List;

import android.app.Activity;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.hjq.permissions.OnPermission;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;


public class MainActivity extends Activity implements View.OnClickListener{
    protected LocationManager  locationManager;
    protected Location mlocation;
    TextView gpstext;
    Button btn1;//定位
    Button btn2;//获取权限;
    private LocationUtils locationUtil;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gpstext=(TextView) findViewById(R.id.info);
        btn1= (Button) findViewById(R.id.button1);
        btn2= (Button) findViewById(R.id.button2);
		btn1.setOnClickListener(this);
		btn2.setOnClickListener(this);

		
        locationUtil = LocationUtils.getInstance(this);
        locationUtil.text=gpstext;
    }
    @Override
    public void onClick(View v) {
    	switch (v.getId()){
        		case R.id.button1:
    				Toast.makeText(MainActivity.this,"Button点击事件1",Toast.LENGTH_LONG).show();
    				locationUtil.getLocation();
            	break;
        		case R.id.button2:
        			XXPermissions.with(this).permission(Permission.Group.LOCATION)
        			   .request(new OnPermission() {

	                    @Override
	                    public void hasPermission(List<String> granted, boolean isAll) {
	                        if (isAll) {
	                            Toast.makeText(MainActivity.this, "获取权限成功", Toast.LENGTH_SHORT).show();
	                        }else {
	                            Toast.makeText(MainActivity.this, "获取权限成功,部分权限未正常授予", Toast.LENGTH_SHORT).show();
	                        }
	                    }

	                    @Override
	                    public void noPermission(List<String> denied, boolean quick) {
	                        if(quick) {
	                            Toast.makeText(MainActivity.this, "被永久拒绝授权,请手动授予权限", Toast.LENGTH_SHORT).show();
	                            //如果是被永久拒绝就跳转到应用权限系统设置页面
	                            XXPermissions.gotoPermissionSettings(MainActivity.this);
	                        }else {
	                            Toast.makeText(MainActivity.this, "获取权限失败", Toast.LENGTH_SHORT).show();
	                        }
	                    }
	                });
    				Toast.makeText(MainActivity.this,"Button点击事件2",Toast.LENGTH_LONG).show();
        			break;
    	}
    
    }
    protected void onDestroy() {
        super.onDestroy();

        locationUtil.removeLocationUpdatesListener();
    }

	    public void gotoPermissionSettings(View view) {
	        XXPermissions.gotoPermissionSettings(MainActivity.this);
	    }
}
package com.example.location_test;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import com.hjq.permissions.OnPermission;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;

/*
* 注意
* 1、Android6.0动态权限, 
* 2、Geocoder获取地理位置信息是一个后台的耗时操作,
* 为了不阻塞主线程,强力建议在使用Geocoder获取地理位置信息时采用异步线程的方式来请求服务,这样不会造成主线程的阻塞。
* */
public class LocationUtils {

    private volatile static LocationUtils uniqueInstance;
    private LocationManager locationManager;
    private Activity mContext;
    public TextView text;
    private LocationUtils(Activity context) {
        mContext = context;
    }

    //采用Double CheckLock(DCL)实现单例
    public static LocationUtils getInstance(Activity context) {
        if (uniqueInstance == null) {
            synchronized (LocationUtils.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new LocationUtils(context);
                }
            }
        }
        return uniqueInstance;
    }

    public void getLocation() {
        //1.获取位置管理器
        locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);

        //2.获取位置提供器,GPS或是NetWork
        // 获取所有可用的位置提供器
        List<String> providerList = locationManager.getProviders(true);
        String locationProvider;
      if (providerList.contains(LocationManager.NETWORK_PROVIDER)) {//Google服务被墙不可用
            //网络定位的精准度稍差,但耗电量比较少。
            System.out.println("=====NETWORK_PROVIDER====");
            locationProvider = LocationManager.NETWORK_PROVIDER;

      }  
            else  if (providerList.contains(LocationManager.GPS_PROVIDER)) {
                //GPS 定位的精准度比较高,但是非常耗电。
                System.out.println("=====GPS_PROVIDER=====");
                locationProvider = LocationManager.GPS_PROVIDER;
        } else {
            System.out.println("=====NO_PROVIDER=====");
            // 当没有可用的位置提供器时,弹出Toast提示用户
            Toast.makeText(mContext, "No location provider to use", Toast.LENGTH_SHORT).show();
   			XXPermissions.with(mContext).permission(Permission.Group.LOCATION)
			   .request(new OnPermission() {
             @Override
             public void hasPermission(List<String> granted, boolean isAll) {
                 if (isAll) {
                     Toast.makeText(mContext, "获取权限成功", Toast.LENGTH_SHORT).show();
                     getLocation();
                 }else {
                     Toast.makeText(mContext, "获取权限成功,部分权限未正常授予", Toast.LENGTH_SHORT).show();
                 }
             }

             @Override
             public void noPermission(List<String> denied, boolean quick) {
                 if(quick) {
                     Toast.makeText(mContext, "被永久拒绝授权,请手动授予权限", Toast.LENGTH_SHORT).show();
                     //如果是被永久拒绝就跳转到应用权限系统设置页面
                     XXPermissions.gotoPermissionSettings(mContext);
                 }else {
                     Toast.makeText(mContext, "获取权限失败", Toast.LENGTH_SHORT).show();
                 }
             }
         });
//            Intent intent = new Intent();
//            intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
//            mContext.startActivity(intent);
            return;
        }

        //3.获取上次的位置,一般第一次运行,此值为null
        Location location = locationManager.getLastKnownLocation(locationProvider);
        if (location != null) {
            // 显示当前设备的位置信息
            System.out.println("==显示当前设备的位置信息==");
            showLocation(location);
        } else {//当GPS信号弱没获取到位置的时候可从网络获取
            System.out.println("==Google服务被墙的解决办法==");
            getLngAndLatWithNetwork();//Google服务被墙的解决办法
        }
        // 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
        //LocationManager 每隔 5 秒钟会检测一下位置的变化情况,当移动距离超过 10 米的时候,
        // 就会调用 LocationListener 的 onLocationChanged() 方法,并把新的位置信息作为参数传入。
        locationManager.requestLocationUpdates(locationProvider, 5000, 10, locationListener);
    }

    //获取经纬度
    private void showLocation(Location location) {
        double latitude = location.getLatitude();//纬度
        double longitude = location.getLongitude();//经度
        getAddress(latitude, longitude);
    }

    private void getAddress(double latitude, double longitude) {
        //Geocoder通过经纬度获取具体信息
        Geocoder gc = new Geocoder(mContext, Locale.getDefault());
        try {
            List<Address> locationList = gc.getFromLocation(latitude, longitude, 1);

            if (locationList != null) {
                Address address = locationList.get(0);

                String countryName = address.getCountryName();//国家
                String countryCode = address.getCountryCode();
                String adminArea = address.getAdminArea();//省
                String locality = address.getLocality();//市
                String subAdminArea = address.getSubAdminArea();//区
                String featureName = address.getFeatureName();//街道
                StringBuilder sb=new StringBuilder();
                for (int i = 0; address.getAddressLine(i) != null; i++) {
                    String addressLine = address.getAddressLine(i);
                    //街道名称:广东省深圳市罗湖区蔡屋围一街深圳瑞吉酒店
                    System.out.println("addressLine=====" + addressLine);
                    sb.append(addressLine).append(":");
                }

                String currentPosition = "latitude is " + latitude//22.545975
                        + "\n" + "longitude is " + longitude//114.101232
                        + "\n" + "countryName is " + countryName//null
                        + "\n" + "countryCode is " + countryCode//CN
                        + "\n" + "adminArea is " + adminArea//广东省
                        + "\n" + "locality is " + locality//深圳市
                        + "\n" + "subAdminArea is " + subAdminArea//null
                        + "\n" + "featureName is " + featureName;//蔡屋围一街深圳瑞吉酒店

                System.out.println(currentPosition);
                text.setText(address.toString()+"@@@"+sb+"@@@"+currentPosition);                //text.setText(sb+currentPosition);
                Log.e("location test", currentPosition);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void removeLocationUpdatesListener() {
        if (locationManager != null) {
            uniqueInstance = null;
            locationManager.removeUpdates(locationListener);
        }
    }


    private LocationListener locationListener = new LocationListener() {
        // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
        @Override
        public void onStatusChanged(String provider, int status, Bundle arg2) {
        }

        // Provider被enable时触发此函数,比如GPS被打开
        @Override
        public void onProviderEnabled(String provider) {
        }

        // Provider被disable时触发此函数,比如GPS被关闭
        @Override
        public void onProviderDisabled(String provider) {
        }

        //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
        @Override
        public void onLocationChanged(Location location) {
            System.out.println("==onLocationChanged==");
            showLocation(location);
        }
    };

    //从网络获取经纬度
    private void getLngAndLatWithNetwork() {
        LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10, locationListener);
        Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        showLocation(location);
    }
}

欢迎大家加入移动前端学习群 讨论 339033019

猜你喜欢

转载自blog.csdn.net/qq_18709863/article/details/84329669