2015-09-13 163 views
3

我有一個應用程序需要用戶的位置,我是新的實施谷歌的位置服務。 我做了一個單獨的java類來處理與獲取位置有關的東西,然後在活動中使用位置信息來顯示位置(到目前爲止),但在我的活動中,經緯度的默認值爲0。Android應用程序未收到位置

這裏的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:發揮服務:7.8.0」 到的build.gradle(模塊:應用程序) - >下的依賴關係,並要求對清單的權限。謝謝!

+0

你能在模擬器上模擬地點? – user5292387

+0

我使用的是真實設備,nexus 7和sony xperia –

回答

3

問題1:

你不是叫connect()上mGoogleApiClient。

您需要調用以連接爲onConnected()被調用:

public CommentLocation(Context context){ 
    buildGoogleApiClient(context); 
    mGoogleApiClient.connect(); //added 
} 

問題2:

它看起來像你只使用getLastLocation()。這可能適合您的需求,但如果您需要一個位置,此方法不保證給出。 getLastLocation()方法可以並且將返回null。主要問題是它不會提示操作系統請求新的位置鎖定,而只是檢查是否存在來自某個其他應用的位置請求的最後一個已知位置。如果最近沒有其他應用程序發出位置請求,則會返回給您的空位置。

保證你實際上得到一個位置,唯一的辦法是要求之一,這與呼叫做requestLocationUpdates()。

問題3:

由於它需要時間來連接到谷歌API客戶,時間可能會關閉,即使你從getLastLocation()得到一個位置,你可能已經申請從你分段。

爲了解決這個問題,你可以使用一個BroadcastReceiver從CommentLocation類的片段發送位置。

需要注意的是,一般保持封裝的定位功能是一種更好的方法,但它的實現更多的工作。您可能想要使用更簡單的設計,其中位置功能位於與此Fragment關聯的Activity中。然後,您可以在有位置時調用碎片。

樣的活動代碼位置監聽器:

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(); 
    } 
} 
+0

問題1和問題2: 我添加了connect()函數,並且我使用了另一個使用位置獲取最後位置的應用程序,仍然返回的值爲0! 「 問題3: 」鑑於連接到Google Api Client需要時間,時間可能會關閉,即使您從getLastLocation()獲取位置,您可能已經從您的Fragment中請求了它。 「你能談談更多嗎?我不明白這個問題是什麼。我想要一個單獨的類來處理位置的原因是,我將在另外兩個活動中使用它,所以... 非常感謝 –

+0

@ashl確保將一些日誌放在onConnected()方法中,並將日誌放入getCommentLongitude( )和getCommentLatitude()方法。我猜這些是在onConnected()之前調用的,有機會檢查一個位置。日誌會告訴你他們被調用的順序,如果這是問題。 –

相關問題