Я экспериментировал с базовым приложением определения местоположения, предоставляемым Службами Google Play. https://github.com/android/location-samples/tree/master/BasicLocation
Насколько я понимаю, приложение возвращает широту и долготу в виде текстовых представлений. Тем не менее, я хотел бы получить значения широты и долготы как двойные, чтобы я мог передавать значения другим функциям и / или вычислениям.
По умолчанию MainActivity.java и скриншот обычного вывода на моем эмуляторе находятся в нижней части этого поста.
Чтобы попытаться получить значения широты и долготы как двойные, я попробовал дваметоды:
- Получение широты и долготы как двойных
- Преобразование текстовых представлений широты / долготы в двойные
Чтобы попытаться читать по широте иЗначения долготы как двойные, я отредактировал раздел getLastLocation (), как показано ниже.
private void getLastLocation() {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(this, new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLastLocation = task.getResult();
// lines added here
mLatitudeDouble = mLastLocation.getLatitude();
mLongitudeDouble = mLastLocation.getLongitude();
} else {
Log.w(TAG, "getLastLocation:exception", task.getException());
showSnackbar(getString(R.string.no_location_detected));
}
}
});
}
Однако, когда я передаю mLatitudeDouble и mLongitudeDouble в текстовое представление, просто чтобы проверить, что каждый возвращает, оба показывают ноль.
В качестве альтернативы я попытался преобразовать текстовые представления широты и долготы в двойные. Чтобы сделать это, я сначала отредактировал текстовые представления так, чтобы были возвращены только числа.
private void getLastLocation() {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(this, new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLastLocation = task.getResult();
mLatitudeText.setText(String.format(Locale.ENGLISH, "%s",
mLastLocation.getLatitude()));
mLongitudeText.setText(String.format(Locale.ENGLISH, "%s",
mLastLocation.getLongitude()));
} else {
Log.w(TAG, "getLastLocation:exception", task.getException());
showSnackbar(getString(R.string.no_location_detected));
}
}
});
}
, который первоначально дал вывод, который выглядит следующим образом
![enter image description here](https://i.stack.imgur.com/kKN7q.png)
Однако, когда я попытался преобразовать текстовые представления в двойные, используя код под приложением, произошел сбой без предупреждения. Эта строка кода основана на другой записи Преобразование значения TextView в двойную переменную
double mLatitudeTextDouble = Double.parseDouble(mLatitudeText.getText().toString());
Я запустил приложение в режиме отладки, и похоже, что ошибка была вызвана пустой строкой. Соответствующая строка размещена ниже.
2019-10-24 16:44:55.996 22629-22629/com.google.android.gms.location.sample.basiclocationsample E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.google.android.gms.location.sample.basiclocationsample, PID: 22629
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.android.gms.location.sample.basiclocationsample/com.google.android.gms.location.sample.basiclocationsample.MainActivity}: java.lang.NumberFormatException: empty String
Если у кого-нибудь есть какие-либо предложения о том, как получить значения долготы и широты как двойные, или можете указать мне направление соответствующих фоновых чтений, это будет очень полезно, и я могуответьте на любые вопросы, если это необходимо. Извиняюсь, если вы прочитали пост, похожий на этот ранее. Я удалил предыдущий пост, потому что я думал, что это не очень ясно.
Внешний вид приложения при нормальной работе
![enter image description here](https://i.stack.imgur.com/7zupi.png)
Основная активность по умолчанию
/*
Copyright 2017 Google Inc. All Rights Reserved.
<p>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<p>
http://www.apache.org/licenses/LICENSE-2.0
<p>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
*/
package com.google.android.gms.location.sample.basiclocationsample;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import androidx.annotation.NonNull;
import com.google.android.material.snackbar.Snackbar;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import java.util.Locale;
/**
* Location sample.
* <p>
* Demonstrates use of the Location API to retrieve the last known location for a device.
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
/**
* Provides the entry point to the Fused Location Provider API.
*/
private FusedLocationProviderClient mFusedLocationClient;
/**
* Represents a geographical location.
*/
protected Location mLastLocation;
private String mLatitudeLabel;
private String mLongitudeLabel;
private TextView mLatitudeText;
private TextView mLongitudeText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mLatitudeLabel = getResources().getString(R.string.latitude_label);
mLongitudeLabel = getResources().getString(R.string.longitude_label);
mLatitudeText = (TextView) findViewById((R.id.latitude_text));
mLongitudeText = (TextView) findViewById((R.id.longitude_text));
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
@Override
public void onStart() {
super.onStart();
if (!checkPermissions()) {
requestPermissions();
} else {
getLastLocation();
}
}
/**
* Provides a simple way of getting a device's location and is well suited for
* applications that do not require a fine-grained location and that do not need location
* updates. Gets the best and most recent location currently available, which may be null
* in rare cases when a location is not available.
* <p>
* Note: this method should be called after location permission has been granted.
*/
@SuppressWarnings("MissingPermission")
private void getLastLocation() {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(this, new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLastLocation = task.getResult();
mLatitudeText.setText(String.format(Locale.ENGLISH, "%s: %f",
mLatitudeLabel,
mLastLocation.getLatitude()));
mLongitudeText.setText(String.format(Locale.ENGLISH, "%s: %f",
mLongitudeLabel,
mLastLocation.getLongitude()));
} else {
Log.w(TAG, "getLastLocation:exception", task.getException());
showSnackbar(getString(R.string.no_location_detected));
}
}
});
}
/**
* Shows a {@link Snackbar} using {@code text}.
*
* @param text The Snackbar text.
*/
private void showSnackbar(final String text) {
View container = findViewById(R.id.main_activity_container);
if (container != null) {
Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
}
}
/**
* Shows a {@link Snackbar}.
*
* @param mainTextStringId The id for the string resource for the Snackbar text.
* @param actionStringId The text of the action item.
* @param listener The listener associated with the Snackbar action.
*/
private void showSnackbar(final int mainTextStringId, final int actionStringId,
View.OnClickListener listener) {
Snackbar.make(findViewById(android.R.id.content),
getString(mainTextStringId),
Snackbar.LENGTH_INDEFINITE)
.setAction(getString(actionStringId), listener).show();
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
private void startLocationPermissionRequest() {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION);
// Provide an additional rationale to the user. This would happen if the user denied the
// request previously, but didn't check the "Don't ask again" checkbox.
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
showSnackbar(R.string.permission_rationale, android.R.string.ok,
new View.OnClickListener() {
@Override
public void onClick(View view) {
// Request permission
startLocationPermissionRequest();
}
});
} else {
Log.i(TAG, "Requesting permission");
// Request permission. It's possible this can be auto answered if device policy
// sets the permission in a given state or the user denied the permission
// previously and checked "Never ask again".
startLocationPermissionRequest();
}
}
/**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If user interaction was interrupted, the permission request is canceled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
getLastLocation();
} else {
// Permission denied.
// Notify the user via a SnackBar that they have rejected a core permission for the
// app, which makes the Activity useless. In a real app, core permissions would
// typically be best requested during a welcome-screen flow.
// Additionally, it is important to remember that a permission might have been
// rejected without asking the user for permission (device policy or "Never ask
// again" prompts). Therefore, a user interface affordance is typically implemented
// when permissions are denied. Otherwise, your app could appear unresponsive to
// touches or interactions which have required permissions.
showSnackbar(R.string.permission_denied_explanation, R.string.settings,
new View.OnClickListener() {
@Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
}
}