我正在努力访问用户当前位置,并完成了本教程Current location和本教程Current Location。一切似乎都很好,但是TextView字段中没有出现纬度和经度。
这是我的代码
@Keep
public class edit_information extends Fragment implements AdapterView.OnItemSelectedListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult> {
protected final static String TAG = "EditInformation";
private static final int MY_PERMISSIONS_ACCESS_LOCATION = 1;
private RadioGroup radioGroup;
private RadioGroup musicRadioGroup;
private RadioGroup decorRadioGroup;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
//The desired interval for location updates
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
//The fastest rate for active location updates
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
//Keys for storing activity state in bundle
protected static final String KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates";
protected static final String KEY_LOCATION = "location";
protected static final String KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string";
/*
Provides entry point to Google play service
*/
protected GoogleApiClient mGoogleApiClient;
//Store parametrers for request to the FusedLocationProviderApi
protected LocationRequest mLocationRequest;
//location setting request
protected LocationSettingsRequest mLocationSettingsRequest;
protected Location mCurrentLocation;
//UI
protected TextView mLatitudeText;
protected TextView mLongitudeText;
protected Boolean mRequestingLocationUpdates;
protected String mLastUpdateTime;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_information, container, false);
Spinner spinner = (Spinner) view.findViewById(R.id.spinner1);
Spinner spinner2 = (Spinner) view.findViewById(R.id.spinner2);
//Creating an array adapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), R.array.hall_type, simple_spinner_item);
ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(getContext(), R.array.hall_size, simple_spinner_item);
//Layout to choose the dropdown list
adapter.setDropDownViewResource(simple_spinner_dropdown_item);
adapter1.setDropDownViewResource(simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner2.setAdapter(adapter1);
spinner.setOnItemSelectedListener(this);
spinner2.setOnItemSelectedListener(this);
radioGroup = (RadioGroup) view.findViewById(R.id.food_facility);
musicRadioGroup = (RadioGroup) view.findViewById(R.id.music_facility);
decorRadioGroup = (RadioGroup) view.findViewById(R.id.decor_facility);
mLatitudeText = (TextView) view.findViewById(R.id.myLatitude);
mLongitudeText = (TextView) view.findViewById(R.id.myLongitude);
mRequestingLocationUpdates = false;
mLastUpdateTime = "";
updateValuesFromBundle(savedInstanceState);
//Start the process of building GoogleApiClient, LocationRequest and LocationSettingRequest
buildGoogleApiClient();
createLocationRequest();
buildLocationSettingsRequest();
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
switch (checkedId) {
case R.id.yes:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.may:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.no:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
musicRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.yesMusic:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.mayMusic:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.noMusic:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
decorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.yesDecor:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.mayDecor:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.noDecor:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
return view;
}
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(adapterView.getContext(), "" + adapterView.getItemAtPosition(i).toString(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
private void updateValuesFromBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
// Update the value of mRequestingLocationUpdates from the Bundle, and make sure that
// the Start Updates and Stop Updates buttons are correctly enabled or disabled.
if (savedInstanceState.keySet().contains(KEY_REQUESTING_LOCATION_UPDATES)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
KEY_REQUESTING_LOCATION_UPDATES);
}
// Update the value of mCurrentLocation from the Bundle and update the UI to show the
// correct latitude and longitude.
if (savedInstanceState.keySet().contains(KEY_LOCATION)) {
// Since KEY_LOCATION was found in the Bundle, we can be sure that mCurrentLocation
// is not null.
mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION);
}
// Update the value of mLastUpdateTime from the Bundle and update the UI.
if (savedInstanceState.keySet().contains(KEY_LAST_UPDATED_TIME_STRING)) {
mLastUpdateTime = savedInstanceState.getString(KEY_LAST_UPDATED_TIME_STRING);
}
updateUI();
}
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void buildLocationSettingsRequest() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
}
protected void checkLocationSettings() {
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
mGoogleApiClient,
mLocationSettingsRequest
);
result.setResultCallback(this);
}
@Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i(TAG, "All location settings are satisfied.");
startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to" +
"upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(getActivity(), REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
"not created.");
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
Log.i(TAG, "User agreed to make required location settings changes.");
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
Log.i(TAG, "User chose not to make required location settings changes.");
break;
}
break;
}
}
public void startUpdatesButtonHandler(View view) {
checkLocationSettings();
}
public void stopUpdatesButtonHandler(View view) {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
stopLocationUpdates();
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
mLocationRequest,
this
).setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
mRequestingLocationUpdates = true;
}
});
}
private void updateUI() {
updateLocationUI();
}
private void updateLocationUI() {
if (mCurrentLocation != null) {
mLatitudeText.setText(String.valueOf(mCurrentLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));
}
}
@Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
public void onResume() {
super.onResume();
// Within {@code onPause()}, we pause location updates, but leave the
// connection to GoogleApiClient intact. Here, we resume receiving
// location updates if the user has requested them.
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
@Override
public void onPause() {
super.onPause();
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
}
}
protected void stopLocationUpdates() {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient,
this
).setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
mRequestingLocationUpdates = false;
}
});
}
@Override
public void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.i(TAG, "Connected to GoogleApiClient");
// If the initial location was never previously requested, we use
// FusedLocationApi.getLastLocation() to get it. If it was previously requested, we store
// its value in the Bundle and check for it in onCreate(). We
// do not request it again unless the user specifically requests location updates by pressing
// the Start Updates button.
//
// Because we cache the value of the initial location in the Bundle, it means that if the
// user launches the activity,
// moves to a new location, and then changes the device orientation, the original location
// is displayed as the activity is re-created.
if (mCurrentLocation == null) {
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
}
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_ACCESS_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
updateLocationUI();
// 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.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
/**
* Stores activity data in the Bundle.
*/
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean(KEY_REQUESTING_LOCATION_UPDATES, mRequestingLocationUpdates);
savedInstanceState.putParcelable(KEY_LOCATION, mCurrentLocation);
savedInstanceState.putString(KEY_LAST_UPDATED_TIME_STRING, mLastUpdateTime);
super.onSaveInstanceState(savedInstanceState);
}
}
这些是我在清单文件中添加的权限
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
这是纬度和经度的xml代码
<TextView
android:id="@+id/myLatitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="15sp"
android:textColor="@color/cordinates_color"
/>
<TextView
android:id="@+id/myLongitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="15sp"
android:textColor="@color/cordinates_color"
/>
我已在build.gradle应用级别添加此行并同步项目compile 'com.google.android.gms:play-services:10.0.1'
我已经能够连接到GoogleApiClient,但坐标不会出现。这是logcat的一瞥
01-29 14:49:31.395 10560-10560/com.example.luke.xyz I/EditInformation: Building GoogleApiClient
01-29 14:49:31.675 10560-10560/com.example.luke.xyz D/ViewRootImpl: #1 mView = android.widget.LinearLayout{2782c80 V.E...... ......I. 0,0-0,0}
01-29 14:49:31.715 10560-10616/com.example.luke.xyz D/mali_winsys: new_window_surface returns 0x3000, [468x91]-format:1
01-29 14:49:31.755 10560-10560/com.example.luke.xyz I/EditInformation: Connected to GoogleApiClient
01-29 14:49:31.805 10560-10616/com.example.luke.xyz V/RenderScript: 0xdc179000 Launching thread(s), CPUs 8
我在Android Marshmallow上测试它。仍无法弄明白。
你能救我吗?
谢谢
答案 0 :(得分:1)
询问这样的运行时权限:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.ACCESS_COURSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.ACCESS_COURSE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.ACCESS_COURSE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
// MY_PERMISSIONS_REQUEST_LOCATION is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
然后:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_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.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
您可以在此处找到更多详细信息:https://developer.android.com/training/permissions/requesting.html
答案 1 :(得分:0)
转到设置&gt;应用&gt; Your_app ,在权限标签中,启用位置即可立即获取Marshmallow的输出。
答案 2 :(得分:0)
使用位置Permission - ACCESS_COARSE_LOCATION , ACCESS_FINE_LOCATION
,同时使用Double
LatLng
:
@Override
public void onConnected(@Nullable Bundle connectionHint) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&&
ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, 1);
return;
}
}
else{
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation!=null){
mLatitudeText.setText(Double.parseDouble(mLastLocation.getLatitude()));
mLongitudeText.setText(Double.parseDouble(mLastLocation.getLongitude()));
}else {
Toast.makeText(getContext(),"LOcation is null",Toast.LENGTH_SHORT).show();
}
}
}
处理请求Permission
:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED){
Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
}
break;
}
}
答案 3 :(得分:0)
您的编码很好,您只需要为清单文件添加更多权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
确保您的gps已启用。如果这可以解决您的问题,请告诉我。
答案 4 :(得分:0)
您目前只询问onConnected
中的最后一个已知位置。如果没有缓存位置,则不执行任何操作。
一旦您的Google API客户端连接,您应该覆盖onLocationChanged
以接收当前位置。 https://developer.android.com/training/location/receive-location-updates.html#callback
GoogleApiClient.connect
方法是异步的。在上面链接的文档中,位置更新请求是在GoogleApiClient
连接后进行的。您是在onResume
内提出此请求,但不保证GoogleApiClient
在onConnected
之前已连接。在onConnected
中发出请求,如文档中的示例所示。