当前位置: 首页 > 知识库问答 >
问题:

网络提供商和GPS提供商合作时,需要根据可用的提供商将两者分开

洪弘壮
2023-03-14

我正在尝试开发一个android应用程序,该应用程序使用GPS或网络提供商获取设备纬度和经度,以该过程可用的为准。当设备的GPS打开时,代码工作得非常好,但不幸的是,当设备的GPS关闭时,它永远不会工作。

例如,我想根据可用的提供商获取设备的纬度和经度;如果设备的GPS打开,它应该使用GPS提供商获取设备的纬度和经度,如果GPS关闭,它应该使用网络提供商获取设备的纬度和经度。在我的情况下,网络提供商总是返回false,并且只有在设备的GPS打开时才有效,因为它不应该为设备GPS打开或关闭而烦恼,它应该根据网络提供商简单地获取纬度和经度。

我使用了谷歌提供的融合API,但即使这样也有同样的问题,我只能使用GPS提供商获取纬度和经度,当我关闭设备的GPS时,它也不会使用网络提供商返回所需的纬度和经度,因为当设备的GPS关闭时,网络提供商和GPS提供商都会返回false。

GPS和网络供应商都在开发设备的GPS,我想分别介绍他们的流程。

我正在使用以下权限和功能

<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" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.LOCATION_HARDWARE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-feature android:name="android.hardware.location" android:required="true"/>
<uses-feature android:name="android.hardware.location.network" android:required="true"/>
<uses-feature android:name="android.hardware.location.gps" android:required="true"/>

以下是我的完整Java代码,它只在设备的GPS处于打开状态时工作,无论是在GPS还是网络情况下。

package com.example.administrator.locationgetter;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends Activity {
    public static final int MY_PERMISSIONS_REQUEST = 0;

    LocationManager locationManager;

    private LocationListener mLocationListener;


    private void showStatus(String st)
    {
        Toast.makeText(MainActivity.this,st,Toast.LENGTH_SHORT).show();
    }
    private LocationListener createLocationListener() {
        return new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                // Called when a new location is found by the network location provider.
                Toast.makeText(MainActivity.this,"accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude(),Toast.LENGTH_SHORT).show();
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
                showStatus(provider + " -- " + status);
            }

            public void onProviderEnabled(String provider) {
                showStatus(provider + " -- " + "ENABLED!");
            }

            public void onProviderDisabled(String provider) {
                showStatus(provider + " -- " + "DISABLED!");
            }


        };
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        //setSupportActionBar(toolbar);

        mLocationListener = createLocationListener();
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener);

                } else {
                    Toast.makeText(MainActivity.this, "So sad! Give me the damn permissions!", Toast.LENGTH_SHORT).show();

                }
                return;
            }
        }
    }

    public void btnLocation(View v) {

        if ((ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )){
            showStatus("Give me the permissions man!");
            ActivityCompat.requestPermissions(this,
                    new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST);
        }
        else
        {
            showStatus("Already have permission");
            locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
            String locationProvider = LocationManager.NETWORK_PROVIDER;
            Location location = locationManager.getLastKnownLocation(locationProvider);
            if(location != null)
            {
                Toast.makeText(MainActivity.this,"accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude(),Toast.LENGTH_SHORT).show();
            }
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener);

        }
    }
    public void btnLocation1(View v) {

        if ((ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED )){
            showStatus("Give me the permissions man!");
            ActivityCompat.requestPermissions(this,
                    new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST);
        }
        else
        {
            showStatus("Already have permission");
            locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
            String locationProvider = LocationManager.GPS_PROVIDER;
            Location location = locationManager.getLastKnownLocation(locationProvider);
            if(location != null)
            {
                Toast.makeText(MainActivity.this,"accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude(),Toast.LENGTH_SHORT).show();
            }
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);

        }
    }
}

我在KitKat、Lollipop和Marshmallow上测试了这个应用程序,所有的结果都是一样的。

[更新]如果你下载百度地图并启动应用程序,它会要求你授予位置访问权限,只需确保你的位置已关闭,只需向百度地图授予位置权限,你就会注意到,即使你的GPS或位置服务已关闭,它也会在百度地图上指出你的位置。

共有1个答案

东郭展
2023-03-14

因此,只有在高精度省电模式下,网络提供商才可用

要在gps关闭时获取位置更新,您可以使用LocationManager.PASSIVE_PROVIDER。可以在此处获得详细信息

即使位置关闭,您也可以使用来自google play服务的LocationServices来获取最后一个已知位置。参考这个

 类似资料:
  • Galaxy S3-GPS图标没有出现,它没有启动onLocationChanged方法。(好吧) Htc one M8-GPS图标出现,闪烁,并触发onlocationchange(但如何?) 这时问题突然出现 null null

  • 我正在尝试从最好的提供商那里获取位置。我启用了GPS。此外,当我打印纬度和经度时,我从网络提供商那里获取它。 我的问题是: 如果启用了GPS,那么我想通过GPS搜索30秒的位置。在那之后,如果我的精度低于200米,那么我就使用它。如果精度超过200米,我会再次搜索,然后从网络提供商那里开始。 之后,我比较两者的准确性,并获取更准确的提供商的数据。 这是我的代码: LocationUtil。JAVA

  • PagodaBox AppFog Heroku fortrabbit Engine Yard Cloud Red Hat OpenShift Platform AWS Elastic Beanstalk Windows Azure Google App Engine Jelastic Platform.sh Cloudways IBM Bluemix Cloud Foundry Pivotal W

  • 从priority_balanced_power_precission给出的精确度有多高得到了这个? 高精度模式使用所有位置提供商,但是,它优先考虑位置提供商,并包括GPS和位置提供商。定位精度大约在10米范围内。 NO_POWER不使用任何位置提供商,而是从其他应用程序获取位置的被动模式。精确度可能是一英里或更多。它完全基于其他应用程序最近获取的位置。 Priority_balanced_pow

  • 我为一家SaaS提供商工作,该提供商希望以我们的应用程序作为服务提供商,向企业客户提供SSO应用程序。 我理解需要发生的事情背后的概念,并且SAML是我们希望做的事情的适当解决方案。看看更大的SaaS提供商(slack、dropbox、new relic等)我可以看到,它们通常似乎与许多身份提供商集成,如OneLogin、Bitium、Okta、Ping Identity等。。。以及通用SAML支

  • 我已经构建了一个自定义凭据提供程序,它在Windows SDK中作为示例提供。它在计算机上工作得很好。 当CR安装在远程服务器上,人们通过RDP连接到它时,会两次提示用户输入用户名/密码对,第一次是在本机RDP客户端中,第二次是在自定义凭据提供程序本身中,当用户通过本机RDP客户端成功登录时。 有没有办法获取第一步输入的用户名和密码,并将其写入CR字段。