Bear with me, I am a good java developer, but I have been learning android for only one month. I am currently creating an app, where one key element of the app is to share your current location with the help of Google API location services.
I found this nice guide on how to get started with the location concept in android. Some may argue it is a little outdated, as its 2 years old now, but I thought I might give it a shot anyway.
Even though I love much about android studio, I have ran into so many complicated problems, that I almost feel like giving up. For example the builder complained that I have more than 64k method references, I looked up the problem, and found a workaround with a one liner in my gradle file. Later I faced a problem with heap allocation, and again I had to just paste in this one liner so that more space was allocated for my app(no where is this feature explained, you are just supposed to throw it in!).
At last my app is up and running on my phone, but instead of showing me a nice map with a marker of my current location, all I see is a white screen with the google text in the bottom left corner. All I can do is wonder, what is wrong?
A list of what has been done:
-I have the API-key, and put it correctly in my manifest -I followed the step-by-step guide closely -I have tried debugging with logcat by using Log and tagging every method
My last hope is to share this with you guys, and hope that some more experienced guys will point out my error(s)!
So here it goes.
Here is the MapsActivity class:
Imports...
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
LocationListener
{
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
public static final String TAG = MapsActivity.class.getSimpleName();
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
}
@Override
protected void onResume()
{
super.onResume();
mGoogleApiClient.connect();
}
@Override
protected void onPause()
{
super.onPause();
if (mGoogleApiClient.isConnected())
{
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.i(TAG, "Location services connected");
try
{
//if we get permissions from user to use this service, this will be executed
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null)
{
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
else
{
handleNewLocation(location);
};
}
catch(SecurityException e)
{
//here we did not get the permission
Log.i(TAG, "Did not get permissions");
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services suspended. Please reconnect");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try
{
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
}
catch (IntentSender.SendIntentException e)
{
e.printStackTrace();
}
}
else
{
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
private void handleNewLocation(Location location)
{
Log.d(TAG, "heresthelocation "+location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!");
mMap.addMarker(options);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
@Override
public void onLocationChanged(Location location)
{
handleNewLocation(location);
}
}
And if needed, here is my androidmanifest:
<?xml version="1.0" encoding="utf-8"?>
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"></activity>
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_login">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
</application>