android - 使用 PendingIntent 获取位置始终返回 Null

标签 android google-maps location google-play-services android-pendingintent

在了解最佳方法后,我正在使用 PendingIntent 获取 Location reference to my old post . PendingIntent 完全按照我的需要工作。但它始终将位置返回为 null。

Intent intent = new Intent(this, LocationReceiver.class);
PendingIntent locationIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, locationIntent);

在 LocationReceiver(广播接收器类)中,

public class LocationReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Log.i("LocationReceiver", "OnReceive");
    Location location = (Location) intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED);
    if (location != null) {
        double lat = location.getLatitude();
        double lng = location.getLongitude();

        Log.i("LocationReceiver", lat + ", " + lng);
    } else {
        Log.i("LocationReceiver", "Location is null");
    }

    LocationReceiver.completeWakefulIntent(intent);
  }
}

附加信息,

使用 GooglePlayService 8.3.0buildToolVersion 23.0.2

我想知道在什么情况下返回Null!任何帮助将不胜感激!

编辑: list

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<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="com.google.android.providers.gsf.permission.READ_GSERVICES" />

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

<application
    android:name="package.ApplicationClass"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity
        android:name=".activity.SplashScreen"
        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>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".activity.MapsActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.MapsActivity" />
    <activity
        android:name=".activity.LoginActivity"
        android:label="@string/title_activity_login"
        android:theme="@style/AppTheme.NoActionBar" />

    <receiver android:name=".receiver.LocationReceiver"/>

</application>
</manifest>

启动画面

public class SplashScreen extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, ResultCallback<LocationSettingsResult>,
    LocationListener {

public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
        UPDATE_INTERVAL_IN_MILLISECONDS / 2;

protected static final int REQUEST_CHECK_SETTINGS = 0x1;
private final static String TAG = "SplashScreen";

protected Boolean mRequestingLocationUpdates;

protected Location mCurrentLocation;

protected GoogleApiClient googleApiClient;
protected LocationSettingsRequest locationSettingsRequest;
protected LocationRequest locationRequest;

/**
 * Initialize GoogleApiClient Builder to fetch required Google Services
 */
protected synchronized void buildGoogleApiClient() {
    googleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}


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

    mRequestingLocationUpdates = false;

    buildGoogleApiClient();

    createLocationRequest();

    buildLocationSettingsRequest();

    checkLocationSettings();
}

@Override
protected void onStart() {
    super.onStart();

    // Establish the connection to GoogleApiClient
    googleApiClient.connect();
}

@Override
protected void onResume() {
    super.onResume();

    if (googleApiClient.isConnected() && mRequestingLocationUpdates) {
        startLocationUpdates();
    } else
        Log.i(TAG, "onResume - Failed");
}

protected void createLocationRequest() {
    locationRequest = new LocationRequest();

    locationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
       locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);

    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

protected void buildLocationSettingsRequest() {
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
    builder.addLocationRequest(locationRequest);
    builder.setAlwaysShow(true);
    locationSettingsRequest = builder.build();
}

protected void checkLocationSettings() {
    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(
                    googleApiClient,
                    locationSettingsRequest);
    result.setResultCallback(this);
}

@Override
public void onConnected(Bundle bundle) {

    if (mCurrentLocation == null)
        mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
}

private void validateUserAndProcess() {
    boolean isExistingUser = false;
    try {
        isExistingUser = (boolean) ApplicationClass.mSharedPreferenceOperation.getData(
                getString(R.string.is_existing_user), SharedPreferenceOperation.BOOLEAN);
    } catch (Exception e) {
        e.printStackTrace();
    }

    if (isExistingUser) {
        Intent intent = new Intent(this, MapsActivity.class);
        startActivity(intent);
        finish();
    } else {
        int currentApiVersion = Build.VERSION.SDK_INT;

        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        String deviceId = telephonyManager.getDeviceId();

        Intent intent = new Intent(this, LoginActivity.class);
        intent.putExtra(getString(R.string.intent_extra_user_imei), deviceId);
        intent.putExtra(getString(R.string.intent_extra_user_android_api), currentApiVersion);
        startActivity(intent);
        finish();
    }
}


@Override
public void onConnectionSuspended(int cause) {

    // In case of connection is suspended.
    switch (cause) {
        case CAUSE_NETWORK_LOST:
            Toast.makeText(this, "Connection Suspended due to Network Lost", Toast.LENGTH_LONG).show();
            break;
        case CAUSE_SERVICE_DISCONNECTED:
            Toast.makeText(this, "Connection Suspended due to Service Disconnection", Toast.LENGTH_LONG).show();
            break;
        default:
            Toast.makeText(this, "Connection Suspended due to Unknown Issue", Toast.LENGTH_LONG).show();
            break;
    }
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Toast.makeText(this, "Failed to connect due to " + connectionResult.getErrorCode(), Toast.LENGTH_LONG).show();
}

@Override
public void onResult(LocationSettingsResult locationSettingsResult) {
    final Status status = locationSettingsResult.getStatus();
    switch (status.getStatusCode()) {
        case LocationSettingsStatusCodes.SUCCESS:
            // Start Location Updates
            startLocationUpdates();
            break;
        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
            try {
                // Show the dialog by calling startResolutionForResult(), and check the result
                // in onActivityResult().
                status.startResolutionForResult(SplashScreen.this, REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException e) {
                e.printStackTrace();
            }
            break;
        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
            Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
                    "not created.");
            break;
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
        // Check for the integer request code originally supplied to startResolutionForResult().
        case REQUEST_CHECK_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // Start Location Updates
                    startLocationUpdates();
                    break;
                case Activity.RESULT_CANCELED:
                    finish();
                    break;
            }
            break;
    }
}

@Override
public void onLocationChanged(Location location) {
    mCurrentLocation = location;

    Intent intent = new Intent(this, LocationReceiver.class);
    PendingIntent locationIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, locationIntent);

    if (mCurrentLocation != null) {

        ApplicationClass.LATITUDE = mCurrentLocation.getLatitude();
        ApplicationClass.LONGITUDE = mCurrentLocation.getLongitude();

        validateUserAndProcess();
    }
}

/**
 * Requests location updates from the FusedLocationApi.
 */
protected void startLocationUpdates() {
    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest,
            this).setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(Status status) {
            mRequestingLocationUpdates = true;
        }
    });

    Log.i(TAG, "startLocationUpdates Invoked");
}

@Override
protected void onStop() {
    super.onStop();
    //googleApiClient.disconnect();
}

@Override
protected void onPause() {
    super.onPause();

    // Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
    /**if (googleApiClient.isConnected()) {
        stopLocationUpdates();
     }*/
}

/**
 * Removes location updates from the FusedLocationApi.
 */
protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this)
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    mRequestingLocationUpdates = false;
                }
            });
    }
}

最佳答案

取而代之的是:

Location location = (Location) intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED);

尝试使用:

LocationResult locationResult = LocationResult.extractResult(intent);
if (locationResult != null) {}

关于android - 使用 PendingIntent 获取位置始终返回 Null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34252744/

相关文章:

Android Studio 新项目文件大小太大

android - 如何使用Google CardBoard SDK 实现Google StreetView?

安卓 : Get notification when user enter in specific location

android - 为什么 texImage2D 总是给出无效操作错误?

Android 和 Azure 移动服务异常 : "Error while processing request"

javascript - 使用 Maps API XML 示例调整 map 标记的大小

android - 为两个 LatLong 值计算 Google map 的缩放级别

objective-c - 在网络偏好设置 Pane 中设置 "Location"值,而不使用私有(private) API

android - 为什么我的应用程序强制关闭?

java - 检查是否有任何日历事件/媒体文件已更新