[英]Location Not Received on Android App
I have an app that needs the location of the user, and I am new in implementing location service of Google. 我有一个需要用户所在位置的应用,而且我是Google实施位置服务的新手。 I made a separate java class to handle things related to getting location, and then using the location information in a activity just to show the location(so far), but I get the default value of 0 for latitude and longitude in my activity.
我创建了一个单独的java类来处理与获取位置相关的事情,然后使用活动中的位置信息来显示位置(到目前为止),但我的活动中的纬度和经度的默认值为0。
Here's the java class implementing the location related stuff, following google guideline: 以下是遵循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");
}
} }
And here is the caller of this location class (the fragment PostCommentFragment) 这是这个位置类的调用者(片段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;
}
What am I doing wrong here? 我在这做错了什么? I also added this line compile 'com.google.android.gms:play-services:7.8.0' to build.gradle(Module:app)->under dependencies, and asked for permission in Manifest.
我还将此行编译为'com.google.android.gms:play-services:7.8.0'到build.gradle(Module:app) - >依赖项下,并在Manifest中请求权限。 Thanks!
谢谢!
Issue 1: 问题1:
You're not calling connect()
on mGoogleApiClient. 你没有在mGoogleApiClient上调用
connect()
。
You need to call connect in order for onConnected()
to be invoked: 您需要调用connect以便调用
onConnected()
:
public CommentLocation(Context context){
buildGoogleApiClient(context);
mGoogleApiClient.connect(); //added
}
Issue 2: 问题2:
It looks like you're only using getLastLocation()
. 看起来你只使用
getLastLocation()
。 This may work for your needs, but if you need a location, this method is not guaranteed to give one. 这可能适合您的需求,但如果您需要某个位置,则无法保证此方法。 The
getLastLocation()
method can and will return null. getLastLocation()
方法可以并且将返回null。 The main problem is that it doesn't prompt a request to the OS for a new location lock, instead it just checks if there was a last known location from some other app's location request. 主要问题是它不会向操作系统提示请求新的位置锁定,而只是检查是否有来自其他应用程序位置请求的最后一个已知位置。 If no other app had recently made a location request, then you get a null location returned to you.
如果最近没有其他应用程序发出了位置请求,那么您将获得一个返回给您的空位置。
The only way to guarantee that you actually get a location is to request one, and this is done with a call to requestLocationUpdates(). 保证实际获得位置的唯一方法是请求一个,这是通过调用requestLocationUpdates()来完成的。
Issue 3: 问题3:
Given that it takes time to connect to the Google Api Client, the timing may be off, and even if you get a location from getLastLocation()
, you may have already requested it from your Fragment. 鉴于连接到Google Api客户端需要时间,时间可能会关闭,即使您从
getLastLocation()
获取位置,您可能已经从Fragment请求了它。
To get around this issue, you could use a BroadcastReceiver to send the location from the CommentLocation class to the Fragment. 要解决此问题,您可以使用BroadcastReceiver将位置从CommentLocation类发送到Fragment。
Note that in general keeping the location functionality encapsulated is a better approach, but it's more work to implement. 请注意,通常保持封装的位置功能是一种更好的方法,但实现起来还需要做更多的工作。 You might want to go with a more simple design, where the location functionality is within the Activity that is associated with this Fragment.
您可能希望采用更简单的设计,其中位置功能位于与此Fragment关联的Activity中。 Then you could just call into the Fragment when a location is available.
然后你可以在一个位置可用时调用Fragment。
Sample Activity code with a location listener: 带有位置侦听器的示例活动代码:
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.