2016-05-06 62 views
1

我想使用Google的融合位置API获取我的位置。为此,我创建了两个类。一个是MainActivity,另一个是FusedLocationService,其中MainActivity是主类。但是我的经度和纬度都是0.0。所以请帮助我。无法使用Google的融合位置API获取位置

这里是我的MainActivity代码: -

public class MainActivity extends AppCompatActivity { 

TextView tvLocation; 
FusedLocationService fusedLocationService; 
double latitude; 
double longitude; 

String locationResult = ""; 
Location location; 

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

    tvLocation = (TextView) findViewById(R.id.tvLocation); 
    fusedLocationService = new FusedLocationService(this); 
    location = fusedLocationService.getLocation(); 

    if (null != location) { 
     latitude = location.getLatitude(); 
     longitude = location.getLongitude(); 
     locationResult = "Latitude: " + latitude + "\n" + 
       "Longitude: " + longitude + "\n"; 
    } else { 
     Timber.e("-error-%s", "Location Not Available!"); 
     locationResult = "Location Not Available!"; 
    } 

    Log.e("Lati ", String.valueOf(latitude)); 
    Log.e("longi ", String.valueOf(longitude)); 
    tvLocation.setText(locationResult); 
    } 
} 

这里是我FusedLocationService类: -

public class FusedLocationService implements LocationListener, GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener { 

private static final long INTERVAL = 1000 * 30; //30sec 
private static final long FASTEST_INTERVAL = 1000 * 5; // 5sec 

Activity mActivity; 
public LocationRequest locationRequest; 
public GoogleApiClient googleApiClient; 
public Location location; 
public FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi; 

public FusedLocationService(Activity activity) { 

    Timber.plant(new Timber.DebugTree()); 
    locationRequest = LocationRequest.create(); 
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    locationRequest.setInterval(INTERVAL); 
    locationRequest.setFastestInterval(FASTEST_INTERVAL); 
    mActivity = activity; 
    googleApiClient = new GoogleApiClient.Builder(mActivity) 
      .addApi(LocationServices.API) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .build(); 

    if (googleApiClient != null) { 
     googleApiClient.connect(); 
    } 

} 

@Override 
public void onConnected(Bundle connectionHint) { 
    Log.e("-onConnected-", "connected now"); 
    location = fusedLocationProviderApi.getLastLocation(googleApiClient); 
    fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this); 
} 

@Override 
public void onLocationChanged(Location location) { 
} 

public Location getLocation() { 
    return location; 
} 

@Override 
public void onConnectionSuspended(int i) { 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    } 
} 

我已经包含在gradle这个文件夹中的体现权限和lib。 所以请帮助。谢谢你在前进

+0

在'onConnected'方法检查此代码'googleApiClient.isConnected()'。如果它返回false,那么应该有一个残疾人位置的情况下可能在设置电话或谷歌服务。 –

回答

2

到新位置的参考丢失:

@Override 
public void onLocationChanged(Location location) { 
    this.location = location; 
} 

而且位置更新异步。因此,您需要类似回调的活动。

编辑:

还检查谷歌播放服务是可用的。您可以创建这样的方法:

public boolean checkPlayServices() { 
    return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS; 
} 

Google documentation

+0

谢谢你的回答,但添加this.location = location到onLocationChanged后仍然是同样的问题@momo – Ghost

+0

我已编辑我的帖子 – momo

+0

不要在'Activity'中调用'location = fusedLocationService.getLocation();'的onCreate()'。这是行不通的,因为这个位置不是立即可用的。事实上,不要在'onCreate()'中做任何需要位置的事情。一旦'onLocationChanged(Location location)'被调用,人们正在解释,你只有一个位置。重新设计你的代码,以便只有在调用了onLocationChanged()'后才会运行任何与位置有关的事务。 –

1

简短说明

你是让你的全球纬度和经度变量

double latitude; 
double longitude; 

长的默认值解释

当你实例FusedLocationService类

fusedLocationService = new FusedLocationService(this); 

它建立谷歌API客户端然后尝试

public FusedLocationService(Activity activity) { 
    ... 
    googleApiClient = new GoogleApiClient.Builder(mActivity) 
     .addApi(LocationServices.API) 
     .addConnectionCallbacks(this) 
     .addOnConnectionFailedListener(this) 
     .build(); 

    if (googleApiClient != null) { 
     googleApiClient.connect(); 
    } 
} 

,并在成功连接来连接,使得定位请求

@Override 
public void onConnected(Bundle connectionHint) { 
    Log.e("-onConnected-", "connected now"); 
    location = fusedLocationProviderApi.getLastLocation(googleApiClient); 
    fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this); 
} 

连接谷歌的API,并且接收位置是异步操作。

这意味着,必须趋向于它们的回调函数

但是你的初始化FusedLocationService课后使用经纬度变量。所以这就是为什么你获得0.0作为经度和纬度。

Log.e("Lati ", String.valueOf(latitude)); 
Log.e("longi ", String.valueOf(longitude)); 
tvLocation.setText(locationResult); 

编辑 - 临门一脚

首先,你可以删除或移动这些代码。您正在处理异步操作。

Log.e("Lati ", String.valueOf(latitude)); 
Log.e("longi ", String.valueOf(longitude)); 
tvLocation.setText(locationResult); 

当谷歌的API连接,请检查先前接收的位置,并更新你的UI如有

@Override 
public void onConnected(Bundle connectionHint) { 
    ... 
    Location location = fusedLocationProviderApi.getLastLocation(googleApiClient); 
    // Provider could return null, because it tries to get location if any 
    if(location != null){ 
     // UPDATE YOUR UI 
    } 
    fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this); 
} 

当接收到新的位置,更新你的UI

@Override 
public void onLocationChanged(Location location) { 
    // You have received fresh location 
    // UPDATE YOUR UI 
} 

还要检查这个link,你会更好地理解我提到的方面。

+0

谢谢你的解释。那么你能否提供解决这个问题的方法? – Ghost

0

我创建了一个名为LocationActivity

public class LocationActivitity extends AppCompatActivity 
      implements LocationListener, 
      GoogleApiClient.ConnectionCallbacks, 
      GoogleApiClient.OnConnectionFailedListener { 

     final String TAG = "GPS"; 
     private long UPDATE_INTERVAL = 2 * 1000; /* 10 secs */ 
     private long FASTEST_INTERVAL = 2000; /* 2 sec */ 
     static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; 

     GoogleApiClient gac; 
     LocationRequest locationRequest; 
     public String tvLatitude, tvLongitude, tvTime; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      isGooglePlayServicesAvailable(); 

      if(!isLocationEnabled()) 
       showAlert(); 

      locationRequest = new LocationRequest(); 
      locationRequest.setInterval(UPDATE_INTERVAL); 
      locationRequest.setFastestInterval(FASTEST_INTERVAL); 
      locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
      gac = new GoogleApiClient.Builder(this) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } 

     @Override 
     protected void onStart() { 
      gac.connect(); 
      super.onStart(); 
     } 

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

     @Override 
     public void onLocationChanged(Location location) { 
      if (location != null) { 
       updateUI(location); 
      } 
     } 

     @Override 
     public void onConnected(@Nullable Bundle bundle) { 
      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
        != PackageManager.PERMISSION_GRANTED 
        && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) 
        != PackageManager.PERMISSION_GRANTED) { 
       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
         MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); 

       return; 
      } 
      Log.d(TAG, "onConnected"); 

      Location ll = LocationServices.FusedLocationApi.getLastLocation(gac); 
      Log.d(TAG, "LastLocation: " + (ll == null ? "NO LastLocation" : ll.toString())); 

      LocationServices.FusedLocationApi.requestLocationUpdates(gac, locationRequest, this); 
     } 

     @Override 
     public void onRequestPermissionsResult(
       int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 

      switch (requestCode) { 
       case MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: { 
        // If request is cancelled, the result arrays are empty. 
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
         Toast.makeText(this, "Permission was granted!", Toast.LENGTH_LONG).show(); 

         try{ 
          LocationServices.FusedLocationApi.requestLocationUpdates(
            gac, locationRequest, this); 
         } catch (SecurityException e) { 
          Toast.makeText(this, "SecurityException:\n" + e.toString(), Toast.LENGTH_LONG).show(); 
         } 
        } else { 
         Toast.makeText(this, "Permission denied!", Toast.LENGTH_LONG).show(); 
        } 
        return; 
       } 
      } 
     } 

     @Override 
     public void onConnectionSuspended(int i) {} 

     @Override 
     public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
      Toast.makeText(this, "onConnectionFailed: \n" + connectionResult.toString(), 
        Toast.LENGTH_LONG).show(); 
      Log.d("DDD", connectionResult.toString()); 
     } 

     private void updateUI(Location loc) { 
      Log.d(TAG, "updateUI"); 
      tvLatitude=loc.getLatitude()+""; 
      tvLongitude=loc.getLongitude()+""; 
      //tvTime.setText(DateFormat.getTimeInstance().format(loc.getTime())); 
     } 

     private boolean isLocationEnabled() { 
      LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
      return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || 
        locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     } 

     private boolean isGooglePlayServicesAvailable() { 
      final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; 
      GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); 
      int resultCode = apiAvailability.isGooglePlayServicesAvailable(this); 
      if (resultCode != ConnectionResult.SUCCESS) { 
       if (apiAvailability.isUserResolvableError(resultCode)) { 
        apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST) 
          .show(); 
       } else { 
        Log.d(TAG, "This device is not supported."); 
        finish(); 
       } 
       return false; 
      } 
      Log.d(TAG, "This device is supported."); 
      return true; 
     } 

     private void showAlert() { 
      final AlertDialog.Builder dialog = new AlertDialog.Builder(this); 
      dialog.setTitle("Enable Location") 
        .setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " + 
          "use this app") 
        .setPositiveButton("Location Settings", new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface paramDialogInterface, int paramInt) { 

          Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
          startActivity(myIntent); 
          finish(); 
         } 
        }) 
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface paramDialogInterface, int paramInt) { 
         } 
        }); 
      dialog.show(); 
     } 
    } 

下面类的方法updateUI(位置LOC)你在哪里得到的位置。

相关问题