Android获取定位权限,获取设备所在的经纬度
转载请标明出处:http://www.cnblogs.com/tangZH/p/8969898.html
更多文章:http://77blogs.com/?p=253
前言:
有时候我们仅仅是想要获取设备所在的经纬度,那么直接调用Android相关的api就可以了,不需要去接入高德地图或者谷歌地图等等。
一、获取定位服务
private LocationManager locationManager;
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
二、获取所有可用的位置提供器
//获取所有可用的位置提供器
List<String> providers = locationManager.getProviders(true);
三、判断可用的位置提供器类型,是网络定位,还是GPS定位,若是都没有,那么就跳转至设置界面,提示打开网络和GPS定位服务
这里说一下两种定位的区别:
通过GPS定位,较精确,也比较耗电,而网络定位精度不高,省电。
String locationProvider = null;
if (providers.contains(LocationManager.GPS_PROVIDER)) {
//如果是GPS
locationProvider = LocationManager.GPS_PROVIDER;
} else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
//如果是Network
locationProvider = LocationManager.NETWORK_PROVIDER;
} else {
Intent i = new Intent();
i.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(i);
return null;
}
四、获取Location
//获取Location
Location location = locationManager.getLastKnownLocation(locationProvider);
五、监视地理位置变化
这里设置3秒监听一次
//监视地理位置变化
locationManager.requestLocationUpdates(locationProvider, 3000, 1, locationListener);
六、实现地理位置变化接口
public LocationListener locationListener = new LocationListener() { // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
@Override
public void onStatusChanged(String provider, int status, Bundle extras) { } // 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) {
}
};
注意:
要在文件清单里面写上
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
我为此写了个工具类。
package com.example.chatting.chatting.utils; import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings; import java.util.List; /**
* Created by Administrator on 2018/4/17.
* 获取用户的地理位置
*/
public class GPSUtils { private static GPSUtils instance;
private Context mContext;
private LocationManager locationManager; private GPSUtils(Context context) {
this.mContext = context;
} public static GPSUtils getInstance(Context context) {
if (instance == null) {
instance = new GPSUtils(context);
}
return instance;
} /**
* 获取经纬度
*
* @return
*/
public String getLngAndLat(OnLocationResultListener onLocationResultListener) {
double latitude = 0.0;
double longitude = 0.0; mOnLocationListener = onLocationResultListener; String locationProvider = null;
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
//获取所有可用的位置提供器
List<String> providers = locationManager.getProviders(true); if (providers.contains(LocationManager.GPS_PROVIDER)) {
//如果是GPS
locationProvider = LocationManager.GPS_PROVIDER;
} else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
//如果是Network
locationProvider = LocationManager.NETWORK_PROVIDER;
} else {
Intent i = new Intent();
i.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(i);
return null;
} //获取Location
Location location = locationManager.getLastKnownLocation(locationProvider);
if (location != null) {
//不为空,显示地理位置经纬度
if (mOnLocationListener != null) {
mOnLocationListener.onLocationResult(location);
} }
//监视地理位置变化
locationManager.requestLocationUpdates(locationProvider, , , locationListener);
return null;
} public LocationListener locationListener = new LocationListener() { // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
@Override
public void onStatusChanged(String provider, int status, Bundle extras) { } // 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) {
if (mOnLocationListener != null) {
mOnLocationListener.OnLocationChange(location);
}
}
}; public void removeListener() {
locationManager.removeUpdates(locationListener);
} private OnLocationResultListener mOnLocationListener; public interface OnLocationResultListener {
void onLocationResult(Location location); void OnLocationChange(Location location);
}
}
这里边涉及到了另一个问题,获取权限
对于6.0以下的权限及在安装的时候,根据权限声明产生一个权限列表,用户只有在同意之后才能完成app的安装,造成了我们想要使用某个app,就要默默忍受其一些不必要的权限(比如是个app都要访问通讯录、短信等)。而在6.0以后,我们可以直接安装,当app需要我们授予不恰当的权限的时候,我们可以予以拒绝。当然你也可以在设置界面对每个app的权限进行查看,以及对单个权限进行授权或者解除授权。
新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。
对于Dangerous Permission,我们需要动态获取权限,那么我们怎么动态定位权限呢?
在activity中(其实我们可以把权限的获取写在一个BaseActivity中)我们可以这么做:
1、判断版本,如果6.0以下,那么便不需要获取权限。
/**
* 是否应该检查权限
* @return
*/
public boolean showCheckPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return true;
} else {
return false;
}
}
2、若是6.0以及以上的话,那么便去判断是否已经授权,若是没有授权,那么便会去申请授权。若是已经授权,那么便直接执行我们的操作。
(判断之后若是没有授权,会弹出系统对话框询问是否同意授权,该对话框不可定制。)
//获取权限(如果没有开启权限,会弹出对话框,询问是否开启权限)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//请求权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_CODE);
} else { }
3、授权回调。询问是否同意授权的时候,系统会弹出对话框,我们选择之后,会进行回调。在回调里面进行判断。
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case LOCATION_CODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
// 权限被用户同意。
// 执形我们想要的操作
} else { }
}
}
}
若是同意了,那么便可以直接执形我们的操作,若是不同意,那么下次依旧会弹出询问的对话框。不过这个对话框与之前比起来多了一个选项,那就是“不再提醒”(第一次询问没有这个选项)。这就难办了,若是点击了不再提醒,那么以后就不会再弹出对话框了,唉,那我们怎么判断呢?
Google给我们提供了一个方法:
ActivityCompat.shouldShowRequestPermissionRationale
该方法主要是为了给用户提供解释。
这个方法,在没弄明白之前,也是挺烦人。弄明白之后就好办了,那么,我们需要弄明白它的返回值。
(1)、当用户第一次被询问是否授权的时候,该方法返回值为false
(2)、若是用户上一次拒绝授权,但是没有点击“不再提醒“”的时候,这一次返回true。(我们可以根据这个判断,在这一次给用户一个解释,解释为什么该app需要该权限)
(3)、当用户上一次拒绝授权,并且点击了“不再提醒”的时候,那么返回false。
(4)、当用户在设置界面手动关闭了该APP的权限,那么也返回false。
那么,就出现了一个问题,这么多种情况都返回false,那么我们要怎么判断是哪一种情况呢?
比如第一与第三种情况。
若是我们在进行权限判断之前调用这个方法:
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)
|| !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
.....
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
若是返回true,说明是第二种情况,需要给用户一个解释(我们可以给出一个对话框,点击确定后再执形检测权限的操作,即下面的的操作)。
若是返回false,那么到底是第一还是第三种情况。我们无法判断。这里我给出一种方法:在授权回调里面去检测,如下。
else可以说明已经拒绝授权。
然后调用shouldShowRequestPermissionRationale方法,若是返回false,说明
1、点击了“不再提醒”。
2、该app本身没有权限,被关闭。
那么我们就可以提醒用户去设置界面手动开启权限。
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case LOCATION_CODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
// 权限被用户同意。
// 执形我们想要的操作
} else {
// 权限被用户拒绝了。
//若是点击了拒绝和不再提醒
//关于shouldShowRequestPermissionRationale
// 1、当用户第一次被询问是否同意授权的时候,返回false
// 2、当之前用户被询问是否授权,点击了false,并且点击了不在询问(第一次询问不会出现“不再询问”的选项),
// 之后便会返回false
// 3、当用户被关闭了app的权限,该app不允许授权的时候,返回false
// 4、当用户上一次不同意授权,没有点击“不再询问”的时候,下一次返回true
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)
|| !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
//提示用户前往设置界面自己打开权限
Toast.makeText(this, "请前往设置界面打开权限", Toast.LENGTH_SHORT).show();
return;
} }
}
}
}
Android获取定位权限,获取设备所在的经纬度的更多相关文章
- android开发,权限获取
转:http://blog.csdn.net/yawinstake/article/details/6748897 访问登记属性 android.permission.ACCESS_CHECKIN_P ...
- android基站定位程序获取地理位置
目录 一.设置界面 二.为按钮绑定事件 三.获取基站信息 四.获取经纬度 五.获取物理位置 六.显示结果 七.运行程序 八.总结 九.程序代码 正文 在Android操作系统下,基站定位其实很简单,先 ...
- android开发的权限获取 (转载的)
访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...
- Android M 动态权限获取
新的权限获取方式除了要求像之前版本号一样在AndroidManifest文件里静态申请之外,应用还需依据须要请求权限,方式採用向用户显示一个请求权限的对话框. 这些被动态申请的权限能够在系统设置中被手 ...
- 标准基座获取定位可以获取address城市,自定义基座获取不到address
正常的返回应该 { "type": "WGS84", "altitude": 0, "latitude": 31.830 ...
- Android应用请求获取Root权限
应用获取Root权限的原理:让应用的代码执行目录获取最高权限.在Linux中通过chmod 777 [代码执行目录] /** * 应用程序运行命令获取 Root权限,设备必须已破解(获得ROOT权限) ...
- Android -- 程序判断手机ROOT状态,获取ROOT权限
判断手机是否具有ROOT权限 /** * 判断手机是否ROOT */ public ...
- android6.0获取通讯录权限
android6.0中,获取通讯录的权限是 <uses-permission android:name="android.permission.GET_ACCOUNTS" ...
- 软件申请获取root权限
申请root的工具类 //获取root权限 RootManager manager=new RootManager(); manager.upgradeRootPermission(getPack ...
随机推荐
- 消息队列RabbitMq、ActiveMq、ZeroMq、kafka之间的比较
MQ框架非常之多,比较流行的有RabbitMq.ActiveMq.ZeroMq.kafka.这几种MQ到底应该选择哪个?要根据自己项目的业务场景和需求.下面我列出这些MQ之间的对比数据和资料. 第一部 ...
- [Swift]LeetCode102. 二叉树的层次遍历 | Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- 别再说Python没有枚举类型了,好好看看
枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. Python 的原生类型(Built-in types)里并没有专门的枚举类型,但是我们可以通 ...
- python3安装sklearn机器学习库
安装sklearn需要的库请全部在万能仓库下载: http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy http://www.lfd.uci.edu/~go ...
- hadoop分布式搭建
1.新建三台机器,分别为: hadoop分布式搭建至少需要三台机器: master extension1 extension2 本文利用在VMware Workstation下安装Linux cent ...
- 【Docker】(4)搭建私有镜像仓库
[Docker](4)搭建私有镜像仓库 说明 1. 这里是通过阿里云,搭建Docker私有镜像仓库. 2. 这里打包的镜像是从官网拉下来的,并不是自己项目创建的新镜像,主要测试功能 一.搭建过程 首先 ...
- java多线程(6)---ThreadLocal
ThreadLocal 什么是ThreadLocal? 顾名思义它是local variable(线程局部变量).它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可 ...
- 『追捕盗贼 Tarjan算法』
追捕盗贼(COCI2007) Description 为了帮助警察抓住在逃的罪犯,你发明了一个新的计算机系统.警察控制的区域有N个城市,城市之间有E条双向边连接,城市编号为1到N. 警察经常想在罪犯从 ...
- 什么样的IT业务适合外包?
很多公司都应该遇到过这样的问题,什么样的IT业务才适合外包呢? 百度大家都可以百度的到一些信息,比如: 针对这样的推荐答案,是否也需要认真思考一下,我需要外包的业务是什么样的业务?是不是真的适合外包? ...
- 关于ML.NET v0.7的发布说明
我们很高兴宣布推出ML.NET 0.7--面向.NET开发人员的最新版本的跨平台和开源机器学习框架(ML.NET 0.1发布于// Build 2018).此版本侧重于为基于推荐的ML任务提供更好的支 ...