I'm making an app that tracks the user's location and ultimatly uploads it to a Firebase server.
I have created a simple app that displays the location when I press a button on screen. The problem is that it doesnt change the location when I press it again after I walked a few meters (I do get a new location when I re-enter the app though). What do I need to add in order for the app to update the location every X seconds? This is my activity:
package com.example.gpstest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
public class MainActivity extends AppCompatActivity {
private FusedLocationProviderClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
client = LocationServices.getFusedLocationProviderClient(this);
Button button = findViewById(R.id.getLocation);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
return;
}
client.getLastLocation().addOnSuccessListener(MainActivity.this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location != null){
TextView lat = findViewById(R.id.location1);
TextView lon = findViewById(R.id.location2);
TextView alt = findViewById(R.id.location3);
lat.setText(Double.toString(location.getLatitude()));
lon.setText(Double.toString(location.getLongitude()));
alt.setText(Double.toString(location.getAltitude()));
}
}
});
}
});
}
private void requestPermission(){
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);
}
}
Because you get the location from getLastLocation. For that you have to implement LocationCallback.
consider this link for more information
// implement these interface in your class
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener.
//than use this code
public void onConnected(Bundle bundle) {
Location mLastLocation = null;
if (mGoogleApiClient.isConnected()) {
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
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more precise.
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
}
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000); //5 seconds
mLocationRequest.setFastestInterval(3000); //3 seconds
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setSmallestDisplacement(0.1F); //1/10 meter
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
buildGoogleApiClient();
mGoogleApiClient.connect();
}
}
Related
I'm currently doing a GPS App from FreeCodeCamp.Org Youtube Channel, "How to make A GPS Tracking App" https://www.youtube.com/watch?v=_xUcYfbtfsI&t=1774s . I did everything in the video, and the instructions, but every time I pressed the see way point list, it keep crashing. I need help to fix this. I dont know what's wrong with the code.
package com.example.gipies;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static final int DEFAULT_UPDATE_INTERVAL = 30;
public static final int FAST_UPDATE_INTERVAL = 5;
public static final int PERMISSION_FINE_LOCATION = 99;
//Refrensi Element UI
TextView tv_lat, tv_lon, tv_altitude, tv_accuracy, tv_speed, tv_sensor, tv_updates, tv_address,tv_wayPointCounts;
Button btn_newWP, btn_showWayPointList,btn_showMap;
#SuppressLint("UseSwitchCompatOrMaterialCode")
Switch sw_locationupdates, sw_gps;
//Variable to Remember to Track
boolean updateOn = false;
//Current Locaton
Location currentLocation;
//List of Saved
List<Location> savedLocations;
//Location Request configs of FusedLocationProviderClient
LocationRequest locationRequest;
LocationCallback locationCallBack;
//Google API for Location Services
private FusedLocationProviderClient fusedLocationProviderClient;
Object FusedLocationProviderClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Nilai Variable UI
tv_lat = findViewById(R.id.tv_lat);
tv_lon = findViewById(R.id.tv_lon);
tv_altitude = findViewById(R.id.tv_altitude);
tv_accuracy = findViewById(R.id.tv_accuracy);
tv_speed = findViewById(R.id.tv_speed);
tv_sensor = findViewById(R.id.tv_sensor);
tv_updates = findViewById(R.id.tv_updates);
tv_address = findViewById(R.id.tv_address);
sw_gps = findViewById(R.id.sw_gps);
sw_locationupdates = findViewById(R.id.sw_locationsupdates);
btn_newWP = findViewById(R.id.btn_newWP);
btn_showWayPointList= findViewById(R.id.btn_showWayPointList);
btn_showMap = findViewById(R.id.btn_showMap);
tv_wayPointCounts = findViewById(R.id.tv_CountOfPoints);
FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
//Set all Properties of LR
locationRequest = new LocationRequest();
locationRequest.setInterval(1000 * DEFAULT_UPDATE_INTERVAL);
locationRequest.setFastestInterval(1000 * FAST_UPDATE_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
locationCallBack = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
//Save Location
Location location = locationResult.getLastLocation();
updateUIValues(location);
}
};
btn_newWP.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//get GPS Location
// add New Location
MyApplication myApplication = (MyApplication)getApplicationContext();
savedLocations = myApplication.getMyLocations();
savedLocations.add(currentLocation);
}
});
btn_showWayPointList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, ShowSavedLocList.class);
startActivity(i);
}
});
btn_showMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this,MapsActivity.class);
startActivity(i);
}
});
sw_gps.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View v) {
if (sw_gps.isChecked()) {
//GPS Accurate
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
tv_sensor.setText("Using GPS Sensor");
} else {
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
tv_sensor.setText("Using WIFI");
}
}
});
sw_locationupdates.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (sw_locationupdates.isChecked()) {
//Turned On Location Tracking
startLocationUpdates();
} else {
//Turned Off Tracking
stopLocationUpdates();
}
}
});
updateGPS();
}//END onCreate
#SuppressLint("SetTextI18n")
private void stopLocationUpdates() {
tv_updates.setText("Location is NOT Being Tracked");
tv_lat.setText("Not tracking");
tv_lon.setText("Not Tracking");
tv_speed.setText("Not Tracking");
tv_address.setText("Not Tracking");
tv_accuracy.setText("Not Tracking");
tv_altitude.setText("Not Tracking");
tv_sensor.setText("Not Tracking");
LocationCallback.FusedLocationProviderClient.RemoveLocationUpdates(locationCallBack);
}
#SuppressLint("SetTextI18n")
private void startLocationUpdates() {
tv_updates.setText("Location is Being Tracked");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
FusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallBack, null);
updateGPS();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[]grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case PERMISSION_FINE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
updateGPS();
}
else{
Toast.makeText(this,"The APP Needs Permissions",Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void updateGPS(){
//Permissions, Current Location, Update UI
FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MainActivity.this);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
FusedLocationProviderClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
updateUIValues(location);
Location currentLocation = location;
}
});
}
else {
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_FINE_LOCATION);
}
}
}
private void updateUIValues(Location location) {
//Update All Text with New Location
tv_lat.setText(String.valueOf(location.getLatitude()));
tv_lon.setText(String.valueOf(location.getLongitude()));
tv_accuracy.setText(String.valueOf(location.getAccuracy()));
if(location.hasAltitude()){
tv_altitude.setText(String.valueOf(location.getAltitude()));
}
else{
tv_altitude.setText("Not Available");
}
if (location.hasSpeed()){
tv_speed.setText(String.valueOf(location.getAltitude()));
}
else{
tv_speed.setText("Not Available");
}
Geocoder geocoder = new Geocoder(MainActivity.this);
try{
List<Address>addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
tv_address.setText(addresses.get(0).getAddressLine(0));
}
catch ( Exception e){
tv_address.setText("Unable to find");
}
MyApplication myApplication = (MyApplication)getApplicationContext();
savedLocations = myApplication.getMyLocations();
//Show Number of WPs
tv_wayPointCounts.setText(Integer.toString(savedLocations.size()));
}
}
in MainActivity.Java
it said
Cannot Resolve symbol 'FusedLocationProviderClient'
Cannot resolve method 'requestLocationUpdates' in 'Object'
Cannot resolve method 'getLastLocation' in 'Object'
I'm writing an application that among other things should draw a map with the current device position and a remote point.
I started from the example created by Android Studio (Google->Google Map Activity).
I just add the code to get the current location:
package it.tux.mapper.activities;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.material.snackbar.Snackbar;
import java.util.Objects;
import it.tux.mapper.R;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, ActivityCompat.OnRequestPermissionsResultCallback, LocationListener {
private static final int PERMISSION_REQUEST_LOCATION = 11;
private static final int LOCATION_UPDATE_DELAY = 1000;
private final String gps_provider = LocationManager.GPS_PROVIDER;
private GoogleMap map;
private Location location;
private LocationManager location_manager;
private View layout;
#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);
if (mapFragment != null)
mapFragment.getMapAsync(this);
//USER CODE
layout = findViewById(R.id.map);
assert layout != null;
location = new Location(getString(R.string.location_provider));
location.isFromMockProvider();
initLocalization();
//
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_LOCATION) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar.make(layout, R.string.fine_location_access_granted, Snackbar.LENGTH_SHORT).show();
startLocalization();
} else {
Snackbar.make(layout, R.string.denied_fine_location_access_rationale, Snackbar.LENGTH_SHORT).show();
}
}
}
/**
* 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) {
map = googleMap;
}
#Override
public void onLocationChanged(Location location) {
this.location.set(location);
if (map != null) {
LatLng base = new LatLng(location.getLatitude(), location.getLongitude());
map.addMarker(new MarkerOptions().position(base).title(getString(R.string.destination_base_label)));
map.moveCamera(CameraUpdateFactory.newLatLng(base));
}
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
return;
}
#Override
public void onProviderEnabled(String s) {
return;
}
#Override
public void onProviderDisabled(String s) {
return;
}
private void requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
Snackbar.make(layout, R.string.denied_fine_location_access_rationale,
Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok, new View.OnClickListener() {
#Override
public void onClick(View view) {
ActivityCompat.requestPermissions(MapsActivity.this,
new String[]{Manifest.permission.CAMERA},
PERMISSION_REQUEST_LOCATION);
}
}).show();
} else {
Snackbar.make(layout, R.string.denied_fine_location_access_warning, Snackbar.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_LOCATION);
}
}
private void initLocalization() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
Snackbar.make(layout,
R.string.fine_location_access_granted,
Snackbar.LENGTH_SHORT).show();
startLocalization();
} else {
requestLocationPermission();
}
}
#SuppressLint("MissingPermission")
private void startLocalization() {
try {
location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!location_manager.isProviderEnabled(gps_provider)) {
Intent gpsOptionsIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(gpsOptionsIntent);
} else {
location_manager.requestLocationUpdates(gps_provider, LOCATION_UPDATE_DELAY, 2, this);
}
} catch (Throwable e) {
Log.e(getClass().getName(), "Exception: " + e.getMessage());
}
}
}
The code seems to work, i.e. no exceptions are triggered and onMapReady, onLocationChanged and onRequestPermissionsResult events are correctly fired.
The map is just empty. And the use count of the Api key is 0.
The manifest has the correct permission entries:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
And also the GoogleApi key is correctly set (I have a developer account):
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
Where's my error?
The problem seems to be related to the internet connection used to make the first connection to google api service. Under certain firewall the connection is probably blocked preventing a successful authorization. Changing the connection fixed this issue but I probably need to investigate deeply the API auth mechanism.
I've set the setInterval to 10 seconds, and the setFastestInterval to 1 second, but the app doesn't update the address location. It's only loaded once.
I want it to be loaded more than once. Should I put the mLocationProvider in a loop?
Thanks for any help.
MainActivity:
public class MainActivity extends AppCompatActivity implements LocationProvider.LocationCallback {
private LocationProvider mLocationProvider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find my location
mLocationProvider = new LocationProvider(this, this);
}
public void handleNewLocation(Location location) {
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
float currentAccuracy = location.getAccuracy();
}
}
LocationProvider:
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class LocationProvider implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
public abstract interface LocationCallback {
public void handleNewLocation(Location location);
}
public static final String TAG = LocationProvider.class.getSimpleName();
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationCallback mLocationCallback;
private Context mContext;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
public LocationProvider(Context context, LocationCallback callback) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationCallback = callback;
// 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
mContext = context;
}
public void connect() {
mGoogleApiClient.connect();
}
public void disconnect() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Location services connected.");
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
Toast.makeText(mContext, "Permission missing", Toast.LENGTH_LONG).show();
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
else {
mLocationCallback.handleNewLocation(location);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution() && mContext instanceof Activity) {
try {
Activity activity = (Activity)mContext;
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
mLocationCallback.handleNewLocation(location);
}
}
Ive read https://developer.android.com/training/location/receive-location-updates but it didn't help me much.
I'm currently making an app for school.. my app functions specifically for sending users most accurate location via SMS. so I used fused location api ... but now I don't know how to incorporate the SMS manager on my current app ... at present I only built a simple app which shows the users current location by pressing a button
I just want help on how to incorporate SMS manager in my app.
I also want the message to be in a URL form plus the coordinates so that it will be easy for the receiver to track the user.
here is my code Main activity
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 2300;
TextView textView;
Button sosbtn;
FusedLocationProviderClient fusedLocationProviderClient;
LocationRequest locationRequest;
LocationCallback locationCallback;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE: {
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
}
}
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
sosbtn = (Button) findViewById(R.id.sosbtn);
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);
} else {
buildLocationRequest();
buildLocationCallBack();
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
sosbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);
return;
}
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
}
});
}
}
private void buildLocationCallBack() {
locationCallback= new LocationCallback()
{
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
for(Location location:locationResult.getLocations())
textView.setText(String.valueOf(location.getLatitude())+"/"+String.valueOf(location.getLongitude()));
}
};
}
private void buildLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(3000);
locationRequest.setSmallestDisplacement(5);
}
}
your help will be greatly appreciated.
Here's an example, declare the location object as a private field and on the click of your button:
SmsManager smsManager = SmsManager.getDefault ();
String message = "My location: https://www.google.com/maps/#?api=1&map_action=map¢er=" + location.getLatitude () + "," + location.getLongitude ();
String phoneNumber = "+1....";
smsManager.sendTextMessage (phoneNumber, null, message, null, null);
The above link should redirect your recipient to google maps.
SmsManager.sendTextMessage
Don't forget to add this permission in your manifest:
<uses-permission android:name="android.permission.SEND_SMS"/>
and request the send sms permission in runtime.
I am trying to make a Google map show nearby places using retrofit following this tutorial.
I get this error:
Error:(158, 46) error: is not abstract and does not
override abstract method onFailure(Call,Throwable) in
Callback
Error:(159, 13) error: method does not override or implement a method
from a supertype
I tried to implement methods using the alt + enter, but it gets different from the tutorial, and it messes up the code.
Here is my main (it's the same from the tutorial)
MapsActivity.java
package example.googlemapsapp;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.HashMap;
import example.googlemapsapp.POJO.Example;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
double latitude;
double longitude;
private int PROXIMITY_RADIUS = 10000;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
//show error dialog if Google Play Services not available
if (!isGooglePlayServicesAvailable()) {
Log.d("onCreate", "Google Play Services not available. Ending Test case.");
finish();
}
else {
Log.d("onCreate", "Google Play Services available. Continuing.");
}
// 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);
}
private boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if(result != ConnectionResult.SUCCESS) {
if(googleAPI.isUserResolvableError(result)) {
googleAPI.getErrorDialog(this, result,
0).show();
}
return false;
}
return true;
}
/**
* 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;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
Button btnRestaurant = (Button) findViewById(R.id.btnRestaurant);
btnRestaurant.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
build_retrofit_and_get_response("restaurant");
}
});
Button btnHospital = (Button) findViewById(R.id.btnHospital);
btnHospital.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
build_retrofit_and_get_response("hospital");
}
});
Button btnSchool = (Button) findViewById(R.id.btnSchool);
btnSchool.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
build_retrofit_and_get_response("school");
}
});
}
private void build_retrofit_and_get_response(String type) {
String url = "https://maps.googleapis.com/maps/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitMaps service = retrofit.create(RetrofitMaps.class);
Call<Example> call = service.getNearbyPlaces(type, latitude + "," + longitude, PROXIMITY_RADIUS);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Response<Example> response, Retrofit retrofit) {
try {
mMap.clear();
// This loop will go through all the results and add marker on each location.
for (int i = 0; i < response.body().getResults().size(); i++) {
Double lat = response.body().getResults().get(i).getGeometry().getLocation().getLat();
Double lng = response.body().getResults().get(i).getGeometry().getLocation().getLng();
String placeName = response.body().getResults().get(i).getName();
String vicinity = response.body().getResults().get(i).getVicinity();
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(lat, lng);
// Position of Marker on Map
markerOptions.position(latLng);
// Adding Title to the Marker
markerOptions.title(placeName + " : " + vicinity);
// Adding Marker to the Camera.
Marker m = mMap.addMarker(markerOptions);
// Adding colour to the marker
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
// move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
Log.d("onLocationChanged", "entered");
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
latitude = location.getLatitude();
longitude = location.getLongitude();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
// Adding colour to the marker
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
// Adding Marker to the Map
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
Log.d("onLocationChanged", String.format("latitude:%.3f longitude:%.3f", latitude, longitude));
Log.d("onLocationChanged", "Exit");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
// contacts-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other permissions this app might request.
// You can add here other case statements according to your requirement.
}
}
}
The signature of onResponse differs from what you have.
You have:
public void onResponse( Response<Example> response, Retrofit retrofit)
It should be:
public void onResponse(Call<Example> call, Response<Example> response)
Your onFailure also needs to take a Call parameter:
public void onFailure(Call<Example> call, Throwable t)
It's possible the signatures of the methods have changed between versions of Retrofit, and that the tutorial is using an older version than you are. But I'm only speculating.
It's very easy to diagnose: Just read the error message and understand it:
It says that you are trying to sublcass the CallBack interface, so you have to override all the methods it declares. But you are not; because you have not overrided right the onFailure(Call<T> call, Throwable t) method.
See? You missed to add the call parameter in the onFailure method.
Do not trust so tightly on tutorials; use it as a basis, not as a Gospel. Maybe that tutorial is based on a prior version of Retrofit. (Or it maybe contains mistakes).