I want my application work every time in background when gps turn on
e.g if closed application , still run
if press back still run
on resume still run
my application get current location and compare it by another lat and long to track client (user)
thanks very much
GPS_Service.class
public class GPS_Service extends Service {
private LocationListener listener;
private LocationManager locationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_update");
i.putExtra("lat", location.getLatitude());
i.putExtra("longg", location.getLongitude());
sendBroadcast(i);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager = (LocationManager)
getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//noinspection MissingPermission
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#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 Activity#requestPermissions for more details.
return;
}
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, listener);
}
#Override
public void onDestroy() {
super.onDestroy();
if(locationManager != null){
//noinspection MissingPermission
locationManager.removeUpdates(listener);
}
}
}
Activity.class
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap mMap;
LocationManager manager;
Marker marker;
private Circle mCircle;
private Marker mMarker;
Boolean Statein = true;
Boolean Stateout = true;
String phone;
double mLatitude;
double mLongitude;
double radiusInMeters;
private BroadcastReceiver broadcastReceiver;
#Override
protected void onResume() {
super.onResume();
if(broadcastReceiver == null) {
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Backendless.Data.of(Settings.class).find(new AsyncCallback<List<Settings>>() {
#Override
public void handleResponse(List<Settings> response) {
if (response.size() > 0) {
mLatitude = response.get(0).getLat();
mLongitude = response.get(0).getLong();
radiusInMeters = response.get(0).getRadius();
} else {
mLatitude = 21.467969;
mLongitude = 39.230361;
radiusInMeters = 50.0;
}
phone = getIntent().getStringExtra("phone");
float[] distance = new float[2];
Location.distanceBetween(intent.getExtras().getDouble("lat"), intent.getExtras().getDouble("longg"),
mLatitude, mLongitude, distance);
AlertDialog.Builder builder = new AlertDialog.Builder(MapsActivity.this, R.style.MyDialogTheme);
builder.setTitle("Location");
if (distance[0] > radiusInMeters) {
if (Stateout) {
Track track = new Track();
track.setPhone(phone);
track.setState("outside");
Backendless.Persistence.save(track, new AsyncCallback<Track>() {
#Override
public void handleResponse(Track response) {
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
//builder.setMessage("خارج المكان ، " + "المسافة: " + distance[0] + " متر ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر");
//builder.show();
//Toast.makeText(getBaseContext(), "خارج المكان ، " + "المسافة: " + distance[0] + " متر ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر", Toast.LENGTH_LONG).show();
Stateout = false;
Statein = true;
}
} else {
if (Statein) {
Track track = new Track();
track.setPhone(phone);
track.setState("inside");
Backendless.Persistence.save(track, new AsyncCallback<Track>() {
#Override
public void handleResponse(Track response) {
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
//builder.setMessage( "داخل المكان ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر");
//builder.show();
//Toast.makeText(getBaseContext(), "داخل المكان ، " + "قطر الدائرة: " + mCircle.getRadius() + " متر", Toast.LENGTH_LONG).show();
Statein = false;
Stateout = true;
}
}
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
}
};
}
registerReceiver(broadcastReceiver,new IntentFilter("location_update"));
}
#Override
protected void onDestroy() {
super.onDestroy();
if(broadcastReceiver != null){
unregisterReceiver(broadcastReceiver);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
Backendless.Data.of(Settings.class).find(new AsyncCallback<List<Settings>>() {
#Override
public void handleResponse(List<Settings> response) {
if (response.size() > 0) {
mLatitude = response.get(0).getLat();
mLongitude = response.get(0).getLong();
radiusInMeters = response.get(0).getRadius();
} else {
mLatitude = 21.467969;
mLongitude = 39.230361;
radiusInMeters = 50.0;
}
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(MapsActivity.this);
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
if(!runtime_permissions())
enable_service();
}\
private void drawMarkerWithCircle(LatLng position) {
int strokeColor = 0xffff0000; //red outline
int shadeColor = 0x44ff0000; //opaque red fill
CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8);
mCircle = mMap.addCircle(circleOptions);
MarkerOptions markerOptions = new MarkerOptions().position(position);
mMarker = mMap.addMarker(markerOptions);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Changing map type
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Showing / hiding your current location
mMap.setMyLocationEnabled(true);
// Enable / Disable zooming controls
mMap.getUiSettings().setZoomControlsEnabled(true);
// Enable / Disable my location button
mMap.getUiSettings().setMyLocationButtonEnabled(true);
// Enable / Disable Compass icon
mMap.getUiSettings().setCompassEnabled(true);
// Enable / Disable Rotate gesture
mMap.getUiSettings().setRotateGesturesEnabled(true);
// Enable / Disable zooming functionality
mMap.getUiSettings().setZoomGesturesEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLatitude, mLongitude), 17));
MarkerOptions options = new MarkerOptions();
options.position(new LatLng(mLatitude, mLongitude));
LatLng latLng = new LatLng(mLatitude, mLongitude);
drawMarkerWithCircle(latLng);
/* // 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.newLatLngZoom(sydney,10.2f));*/
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
private boolean runtime_permissions() {
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 100);
return true;
}
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
enable_service();
} else {
runtime_permissions();
}
}
}
private void enable_service() {
Intent i = new Intent(getApplicationContext(), GPS_Service.class);
startService(i);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.galalrabie.trackmap">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<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" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!--
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" />
<activity
android:name=".MapsActivity"
android:screenOrientation="portrait">
</activity>
<activity
android:name=".RegisterActivity"
android:screenOrientation="portrait" />
<activity
android:name=".LoginActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".GPS_Service"/>
</application>
</manifest>
it works only when open application and log in but in press back or in close it doesn't work
Related
hi everyone i'm trying to get the user's location, but when i ask for permissions google maps doesn't load. Specifically I have this error:
2022-07-03 12:46:39.032 12031-12031/com.example.progetto E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.progetto, PID: 12031
java.lang.SecurityException: my location requires permission ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION
at com.google.maps.api.android.lib6.impl.bj.J(:com.google.android.gms.dynamite_mapsdynamite#222413068#22.24.13 (100700-0):10)
at com.google.android.gms.maps.internal.i.ba(:com.google.android.gms.dynamite_mapsdynamite#222413068#22.24.13 (100700-0):172)
at et.onTransact(:com.google.android.gms.dynamite_mapsdynamite#222413068#22.24.13 (100700-0):4)
at android.os.Binder.transact(Binder.java:914)
at com.google.android.gms.internal.maps.zza.zzc(com.google.android.gms:play-services-maps##18.0.0:2)
at com.google.android.gms.maps.internal.zzg.setMyLocationEnabled(com.google.android.gms:play-services-maps##18.0.0:3)
at com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(com.google.android.gms:play-services-maps##18.0.0:1)
at com.example.progetto.MapsLine.onMapReady(MapsLine.java:207)
at com.google.android.gms.maps.zzat.zzb(com.google.android.gms:play-services-maps##18.0.0:1)
at com.google.android.gms.maps.internal.zzaq.zza(com.google.android.gms:play-services-maps##18.0.0:5)
at com.google.android.gms.internal.maps.zzb.onTransact(com.google.android.gms:play-services-maps##18.0.0:3)
at android.os.Binder.transact(Binder.java:914)
at es.bc(:com.google.android.gms.dynamite_mapsdynamite#222413068#22.24.13 (100700-0):2)
at com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.dynamite_mapsdynamite#222413068#22.24.13 (100700-0):1)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
My code is:
public class MapsLine extends Fragment implements OnMapReadyCallback {
private static final int MY_PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 0;
private FusedLocationProviderClient fusedLocationClient;
private LocationCallback locationCallback;
private boolean requestingLocationUpdates = true;
GoogleMap gMap;
double latitude;
double longitude;
#Override
public View onCreateView(#NonNull #NotNull LayoutInflater inflater, #Nullable #org.jetbrains.annotations.Nullable ViewGroup container, #Nullable #org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_maps_line, container, false);
}
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment supportMapFragment = (SupportMapFragment)
getChildFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(this);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("MainActivity", "onCreate");
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
//callback per gli aggiornamenti di posizione
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
Log.d("main_activiyt_maps", "location request is null");
return;
}
//aggiorno i dati nelle textView con le informazioni della posizione aggiornata
for (Location location : locationResult.getLocations()) {
Log.d("Location", "New Location received: " + location.toString());
latitude = location.getLatitude();
longitude=location.getLongitude();
Log.d("main_activiyt_maps", String.valueOf(latitude));
Log.d("main_activiyt_maps", String.valueOf(longitude));
}
}
};
}
#Override
public void onPause() {
super.onPause();
fusedLocationClient.removeLocationUpdates(locationCallback);
requestingLocationUpdates = false;
}
#Override
public void onResume() {
super.onResume();
Log.d("MainActivity", "onResume");
if (checkLocationPermission()) {
Log.d("MainActivity", "Permessi OK");
//richiedo l'ultima posizione
//richiedo aggiornamenti sulla posizione
startLocationUpdates();
}
}
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//ho i permessi, scrivo nella casella di testo che va tutto bene
Log.d("Location", "The permission is granted");
return true;
} else {
//non ho i permessi, devo richiederli
Log.d("Location", "Ask for permission");
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_REQUEST_ACCESS_FINE_LOCATION);
return false;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
Log.d("Location", "Now the permission is granted");
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
} else {
// permission was not granted
Log.d("Location", "Permission still not granted");
}
break;
}
}
}
public void getLastKnownLocation() {
if (checkLocationPermission()) {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
Log.d("Location", "Last known location:" + location.toString());
} else {
Log.d("Location", "Last Known location not available");
}
}
});
}
}
//per chiedere la posizione aggiornata
private void startLocationUpdates() {
if (checkLocationPermission()) {
requestingLocationUpdates = true;
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(1000); //in ms.
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
}
}
#SuppressLint("MissingPermission")
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
gMap = googleMap;
gMap.setMyLocationEnabled(true);
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(latitude,longitude);
gMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
gMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
gMap.clear(); //clear old markers
}
}
My themanifest code is:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="my_key" ></meta-data>
in the manifest I have ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION and in the code I check the permissions(checkLocationPermission()). why does it crash at the first start, when the app asks me for permissions?
In onViewCreated(), you are setting up your SupportMapFragment. In onMapReady(), you are trying to use location information via gMap.setMyLocationEnabled(true);. Do not call setMyLocationEnabled() until the user grants you permission.
I try to get current location when the app running in background, so I use service. However, the data does not change in background, the service does not work. I want to know the problem. Here is the code of the app.
MainActivity as follow:
public class MainActivity extends Activity {
Button btn_start;
private static final int REQUEST_PERMISSIONS = 100;
boolean boolean_permission;
TextView tv_latitude, tv_longitude, tv_address,tv_area,tv_locality;
SharedPreferences mPref;
SharedPreferences.Editor medit;
Double latitude,longitude;
Geocoder geocoder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start = (Button) findViewById(R.id.btn_start);
tv_address = (TextView) findViewById(R.id.tv_address);
tv_latitude = (TextView) findViewById(R.id.tv_latitude);
tv_longitude = (TextView) findViewById(R.id.tv_longitude);
tv_area = (TextView)findViewById(R.id.tv_area);
tv_locality = (TextView)findViewById(R.id.tv_locality);
geocoder = new Geocoder(this, Locale.getDefault());
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
medit = mPref.edit();
btn_start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (boolean_permission) {
if (mPref.getString("service", "").matches("")) {
medit.putString("service", "service").commit();
Intent intent = new Intent(getApplicationContext(), GoogleService.class);
startService(intent);
} else {
Toast.makeText(getApplicationContext(), "Service is already running", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "Please enable the gps", Toast.LENGTH_SHORT).show();
}
}
});
fn_permission();
}
private void fn_permission() {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION))) {
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION
},
REQUEST_PERMISSIONS);
}
} else {
boolean_permission = true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSIONS: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
latitude = Double.valueOf(intent.getStringExtra("latitude"));
longitude = Double.valueOf(intent.getStringExtra("longitude"));
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
String cityName = addresses.get(0).getAddressLine(0);
String stateName = addresses.get(0).getAddressLine(1);
String countryName = addresses.get(0).getAddressLine(2);
tv_area.setText(addresses.get(0).getAdminArea());
tv_locality.setText(stateName);
tv_address.setText(countryName);
} catch (IOException e1) {
e1.printStackTrace();
}
tv_latitude.setText(latitude+"");
tv_longitude.setText(longitude+"");
tv_address.getText();
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(GoogleService.str_receiver));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
Service as follow:
public class GoogleService extends Service implements LocationListener{
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude,longitude;
LocationManager locationManager;
Location location;
private Handler mHandler = new Handler();
private Timer mTimer = null;
long notify_interval = 1000;
public static String str_receiver =
"com.findmyelderly.findmyelderly.receiver";
Intent intent;
public GoogleService() {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mTimer = new Timer();
mTimer.schedule(new TimerTaskToGetLocation(),5,notify_interval);
intent = new Intent(str_receiver);
// fn_getlocation();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
private void fn_getlocation() {
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnable && !isNetworkEnable) {
} else {
if (isNetworkEnable) {
location = null;
try {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
if (isGPSEnable) {
location = null;
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
}
private class TimerTaskToGetLocation extends TimerTask {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
fn_getlocation();
}
});
}
}
private void fn_update(Location location){
intent.putExtra("latutide",location.getLatitude()+"");
intent.putExtra("longitude",location.getLongitude()+"");
sendBroadcast(intent);
}
}
build.gradle as follow
.........
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.google.android.gms:play-services-location:10.0.1'
compile 'com.android.support:multidex:1.0.0'
AndroidManifest as follow
..........
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
.........
<service android:name=".GoogleService" android:exported="false" android:enabled="true"/>
</application>
</manifest>
I am very puzzled.
One thing you could try is to check the permissions of the app on the phone itself. I've found with my device (Android version 6.0.1) it's not enough to just add "uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> and
"uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />"
in the manifest, you have to grant permissions to the app manually on the device.
To do this, go to Settings > Apps > 'yourApp' > Permissions and slide across the bar to turn on Location for that app.
I'm new enough to Android apps myself so there may be a bigger problem in your case I'm not sure but worth a try anyway!
I am using google play service for a running app i am making. I am getting the problem that onlocationchanged is not being called. First i though it was the android device that was not working but after testing it with GPS test it seems the device was working as it should. So it must be my code. Onlocationchanged is just not being called by the gps_provider but when i use network_provider it is working but the updates are so slow and in accurate that you can't build a sport runner app with it.
This is my code, what should i do to fix this?
this is in my manifest
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.befitdonate.befitdonate.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
This is my fragment i am using to track the users route on the map.
public class WorkoutActivity extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static String TAG = WorkoutActivity.class.getSimpleName();
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationRequest mLocationRequest;
MapView mapView;
GoogleMap map;
private GoogleApiClient mGoogleApiClient;
private SharedPreferences preferenceSettings;
private SharedPreferences.Editor preferenceEditor;
private static final int PREFERENCE_MODE_PRIVATE = 0;
private static final String PREF_NAME = "UserDetails";
public static final String POST_USEREMAIL = "username";
MainActivity mainactivity;
String emailUser, workoutType;
Button stopWorkout, startWorkout;
TextView speed, info;
ImageView workoutImage;
LinearLayout mapLayout, startWorkoutLayout;
Double currentLat, currentLong;
Double Lat, Longi;
String latLong = "No Location Found!!!";
LocationManager lManager;
final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
//counter that is incremented every time a new position is received, used to calculate average speed
int counter = 0;
//objects to store values for current and average speed
protected double currentSpeed;
protected double kmphSpeed;
protected double avgSpeed;
protected double avgKmph;
protected double totalSpeed;
protected double totalKmph;
ArrayList<LatLng> polylines;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferenceSettings = this.getActivity().getSharedPreferences(PREF_NAME, PREFERENCE_MODE_PRIVATE);
preferenceEditor = preferenceSettings.edit();
emailUser = preferenceSettings.getString("Email", null);
Log.d("Saved user email:", "" + emailUser);
Bundle bundle = this.getArguments();
if (bundle != null) {
workoutType = bundle.getString("workoutType");
}
mGoogleApiClient = new GoogleApiClient.Builder(this.getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(1 * 1000) // 5 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_workout, container, false);
mapView = (MapView) view.findViewById(R.id.mapview);
stopWorkout = (Button) view.findViewById(R.id.stopWorkout);
startWorkout = (Button) view.findViewById(R.id.startWorkout);
startWorkoutLayout = (LinearLayout) view.findViewById(R.id.startWorkoutLayout);
mapLayout = (LinearLayout) view.findViewById(R.id.mapLayout);
workoutImage = (ImageView) view.findViewById(R.id.workoutImage);
speed = (TextView) view.findViewById(R.id.speed);
info = (TextView) view.findViewById(R.id.info);
mapView.onCreate(savedInstanceState);
mainactivity = (MainActivity )getActivity();
mainactivity.menuButton.setVisibility(View.GONE);
mainactivity.mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mainactivity.pageTitle.setText("Workout");
mapLayout.setVisibility(View.GONE);
polylines = new ArrayList<LatLng>();
// Gets to GoogleMap from the MapView and does initialization stuff
map = mapView.getMap();
map.getUiSettings().setMyLocationButtonEnabled(false);
map.setMyLocationEnabled(true);
// Needs to call MapsInitializer before doing any CameraUpdateFactory calls
MapsInitializer.initialize(this.getActivity());
stopWorkout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectOption();
}
});
workoutType = "walking";
startWorkout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mapLayout.setVisibility(View.VISIBLE);
startWorkoutLayout.setVisibility(View.GONE);
}
});
if(workoutType.matches("running")){
Picasso.with(this.getActivity())
.load(R.drawable.newrun)
.fit()
.centerCrop()
.into(workoutImage);
}
if(workoutType.matches("cycling")){
Picasso.with(this.getActivity())
.load(R.drawable.newcycling)
.fit()
.centerCrop()
.into(workoutImage);
}
if(workoutType.matches("walking")){
Picasso.with(this.getActivity())
.load(R.drawable.newwalk)
.fit()
.centerCrop()
.into(workoutImage);
}
return view;
}
#Override
public void onDestroy() {
super.onDestroy();
mainactivity.mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
mapView.onResume();
mGoogleApiClient.connect();
}
#Override
public void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
//DO WHATEVER YOU WANT WITH GOOGLEMAP
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
map.setMyLocationEnabled(false);
map.setTrafficEnabled(false);
map.setIndoorEnabled(true);
map.setBuildingsEnabled(true);
map.getUiSettings().setZoomControlsEnabled(true);
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Log.d(TAG, "Location update running");
handleNewLocation(location);
}
public void selectOption() {
final CharSequence[] items = { "Workout Opslaan", "Afbreken", "Sluiten" };
AlertDialog.Builder builder = new AlertDialog.Builder(WorkoutActivity.this.getActivity());
builder.setTitle("Workout opties");
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Workout Opslaan")) {
} else if (items[item].equals("Afbreken")) {
mapView.onDestroy();
mainactivity.mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
mainactivity.menuButton.setVisibility(View.VISIBLE);
if (mGoogleApiClient.isConnected()) {
onDestroy();
}
Fragment fragment = new HomePage();
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.mainContent, fragment)
.commit();
} else if (items[item].equals("Sluiten")) {
dialog.dismiss();
}
}
});
builder.show();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "Location services connected.");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
else {
handleNewLocation(location);
};
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services suspended. Please reconnect.");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this.getActivity(), 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, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
Lat = location.getLatitude();
Longi = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
CameraUpdate zoom=CameraUpdateFactory.zoomTo(17);
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
map.animateCamera(zoom);
counter++;
//current speed of the gps device
currentSpeed = round(location.getSpeed(),3, BigDecimal.ROUND_HALF_UP);
kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP);
//all speeds added together
totalSpeed = totalSpeed + currentSpeed;
totalKmph = totalKmph + kmphSpeed;
//calculates average speed
avgSpeed = round(totalSpeed/counter,3,BigDecimal.ROUND_HALF_UP);
avgKmph = round(totalKmph/counter,3,BigDecimal.ROUND_HALF_UP);
//gets position
currentLatitude = round(((double) (location.getLatitude())),3,BigDecimal.ROUND_HALF_UP);
currentLongitude = round(((double) (location.getLongitude())),3,BigDecimal.ROUND_HALF_UP);
String infoDetails = "Afstand: "+" | Tijd: ";
String updateSpeed = String.valueOf(kmphSpeed);
Log.d(TAG, updateSpeed.toString());
//info.setText();
speed.setText("Snelheid: "+updateSpeed+" km/hr");
buildPolyline();
}
//Method to round the doubles to a max of 3 decimal places
public static double round(double unrounded, int precision, int roundingMode)
{
BigDecimal bd = new BigDecimal(unrounded);
BigDecimal rounded = bd.setScale(precision, roundingMode);
return rounded.doubleValue();
}
public void buildPolyline(){
Log.d(TAG,"Adding polyline" );
LatLng polyline;
polyline = new LatLng(Lat, Longi);
polylines.add(polyline);
Log.d("Locations Array", ""+polylines);
map.addPolyline(new PolylineOptions().addAll(polylines).width(6.0f).color(Color.BLUE));
//map.moveCamera(CameraUpdateFactory.newLatLngZoom(Start, 14));
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (map == null) {
// Try to obtain the map from the SupportMapFragment.
map = ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapview))
.getMap();
// Check if we were successful in obtaining the map.
if (map != null) {
}
}
}
}
I have spend about a week trying several solution but still stuck with this problem. I need an accurate way to track the route of the runner. I can't find any sport app samples, but enough other location samples but nothing seems to be working. I hope someone can help me with this.
Thanks
you have to use Location manager and register for location updates.
Try adding this code:
protected LocationManager locationManager;
in onCreate() method call registerLocationUpdates();
void registerLocationUpdates() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_HIGH);
locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);
provider = locationManager.getBestProvider(criteria, true);
// Cant get a hold of provider
if (provider == null) {
Log.v(TAG, "Provider is null");
showNoProvider();
return;
} else {
Log.v(TAG, "Provider: " + provider);
}
locationManager.requestLocationUpdates(provider, 0, 0, this);
}
I am trying to find last known location of device using GoogleApiClient, So I used fine level access, but getting following exception because location coming is null.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kuldeep.location2, PID: 1421
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at com.example.kuldeep.location2.MainActivity.onConnected(MainActivity.java:51)
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
try {
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
Toast.makeText(this, mLastLocation.getLatitude() + ", " + mLastLocation.getLongitude(), Toast.LENGTH_SHORT);
} catch (SecurityException e){
e.printStackTrace();
}
}
My manifest file is as follow :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.kuldeep.location2">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
</manifest>
First of all, getLastLocation() can be null so you be carefull acessing directly to mLastLocation without a "null" check. In second place, i suggest you to add in your manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
and then call a LocationRequest.
if(locRequest== null)
{
locRequest= new LocationRequest();
locRequest.setInterval( interval );
locRequest.setFastestInterval( fastestInterval );
locRequest.setPriority( priority );
LocationServices.FusedLocationApi.requestLocationUpdates(yourGoogleApiClient, locRequest, this);
}
Using GoogleApiClient find a CurrentLocation like these:
private GoogleApiClient googleApiClient;
private Location mLastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isCheckLocationServiceisOn(context);
if(googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
protected void onResume() {
super.onResume();
isCheckLocationServiceisOn(context);
}
#Override
public void onConnected(Bundle arg0) {
if(googleApiClient.isConnected()) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (mLastLocation != null) {
System.out.println("latiTude....."+ String.valueOf(mLastLocation.getLatitude()));
System.out.println("longiTude....."+ String.valueOf(mLastLocation.getLongitude()));
}
}
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
System.out.println("onConnectionFailed...."+ arg0.toString());
}
#Override
public void onConnectionSuspended(int arg0) {
System.out.println("onConnectionSuspended...."+ arg0);
}
Add Permission in manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Here,
Implements ConnectionCallbacks, OnConnectionFailedListener interface for that supported override methods they must be com.google.android.gms.common.api.GoogleApiClient package.
MUST REMEMBER:
Wi-Fi and GSM and GPS is must be on in device if not then generate these kind of error in onConnected()
I give you code to check & open location service also:
public static void isCheckLocationServiceisOn (final Context context) {
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
catch(Exception ex) {}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
catch(Exception ex) {}
if(!gps_enabled && !network_enabled) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setMessage("Location Services Disabled. \n Please enable location services.");
dialog.setPositiveButton("Enable", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
}
1.i enable android google map android api and google places Api for android
2.my google map is worked but when use Search place thats Not Work
this my code please help me
manifest:
<uses-sdk android:minSdkVersion="7" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="6" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="my API_KEY" />
google place avtivity :
public class GooglePlacesActivity extends FragmentActivity implements LocationListener {
private static final String GOOGLE_API_KEY = "my api key";
GoogleMap googleMap;
EditText placeText;
double latitude = 0;
double longitude = 0;
private int PROXIMITY_RADIUS = 5000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//show error dialog if GoolglePlayServices not available
if ( !isGooglePlayServicesAvailable()) {
finish();
}
setContentView(R.layout.activity_google_places);
placeText = (EditText) findViewById(R.id.placeText);
Button btnFind = (Button) findViewById(R.id.btnFind);
SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
googleMap = fragment.getMap();
googleMap.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(bestProvider);
if (location != null) {
onLocationChanged(location);
}
locationManager.requestLocationUpdates(bestProvider, 20000, 0, this);
btnFind.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String type = placeText.getText().toString();
StringBuilder googlePlacesUrl = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
googlePlacesUrl.append("location=" + latitude + "," + longitude);
googlePlacesUrl.append("&radius=" + PROXIMITY_RADIUS);
googlePlacesUrl.append("&types=" + "hospital");
googlePlacesUrl.append("&sensor=true");
googlePlacesUrl.append("&key=" + GOOGLE_API_KEY);
GooglePlacesReadTask googlePlacesReadTask = new GooglePlacesReadTask();
Object[] toPass = new Object[2];
toPass[0] = googleMap;
toPass[1] = googlePlacesUrl.toString();
googlePlacesReadTask.execute(toPass);
}
});
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
i cant find nearshearch place :(
try this.
<
meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR API KEY"/>
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
instead of
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="6" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="my API_KEY" />