在对话框中启用 GPS 后 Android 位置返回 null

2024-01-09

当我进入屏幕时,我会检查 GPS 是否已打开,如果未打开,则会显示启用 GPS 的对话框。当用户单击“是”时,onActivityResult -> GPS 已打开,我尝试获取位置,但始终返回 null

当我在 GPS 已打开的情况下进入屏幕时,可以正确检索位置。我已经为此苦苦挣扎了几天,似乎找不到任何资源。

UserLocationUtilities.java

public class UserLocationUtilities implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener{

    GoogleApiClient googleApiClient;
    Activity activity;
    protected static final int REQUEST_CHECK_SETTINGS = 0x1;

    boolean isGPSEnabled = false;
    // flag for network status
    boolean isNetworkEnabled = false;
    // flag for GPS status
    boolean canGetLocation = false;

    protected LocationManager locationManager;
    protected LocationListener locationListener;
    protected Location location;
    protected double latitude,longitude;
    protected boolean gps_enabled,network_enabled;

    // The minimum distance to change Updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 1 * 1000 * 60; // 1 minute

    public UserLocationUtilities(Activity activity){
        this.activity = activity;
    }

    public void settingsRequest()
    {
        if(googleApiClient == null){
            googleApiClient = new GoogleApiClient.Builder(activity)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).build();
            googleApiClient.connect();
        }

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.

                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }
            }
        });
    }

    public Location getLocation() {
        if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            try {
                locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);

                isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

                if (!isGPSEnabled && !isNetworkEnabled) {
                    // no network provider is enabled
                } else {
                    this.canGetLocation = true;
                    if (isNetworkEnabled) {
                        locationManager.requestLocationUpdates(
                                LocationManager.NETWORK_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("Network", "Network");
                        if (locationManager != null) {
                            location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                    // if GPS Enabled get lat/long using GPS Services
                    if (isGPSEnabled) {
                        if (location == null) {
                            locationManager.requestLocationUpdates(
                                    LocationManager.GPS_PROVIDER,
                                    MIN_TIME_BW_UPDATES,
                                    MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                            Log.d("GPS Enabled", "GPS Enabled");
                            if (locationManager != null) {
                                location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                                if (location != null) {
                                    latitude = location.getLatitude();
                                    longitude = location.getLongitude();
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return location;
    }

    public boolean isLocationEnabled() {
        int locationMode = 0;
        String locationProviders;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            try {
                locationMode = Settings.Secure.getInt(activity.getApplicationContext().getContentResolver(), Settings.Secure.LOCATION_MODE);

            } catch (Settings.SettingNotFoundException e) {
                e.printStackTrace();
            }

            return locationMode != Settings.Secure.LOCATION_MODE_OFF;

        }else{
            locationProviders = Settings.Secure.getString(activity.getApplicationContext().getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
            return !TextUtils.isEmpty(locationProviders);
        }


    }

    @Override
    public void onConnected(Bundle bundle) {


    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

用户在“设置”对话框中选择“是”后,onActivityResult,我执行 location = userlocationutilities.getLocation();并且总是返回 null。如果切换屏幕并返回,则会检索位置。

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK: //location settings dialog, user selected YES to enabling location

                        location = userLocationUtilities.getLocation();
                        if(location != null){
                            //location of user FOUND
                            Toast.makeText(getActivity(), "Lat: "+location.getLatitude()+" Long: "+location.getLongitude(), Toast.LENGTH_LONG).show();
                            getRingsNearMeCall();

                        }else{
                            //location of user NOT FOUND
                            Toast.makeText(getActivity(), "null location", Toast.LENGTH_LONG).show();

                        }

                        break;
                    case Activity.RESULT_CANCELED: //location settings dialog, user selected NO to enabling location
                        userLocationUtilities.settingsRequest(); //ask user again with Location Settings Dialog
                        break;
                }
                break;
        }
    }

编辑:我在片段中发出 requestPermission,权限被授予

if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(getActivity(), new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION },
                    PERMISSION_ACCESS_FINE_LOCATION);
        }else{
            checkLocationSettingsGetRings();
        }

LocationSettingsRequest 只是用来进行足够的位置设置,例如您想要接收更准确(HIGH_ACCURACY)的位置,那么您需要启用 GPS。因此,在这种情况下,LocationSettingsRequest 会提示对话框允许 api 更改设置。

按确定后,您可以看到 GPS 已启用。但这并不意味着您已被授予位置请求权限。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_CHECK_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                // Here means required settings are adequate.
                // We can make location request.
                // But are we granted to use request location updates ?
                break;
            }
            break;
        }
    }
}

没关系,但是您正在检查权限,但您从未进行过请求权限。这是获取 null 的第一个可能原因。

public Location getLocation() {
    if (ContextCompat.checkSelfPermission(activity, 
        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        ...
    }
    return location;
}

Even您之前已获准提出位置请求

  location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
  location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

getLastKnownLocation() 方法可能返回 null,这不是意外行为。这是获取 null 的第二个可能原因

您正在发出位置请求,但全局位置变量从未在 onLocationChanged 回调中分配。

 @Override
public void onLocationChanged(Location location) {
    // global location variable is not assigned ?
    // getLocation() method will return null if getLastKnownLocation()
    // did not return null previously. 
}

这是返回 null 的第三个可能原因。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在对话框中启用 GPS 后 Android 位置返回 null 的相关文章

  • 迁移到 java 17 后有关“每个进程的内存映射”和 JVM 崩溃的 GC 警告

    我们正在将 java 8 应用程序迁移到 java 17 并将 GC 从G1GC to ZGC 我们的应用程序作为容器运行 这两个基础映像之间的唯一区别是 java 的版本 例如对于 java 17 版本 FROM ubuntu 20 04
  • 在具有相同属性名称的不同数据类型上使用 ModelMapper

    我有两节课说Animal AnimalDto我想用ModelMapper将 Entity 转换为 DTO 反之亦然 但是对于具有相似名称的一些属性 这些类应该具有不同的数据类型 我该如何实现这一目标 动物 java public class
  • ROOM迁移过程中如何处理索引信息

    CODE Entity tableName UserRepo indices Index value id unique true public class GitHubRepo PrimaryKey autoGenerate true p
  • MediaCodec 创建输入表面

    我想使用 MediaCodec 将 Surface 编码为 H 264 使用 API 18 有一种方法可以通过调用 createInputSurface 然后在该表面上绘图来对表面中的内容进行编码 我在 createInputSurface
  • 如何将文件透明地传输到浏览器?

    受控环境 IE8 IIS 7 ColdFusion 当从 IE 发出指向媒体文件 例如 mp3 mpeg 等 的 GET 请求时 浏览器将启动关联的应用程序 Window Media Player 我猜测 IIS 提供文件的方式允许应用程序
  • Android相机意图:如何获取全尺寸照片?

    我正在使用意图来启动相机 Intent cameraIntent new Intent android provider MediaStore ACTION IMAGE CAPTURE getParent startActivityForR
  • 检查 protobuf 消息 - 如何按名称获取字段值?

    我似乎无法找到一种方法来验证 protobuf 消息中字段的值 而无需显式调用其 getter 我看到周围的例子使用Descriptors FieldDescriptor实例到达消息映射内部 但它们要么基于迭代器 要么由字段号驱动 一旦我有
  • 使用 AWS Java SDK 为现有 S3 对象设置 Expires 标头

    我正在更新 Amazon S3 存储桶中的现有对象以设置一些元数据 我想设置 HTTPExpires每个对象的标头以更好地处理 HTTP 1 0 客户端 我们正在使用AWS Java SDK http aws amazon com sdkf
  • Java直接内存:在自定义类中使用sun.misc.Cleaner

    在 Java 中 NIO 直接缓冲区分配的内存通过以下方式释放 sun misc Cleaner实例 一些比对象终结更有效的特殊幻像引用 这种清洁器机制是否仅针对直接缓冲区子类硬编码在 JVM 中 或者是否也可以在自定义组件中使用清洁器 例
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • Windows 上的 Nifi 命令

    在我当前的项目中 我一直在Windows操作系统上使用apache nifi 我已经提取了nifi 0 7 0 bin zip文件输入C 现在 当我跑步时 bin run nifi bat as 管理员我在命令行上看到以下消息 但无法运行
  • SharedFlow 和 StateFlow 的主要区别

    两者有什么区别共享流 and 状态流 以及如何使用这些MVI建筑学 使用简单更好吗Flow或者这些作为状态和事件 Flow 是冷的 意味着它仅在收集数据时才发出数据 另外Flow不能保存数据 可以把它看成是水在里面流动的管道 Flow中的数
  • Java - 不要用 bufferedwriter 覆盖

    我有一个程序可以将人员添加到数组列表中 我想做的是将这些人也添加到文本文件中 但程序会覆盖第一行 因此这些人会被删除 如何告诉编译器在下一个空闲行写入 import java io import java util import javax
  • Springs 元素“beans”不能具有字符 [children],因为该类型的内容类型是仅元素

    我在 stackoverflow 中搜索了一些页面来解决这个问题 确实遵循了一些正确的答案 但不起作用 我是春天的新人 对不起 这是我的调度程序 servlet
  • 查看Jasper报告执行的SQL

    运行 Jasper 报表 其中 SQL 嵌入到报表文件 jrxml 中 时 是否可以看到执行的 SQL 理想情况下 我还想查看替换每个 P 占位符的值 Cheers Don JasperReports 使用 Jakarta Commons
  • java迭代器内部是如何工作的? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个员工列表 List
  • 无法运行我的应用程序,要求选择 Android SDK

    今天我已经安装了Android Studio 金丝雀 1 现在我无法运行我的应用程序 将出现以下对话框 我已经通过 文件 gt 项目结构 gt Android SDK 位置 设置了正确的 SDK 位置 期待您的帮助来解决这个问题 警告对话框
  • java8 Collectors.toMap() 限制?

    我正在尝试使用java8Collectors toMap on a Stream of ZipEntry 这可能不是最好的想法 因为在处理过程中可能会发生异常 但我想这应该是可能的 我现在收到一个我不明白的编译错误 我猜是类型推理引擎 这是
  • javax.persistence.Table.indexes()[Ljavax/persistence/Index 中的 NoSuchMethodError

    我有一个 Play Framework 应用程序 并且我was使用 Hibernate 4 2 5 Final 通过 Maven 依赖项管理器检索 我决定升级到 Hibernate 4 3 0 Final 成功重新编译我的应用程序并运行它
  • Jackson 将单个项目反序列化到列表中

    我正在尝试使用一项服务 该服务为我提供了一个带有数组字段的实体 id 23233 items name item 1 name item 2 但是 当数组包含单个项目时 将返回该项目本身 而不是包含一个元素的数组 id 43567 item

随机推荐

  • 使用 jquery 中的 click() 事件从表单更新 Highchart

    我有一个图表 每当提交同一页面上的表单时我都想更新该图表 这var chart new Highcharts Chart options 表达式本身可以正常工作 它绘制图表 当我将它放在回调函数中时 click 事件中 当我单击相应的提交按
  • 在Linux上的C中分配可执行RAM

    我想在 Linux 上用 c 制作一个简单的即时编译器 如何分配内存 以便向其中写入原始 x86 代码并像其他函数一样执行它 请参阅 mprotect 用代码填充 n 页大小的内存区域 使用 mmap 分配 后 更改其权限以禁止写入并允许执
  • SQL Server 和 C# 的输出不同

    我相信我的编码有问题 我猜它不是按日期过滤 请帮忙 SQL代码 SELECT CONVERT char 80 i InvDate 3 AS InvDate i InvoiceNo i EmployerCode i TaxAmount i S
  • 如何使用 Python 测试 Selenium 中的警报/弹出窗口

    我被自动化困住了 当我输入错误的用户名和密码时 它会弹出 无法登录 尝试不同的用户名 def test logonWrongUserName self self setUpClass Initialize the driver self s
  • 如何在 git 中自动生成版本字符串[重复]

    这个问题在这里已经有答案了 可能的重复 为 Git 存储库启用 ident 字符串 https stackoverflow com questions 1792838 enable ident string for git repos 在我
  • UIRefreshControl在UITableView iOS6的底部?

    是否可以添加UIRefreshControl在底部UITableView 我会用它来加载更多数据 请问 有什么建议吗 我相信这个问题不会有任何简单的解决方案 也许有人可以编写一个单独的库来实现此行为 而且一旦您在表视图中缓存数据 它会导致更
  • 设置对象 nil 与release+realloc

    这不是垃圾收集环境 我有一个类实例变量 在运行时的某个时刻 我需要使用与最初构造时不同的数据集重新初始化 假设地说 如果我有一个NSMutableArray or an NSMutableDictionary 做这样的事情会更有效率吗 my
  • 在 MVC 应用程序中使用 ELMAH 调试/跟踪消息

    我们如何在 MVC 应用程序中使用 ELMAH 添加调试 跟踪消息 ELMAH 通常用于报告异常 而不是作为一般的调试 跟踪日志 对于调试 跟踪日志记录 我建议结合使用log4net https stackoverflow com ques
  • 在 Redhat 5 上运行 JavaFX 应用程序

    From my 上一个问题 https stackoverflow com questions 24420651 javafx helloworld jar cannot be ran on different platform 我知道Re
  • Azure 服务总线空闲时自动删除

    我试图找出设置 AutoDeleteOnIdle 时的正确行为 我有一个名为 MyGameMessages 的主题 不透露游戏名称 因为它可能被视为广告 我所做的是在服务器场中的每个节点上创建一个订阅 var manager GetName
  • 活动模型序列化器:nil:NilClass 的未定义方法“url_for”

    我在用着active model serializersgem 在我的应用程序中发送高级 json 响应 它实际上工作正常 但由于我安装了该 gem 使用几分钟后 应用程序崩溃 显示上面的错误 不确定我的代码是否与之相关 但不知何故 我也需
  • 如何使用Java测量网络响应时间?

    我们有一个客户端和一个服务器 我想测量它们之间网络的响应时间 当我向服务器发送请求时 它应该立即响应我的请求 它应该像 ping 请求一样 以便服务器不会有处理时间 我怎样才能在Java中做到这一点 我通过从客户端向服务器发送带有时间戳的数
  • 控制文件下载

    我正在使用 TWebBrowser 为我的程序构建一个更新程序 OnCreate 时 TWebBrowser 导航到给定的 URL 要下载更新 用户需要单击链接 单击链接时会出现此弹出窗口 所以我想知道是否可以 绕过该弹出窗口并允许自动下载
  • JQueryMobile 自动完成点击条目不更改输入值

    我尝试使用 jquery mobile 进行自动完成输入 所以我在这里找到了一个演示 http demos jquerymobile com 1 4 0 listview autocomplete remote http demos jqu
  • Java静态导入导致编译错误。可能是编译器错误?

    这在 Eclipse JDT 中可以正常编译 但在 1 6 30 或 1 7 25 上则不行 package doh import static doh Wtf InnerClass innerclassMethod import java
  • SQL Server 级联

    我正在制作一个网站 用户可以在其中发布 帖子 然后用户可以对这些帖子进行 评论 我有一个包含 3 个表的数据库 一项包含用户信息 一项包含帖子信息 最后一项包含评论信息 我想设置规则 以便如果用户被删除 他们的所有帖子和评论都会被删除 如果
  • Vue 使用 select、v-for 和 v-model 预选值

    我在用着select with v model并有选项v for和对象作为值 选项是一些由id标识的元素 如何根据自定义相等性预先选择选项 在本例中为相等 id场地 我正在寻找类似于 angularjs 的东西track by from n
  • 在多级继承中从子类调用“大”父函数[重复]

    这个问题在这里已经有答案了 public class GrandParent public void walk public class Parent public void walk public class Child public v
  • JavaFX 中的样式文本?

    我正在将聊天客户端从 Swing 切换到 JavaFX 但遇到了图形问题 以前 我使用的是JTextPane插入样式文本 但切换到 FX 后 我找不到能够执行所需操作的单个组件JTextPane做了 并且从this https stacko
  • 在对话框中启用 GPS 后 Android 位置返回 null

    当我进入屏幕时 我会检查 GPS 是否已打开 如果未打开 则会显示启用 GPS 的对话框 当用户单击 是 时 onActivityResult gt GPS 已打开 我尝试获取位置 但始终返回 null 当我在 GPS 已打开的情况下进入屏