[英]Location Not Received on Android App
我有一个需要用户所在位置的应用,而且我是Google实施位置服务的新手。 我创建了一个单独的java类来处理与获取位置相关的事情,然后使用活动中的位置信息来显示位置(到目前为止),但我的活动中的纬度和经度的默认值为0。
以下是遵循google指南实现位置相关内容的java类:
import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
public class CommentLocation implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private double mLatitude;
private double mLongitude;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
public CommentLocation(Context context){
buildGoogleApiClient(context);
}
public double getCommentLongitude() {
return mLongitude;
}
public double getCommentLatitude() {
return mLatitude;
}
protected synchronized void buildGoogleApiClient(Context context) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
public void onConnected(Bundle connectionHint) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
mLatitude = mLastLocation.getLatitude();
mLongitude = mLastLocation.getLongitude();
}
else{
Log.v(CommentLocation.class.getName(), "LOCATION WAS NOT RECEIVED");
}
Log.v(CommentLocation.class.getName(), "CONNECTION TO GET LOCATION IS SUCCESSFUL");
}
@Override
public void onConnectionSuspended(int i) {
//TODO
Log.v(CommentLocation.class.getName(), "CONNECTION TO GET LOCATION IS SUSPENDED");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
//TODO
Log.v(CommentLocation.class.getName(), "CONNECTION TO GET LOCATION IS FAILED");
}
}
这是这个位置类的调用者(片段PostCommentFragment)
public class PostCommentFragment extends Fragment {
private TextView mLatitudeText;
private TextView mLongtitudeText;
private CommentDatabase database;
private CommentLocation location;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = new CommentDatabase(getActivity());
location = new CommentLocation(getActivity());
setHasOptionsMenu(true);
}
@TargetApi(11) //for setDisplayHomeAsUpEnabled function
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_post_comment, container, false);
//to enable the app icon to work as a button and get the caret to appear in fragment's view
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
if(NavUtils.getParentActivityName(getActivity()) != null) {
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
mLatitudeText = (TextView) v.findViewById(R.id.latitude_text);
mLongtitudeText = (TextView) v.findViewById(R.id.longitude_text);
mLatitudeText.setText(String.valueOf(location.getCommentLatitude()));
mLongtitudeText.setText(String.valueOf(location.getCommentLongitude()));
return v;
}
我在这做错了什么? 我还将此行编译为'com.google.android.gms:play-services:7.8.0'到build.gradle(Module:app) - >依赖项下,并在Manifest中请求权限。 谢谢!
问题1:
你没有在mGoogleApiClient上调用connect()
。
您需要调用connect以便调用onConnected()
:
public CommentLocation(Context context){
buildGoogleApiClient(context);
mGoogleApiClient.connect(); //added
}
问题2:
看起来你只使用getLastLocation()
。 这可能适合您的需求,但如果您需要某个位置,则无法保证此方法。 getLastLocation()
方法可以并且将返回null。 主要问题是它不会向操作系统提示请求新的位置锁定,而只是检查是否有来自其他应用程序位置请求的最后一个已知位置。 如果最近没有其他应用程序发出了位置请求,那么您将获得一个返回给您的空位置。
保证实际获得位置的唯一方法是请求一个,这是通过调用requestLocationUpdates()来完成的。
问题3:
鉴于连接到Google Api客户端需要时间,时间可能会关闭,即使您从getLastLocation()
获取位置,您可能已经从Fragment请求了它。
要解决此问题,您可以使用BroadcastReceiver将位置从CommentLocation类发送到Fragment。
请注意,通常保持封装的位置功能是一种更好的方法,但实现起来还需要做更多的工作。 您可能希望采用更简单的设计,其中位置功能位于与此Fragment关联的Activity中。 然后你可以在一个位置可用时调用Fragment。
带有位置侦听器的示例活动代码:
public class MainActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buildGoogleApiClient();
mGoogleApiClient.connect();
}
@Override
protected void onPause(){
super.onPause();
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
public void onConnected(Bundle bundle) {
Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10);
mLocationRequest.setFastestInterval(10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
//mLocationRequest.setSmallestDisplacement(0.1F);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
}
@Override
public void onLocationChanged(Location location) {
Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude());
Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.