Поиск местоположения пользователя

Я пытаюсь получить местоположение пользователя для моего приложения погоды. В настоящее время я не могу этого сделать и пытался следовать как Руководству по последнему известному местоположению Google, так и https://guides.codepath.com/android/Retrieving-Location-with-LocationServices-API.

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    public static final String TAG = MainActivity.class.getSimpleName();

    public CurrentWeather mCurrentWeather;

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    double latitude;
    double longitude;

    @BindView(R.id.timeLabel)
    TextView mTimeLabel;
    @BindView(R.id.temperatureLabel)
    TextView mTemperatureLabel;
    @BindView(R.id.humidityValue)
    TextView mHumidityValue;
    @BindView(R.id.precipValue)
    TextView mPrecipValue;
    @BindView(R.id.summaryTextView)
    TextView mSummaryLabel;
    @BindView(R.id.iconImageView)
    ImageView mIconImageView;
    @BindView(R.id.refreshImageView)
    ImageView mRefreshImageView;
    @BindView(R.id.progressBar)
    ProgressBar mProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();

        // Import view variables
        ButterKnife.bind(this);

        // Set default progressbar to invisible 
        mProgressBar.setVisibility(View.INVISIBLE);

        // Create onClick for the refresh button
        mRefreshImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getForecast(latitude, longitude);
            }
        });

        getForecast(latitude, longitude);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        if (mGoogleApiClient != null) {
            mGoogleApiClient.disconnect();
        }
        super.onStop();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mCurrentLocation != null){
            Log.d("DEBUG", "current location: " + mCurrentLocation.toString());
            latitude = mCurrentLocation.getLatitude();
            longitude = mCurrentLocation.getLongitude();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        if (i == CAUSE_SERVICE_DISCONNECTED) {
            Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
        } else if (i == CAUSE_NETWORK_LOST) {
            Toast.makeText(this, "Network lost. Please re-connect.", Toast.LENGTH_SHORT).show();
        }
    }

Чего я пытаюсь добиться, так это получить координаты широты и долготы, а затем сохранить их в глобальных переменных, чтобы позже использовать их при вызове getForecast().

AndroidManifest.xml:

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_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:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

person user2683183    schedule 21.07.2016    source источник
comment
Так что же происходит на самом деле?   -  person childofsoong    schedule 21.07.2016
comment
Когда он запускается, он регистрирует широту и долготу для местоположения, и он отображается как 0   -  person user2683183    schedule 21.07.2016
comment
Что находится в вашем файле AndroidManifest?   -  person Eenvincible    schedule 21.07.2016
comment
@Eenvincible Я обновил свой вопрос, включив в него манифест   -  person user2683183    schedule 21.07.2016
comment
Попробуйте добавить WRITE_EXTERNAL_STORAGE и INTERNAL_STORAGE, а затем повторите попытку.   -  person Eenvincible    schedule 21.07.2016
comment
посмотрите ответ Дэвида, а также его комментарий под его ответом здесь   -  person Bill    schedule 21.07.2016
comment
Кроме того, вам нужно включить GPS или нет?   -  person Eenvincible    schedule 21.07.2016
comment
@Eenvincible Когда я выполняю автозаполнение в манифесте, я обнаружил только WRITE_EXTERNAL_STORAGE, а не INTERNAL_STORAGE. Только с этим я попытался запустить его снова, и все равно не повезло. GPS на моем устройстве включен.   -  person user2683183    schedule 21.07.2016
comment
@quidproquo Я посмотрел на его ответ, и он отлично читается. Как мне реализовать LocationRequest?   -  person user2683183    schedule 21.07.2016
comment
Извините, имелось ввиду следующее:   -  person Eenvincible    schedule 21.07.2016
comment
@Eenvincible, это не сработало   -  person user2683183    schedule 21.07.2016
comment
Ссылка, которой вы поделились выше guides.codepath.com/android/ предлагает некоторые идеи по устранению неполадок; пожалуйста, попробуйте и посмотрите, получите ли вы null при вызове LocationServices.FusedLocationApi.getLastLocation   -  person Eenvincible    schedule 21.07.2016
comment
Давайте продолжим обсуждение в чате.   -  person Eenvincible    schedule 21.07.2016


Ответы (1)


Попробуйте следующее решение:

  • Во-первых, убедитесь, что вы реализовали правильный интерфейс LocationListener в своем классе активности:

     com.google.android.gms.location.LocationListener
    

Затем запросите соответствующие разрешения для поддержки устройств Android под управлением v6.0.

 private static final int MY_PERMISSION_REQUEST_READ_COARSE_LOCATION = 102;

Затем запросите разрешение:

@Override
public void onConnected(@Nullable Bundle bundle) {

  // what version of android are you using?
  // Answer = 6.0

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
        ActivityCompat.requestPermissions(thisActivity,
              new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
              MY_PERMISSION_REQUEST_READ_COARSE_LOCATION);

    }

    Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (mCurrentLocation != null) {
        Log.d(TAG, "current location: " + mCurrentLocation.toString());
        latitude = mCurrentLocation.getLatitude();
        longitude = mCurrentLocation.getLongitude();
    }

     startLocationUpdates();

}

Чтобы получить результаты запросов разрешений во время выполнения, переопределите этот метод:

@Override
public void onRequestPermissionsResult(int requestCode,
    String permissions[], int[] grantResults) {
    switch (requestCode) {

      case MY_PERMISSION_REQUEST_READ_COARSE_LOCATION:~~~~~~~~~~~
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            // permission was granted, yay! Do the
            // contacts-related task you need to do.

        } else {

            // permission denied, boo! Disable the
            // functionality that depends on this permission.
        }
        break;
    }

    // other 'case' lines to check for other
    // permissions this app might request
  }
}

Затем ваш метод обновления местоположения:

protected void startLocationUpdates() {
    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(UPDATE_INTERVAL)
            .setFastestInterval(FASTEST_INTERVAL);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        //request permission here like you already do above
        return;
    }

    //there is a problem here because LocationListener is cast as an activity
       LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}

Это должно сделать это;

Удачного кодирования!

person Eenvincible    schedule 21.07.2016