无法通过服务(LocationManager)获取位置

时间:2016-11-09 23:11:57

标签: java android service gps locationmanager

我在这里遇到了麻烦。尝试每隔3秒获得一个后台服务的lat和lon但我只能在模拟器的扩展控件中单击发送lat和lon时才能获得一些数据,因此手机和模拟器都无法正常工作。以下是我的代码,如果有人可以帮助我,那将是非常棒的。谢谢!

服务

public class GPSService extends Service {


    private static final String TAG = "GpsService";
    private LocationListener locationListener;
    private LocationManager locationManager;


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {

        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                Intent i = new Intent("location_update");
                i.putExtra("latExtra",location.getLatitude());
                i.putExtra("lonExtra",location.getLongitude());
                sendBroadcast(i);
                Log.i(TAG, "onLocationChanged: extras lat lon"+location.getLatitude()+" "+location.getLongitude());
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {

            }

            @Override
            public void onProviderEnabled(String s) {

            }

            @Override
            public void onProviderDisabled(String s) {
                Log.i(TAG, "onProviderDisabled: DISABLED");
                Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
            }
        };

        locationManager =(LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);

        Criteria c = new Criteria();
        String provider =locationManager.getBestProvider(c,true);
        Log.i(TAG, "onCreate: bestProvider "+provider);

        //noinspection MissingPermission
        locationManager.requestLocationUpdates(provider,2000,0,locationListener);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (locationManager != null){
            Log.i(TAG, "onDestroy: Location manager nije null i brisem");
            //noinspection MissingPermission
            locationManager.removeUpdates(locationListener);
        }

    }
}

MainActivity

    private final String TAG = "Main";
    ...
    BroadcastReceiver broadcastReciever;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        //setStatusBarTranslucent(false);


        if(!runtimePermisions()){
            startLocationUpdate();}
...

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //stopService();
                if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    //REQUEST PERMISSION
                    Log.i(TAG, "onClick: NO PERMISION");
                } else {
                    Log.i(TAG, "onClick: got permision");
                }
...
    }
    public void startLocationUpdate(){
        Intent i = new Intent(this,GPSService.class);
        startService(i);
        Log.i(TAG, "startLocationUpdate: Pokrenuo sam service");
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (broadcastReciever == null){
            broadcastReciever = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {

                    lat = (Double) intent.getExtras().get("latExtra");
                    lon = (Double) intent.getExtras().get("lonExtra");

                    Log.i(TAG, "onReceive: lat lon "+lat+" "+lon);
                }
            };
        }
        registerReceiver(broadcastReciever,new IntentFilter("location_update"));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (broadcastReciever!=null){
            unregisterReceiver(broadcastReciever);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 100) {
                if (grantResults [0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
                    startLocationUpdate();
                }else{
                    runtimePermisions();}
            }

    }


    private boolean runtimePermisions() {
        if (Build.VERSION.SDK_INT >= 23 &&ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
            requestPermissions(new String[]{
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,

            },100);
            return true;
        }
        return false;
    }

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.digiart.yoweather">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SettingsActivity"
            android:theme="@style/SettingsTheme"></activity>
        <service android:name=".Gps.GPSService"/>
    </application>

</manifest>

再次......任何帮助都会很棒!谢谢:D

1 个答案:

答案 0 :(得分:0)

正如K. Sopheak所说,获取该位置可能需要一段时间。来自文档:

  

接收第一个位置更新可能需要一段时间。如果需要立即位置,应用程序可以使用getLastKnownLocation(String)方法。

因此,您可以尝试在服务启动时使用getLastKnownLocation(String)获取最后一个已知位置,并假设它存在,以与位置更新相同的方式广播它。但请记住,最后一个已知位置可能已过时。根据您使用的内容,可能会或可能不接受此位置。

另外,还有一些想法:

  1. 你说3秒,但代码使用了2000毫秒 - 这只是一个错字?

  2. 位置更新的频率是最小时间 - 您无法保证经常获得更新。根据文件:

      

    可以使用minTime参数控制位置更新间隔。位置更新之间经过的时间永远不会小于minTime,尽管它可能更多取决于位置提供程序实现和其他应用程序请求的更新间隔。

  3. 您是否有任何特殊原因需要以如此高的频率更新位置?获取位置可能是电池密集型的,特别是考虑到您要求FINE以及COARSE位置权限,因此频繁请求它可能会大大消耗设备的电池寿命。鉴于代码在服务中运行并且因此即使应用程序在后台或用户处于不需要位置数据的活动中也将继续运行,因此尤其如此。再次,从文档:

      

    为minTime选择合理的值对于延长电池寿命非常重要。每个位置更新都需要来自GPS,WIFI,Cell和其他无线电的电源。选择尽可能高的minTime值,同时仍提供合理的用户体验。如果您的应用程序不在前台并向用户显示位置,那么您的应用程序应避免使用活动提供程序(例如NETWORK_PROVIDER或GPS_PROVIDER),但如果您坚持,则选择minTime为5 * 60 * 1000(5分钟)或更大。如果您的应用程序位于前台并向用户显示位置,则选择更快的更新间隔是合适的。

  4. Google建议使用Google Play services location APIs代替Android框架位置API:

      

    Google Play服务位置API优先于Android框架位置API(android.location),作为向您的应用添加位置感知的一种方式。如果您当前正在使用Android框架位置API,强烈建议您尽快切换到Google Play服务位置API。