My basic location application doesent work on my Galaxy A20 running API 29 but works fine on all my emuultors running the same API. im not sure what the problem could be as im not experianced with LOGCAT but the error states as following:
Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference.
THE ERROR IS ON LINE 117 on my project (At the end). But ive highlighted it here
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
LocationManager locationManager;
LocationListener locationListener;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1){
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
if (ContextCompat.checkSelfPermission(this , Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER ,0 ,0 , locationListener);
}
}
}
#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);
}
/**
* 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;
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.clear();
mMap.addMarker(new MarkerOptions().position(userLocation).title("Marker in user house"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(userLocation));
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
};
if (ContextCompat.checkSelfPermission(this , Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this , new String[]{Manifest.permission.ACCESS_FINE_LOCATION} , 1);
}
else{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER , 0 , 0 , locationListener);
Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
LatLng userLocation = new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()); // ◅ THE ERROR OCCOURS HERE********
mMap.clear();
mMap.addMarker(new MarkerOptions().position(userLocation).title("Marker in user house"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(userLocation));
}
}
}
Maybe your phone has not managed to get a GPS fix yet. Check if lastKnowLocation is null before using it, and test the app outside where your phone can "see" the sky.
Related
The first time I install this application, and when I launch MapsActivity, I am asked for permissions, which is normal. But the problem is that the application closes in the meantime. How can I modify my code to keep the application open, and the permission pop-up just overlaps. Thank you very much for your answer.
Error code in logcat :
2020-02-02 11:17:01.340 11559-11574/? E/le.rsr_pechhlu: Unable to peek into adb socket due to error. Closing socket.: Connection reset by peer
2020-02-02 11:17:01.470 11559-11636/? E/AwareLog: AtomicFileUtils: readFileLines file not exist: android.util.AtomicFile#2f88384
2020-02-02 11:17:01.470 11559-11636/? E/AwareLog: AtomicFileUtils: readFileLines file not exist: android.util.AtomicFile#7fa676d
2020-02-02 11:17:01.471 11559-11603/? E/MemoryLeakMonitorManager: MemoryLeakMonitor.jar is not exist!
2020-02-02 11:17:10.787 11559-11559/com.example.rsr_pechhlup E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.rsr_pechhlup, PID: 11559
java.lang.RuntimeException: Unable to pause activity {com.example.rsr_pechhlup/com.example.rsr_pechhlup.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.location.LocationManager.removeUpdates(android.location.LocationListener)' on a null object reference
at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:4742)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:4691)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4626)
at android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.location.LocationManager.removeUpdates(android.location.LocationListener)' on a null object reference
at com.example.rsr_pechhlup.MapsActivity.onPause(MapsActivity.java:159)
at android.app.Activity.performPause(Activity.java:7663)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1536)
at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:4726)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:4691)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4626)
at android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
public class MapsActivity extends FragmentActivity implements LocationListener {
private GoogleMap googleMap; //google map is contained in the fragment work on it to change the position of the map and so on.
private Marker marker;
private Button buttonCallNow;
private RelativeLayout callPanelWrapper;
private static final int PERMS_CALL_ID = 1234; //permission identifier, unique identifier
private static final int REQUEST_PHONE_CALL = 4321;
private LocationManager locationManager; // Android manager service of android platform.
private SupportMapFragment mapFragment;
private Utils utils;
private PhoneCallListener phoneCallListener;
private boolean firstTime;
private String adresse;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps2);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment= (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
}
/**
* //When the activity comes back to the foreground, I have to subscribe to the different location information providers, so I will receive the new location information and I will be able to resynchronize my mapping on this location.
*/
#Override
protected void onResume() {
super.onResume();
checkPermissions();
firstTime=true;
}
private void checkPermissions(){
//For older versions of android we check that the ACCES_FINE_LOCATION and ACCES_COARSE_LOCATION permissions are enabled.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION },PERMS_CALL_ID); //We must provide three parameters: it is the activity that requires the activation of these permissions (here it is this), then a table that specifies the set of permissions to allow. And we need a request code.
return;
}
locationManager= (LocationManager) getSystemService(LOCATION_SERVICE);//I ask android to give me that service locationManager. LOCATION SERVICE comes inheritance FragmentActivity, which inherits from Context, which contains this constant.
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){//If on this locationManager, a particular provider here : LocationManager.GPS_PROVIDER is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
if(locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)){//If on this locationManager, a particular provider here : LocationManager.PASIVE_PROVIDER is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){//If on this locationManager, a particular provider here : NETWORK is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
dispMap();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==PERMS_CALL_ID){ //This method will be activated each time a permission request is made. And to know where I'm coming from I need the requestCode. This request is coupled with this requestCode here.
checkPermissions(); //i call again chack permission do disp again pop-up permission.
}
}
/**
* //When my application leaves the foreground, I unsubscribe from the different providers of location information so as not to consume a lot of resources.
*/
#Override
protected void onPause() {
super.onPause();
//If the locationManager has been initialized, I make one of this, one of the earphone of all suppliers
locationManager.removeUpdates(this);
}
private void dispMap(){
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
MapsActivity.this.googleMap=googleMap;
marker = googleMap.addMarker(new MarkerOptions().position(new LatLng(43.799345,6.725426)));
}
});
}
/**
* React each time new positioning information is calculated
* #param location
*/
#Override
public void onLocationChanged(Location location) { //This location is obtained through the provider. Of course this can be any provider, GPS_PROVIDER is more accurate than PASSIVE_PROVIDER etc..
double latitude= location.getLatitude();//I'm getting the latitude.
double longitude=location.getLongitude();// I'm getting the longitude.
Toast.makeText(this, "Location: " + latitude + "/" + longitude,Toast.LENGTH_SHORT).show();
LatLng googleLocation=new LatLng(latitude,longitude);
if(firstTime){
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(googleLocation, 16.2f));
adresse= Utils.getCompleteAddressString(latitude, longitude,this);
BitmapDescriptor subwayBitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.map_marker);
marker = googleMap.addMarker(new MarkerOptions().position(googleLocation).icon(subwayBitmapDescriptor).title(adresse));
googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(this));
}
firstTime=false;
if(this.googleMap!=null){//If my map is correctly displayed
adresse = Utils.getCompleteAddressString(latitude, longitude,this);
googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(this));
marker.setTitle(adresse);
marker.setPosition(googleLocation);
marker.showInfoWindow();
}
}
/**
* To react to every change of state
* #param provider
* #param status
* #param extras
*/
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
/**
* When a location provider is closed.
* #param provider
*/
#Override
public void onProviderEnabled(String provider) {
}
/**
* When a location provider is closed.
* #param provider
*/
#Override
public void onProviderDisabled(String provider) {
}
public void btnBackClick(View view) {
Intent myIntent = new Intent(this, HomeActivity.class);
startActivity(myIntent);
}
public void btnCallMapclicked(View view) {
callPanelWrapper.setVisibility(View.VISIBLE);
buttonCallNow.setVisibility(View.GONE);
}
public void buttonFinalCallClicked(View view) {
call();
}
public void popupClosedClicked(View view) {
callPanelWrapper.setVisibility(View.GONE);
buttonCallNow.setVisibility(View.VISIBLE);
}
}
}
I'm not able to put comment,Thus forward my answer as post.
you may should describe about your problem more but do you add ACCESS_FINE_LOCATION and
ACCESS_COARSE_LOCATION to your Manifest file?
EDIT:
just change onPause to following:
#Override
protected void onPause() {
super.onPause();
if(locationManager != null) // add this line to your code
locationManager.removeUpdates(this);
}
Cause:
When Permission dialog has been shown your activity onPause() is called, and since you not initialize location manager yet, it throws NullPointerException.
Try this code to initialize map with required run time permission.
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleApiClient.OnConnectionFailedListener{
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onMapReady(GoogleMap googleMap) {
Toast.makeText(this, "Map is Ready", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onMapReady: map is ready");
mMap = googleMap;
if (mLocationPermissionsGranted) {
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
init();
}
}
private static final String TAG = "MapActivity";
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
//vars
private Boolean mLocationPermissionsGranted = false;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
getLocationPermission();
}
private void initMap(){
Log.d(TAG, "initMap: initializing map");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
}
private void getLocationPermission(){
Log.d(TAG, "getLocationPermission: getting location permissions");
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
mLocationPermissionsGranted = true;
initMap();
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult: called.");
mLocationPermissionsGranted = false;
switch(requestCode){
case LOCATION_PERMISSION_REQUEST_CODE:{
if(grantResults.length > 0){
for(int i = 0; i < grantResults.length; i++){
if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
mLocationPermissionsGranted = false;
Log.d(TAG, "onRequestPermissionsResult: permission failed");
return;
}
}
Log.d(TAG, "onRequestPermissionsResult: permission granted");
mLocationPermissionsGranted = true;
initMap(); // once permission granted then only initMap()
}
}
}
}
}
So i am doing a project that i only need to get the location, i don't need to show the map or anything like that. I created the GoogleMap mGoogleMap; in the beginning of the class. When asking for the permission of location and course to the user i have this code:
public class Distance extends Activity implements Runnable {
//...
GoogleMap mGoogleMap;
protected LocationManager locationManager;
Location location;
//...
public void onCreate(Bundle savedInstanceState) {
//...
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener()
);
} else {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION},
TAG_CODE_PERMISSION_LOCATION);
}
//...
The first time i ran the application it worked but the other times got this error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.setMyLocationEnabled(boolean)' on a null object reference.
That error is in the line that have: mGoogleMap.setMyLocationEnabled(true);
I know that i need to initialize the googleMap object because it is blank but i don't know how. Help?
Init the map this way:
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
// Add a marker in Sydney, Australia, and move the camera.
LatLng sydney = new LatLng(-34, 151);
mGoogleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
I have been working on an app which implements google maps. When I am on my homescreen and presses the "start map" button the message "Skipped 85 frames! The application may be doing too much work on its main thread." is shown in the Android Monitor. I have been looking around for a solution but have not been able to find one that works for me. Does anyone have any idea how to prevent this?
My maps activity:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
private boolean initiateApp;
double CO2data = 1.02;
double N2data = 0.002;
#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();
}
// 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);
initiateApp = 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);
}
}
/* Here we create the infoWindow **/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
public View getInfoWindow(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.custom_infowindow, null);
TextView tv = (TextView) v.findViewById(R.id.infoText);
tv.setText("CO2 data: "+String.valueOf(CO2data) +"\n" + "N2 data: "+String.valueOf(N2data));
return v;
}
public View getInfoContents(Marker arg0) {
return null;
}
});
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(2000);
mLocationRequest.setFastestInterval(2000);
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) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
Log.d("ADebugTag", "Value: " + Double.toString(location.getLatitude()));
Log.d("ADebugTag", "Value: " + Double.toString(location.getLongitude()));
//move map camera
if(initiateApp){
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
}
initiateApp = false;
boolean contains = mMap.getProjection()
.getVisibleRegion()
.latLngBounds
.contains(latLng);
if(!contains){
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
}
#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.
}
}
}
My maps XML
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.kasper.map_app.MapsActivity" />
Based from this thread, if you have a lot of code in your UI events then you will see this error message. Also this will occur with asynchronous events like fetching data from a URL. The workaround given is to use threads or async tasks.
You want to off load any heavy code off of your UI Threads and onto another area - a new thread or in your main activity.
Here are some SO posts which might also help:
The application may be doing too much work on its main thread
The application may be doing too much work on its main thread - Android
Hey Im new to Android and wondering if someone can help me. I have a MapsActivity which crashes when navigating to it. I think I've narrowed down to exactly where it is from looking through the errors but I cant figure out what to change.
I've added the whole MapsActivity class below. The problem is occuring in the onConnected method on this line mLocationManager.requestLocationUpdates(provider, 5000, 0, this);
. Android Studio recommends I cast 'this' to LocationListener but this doesn't work and the error I get from doing so is listed below the MapsActivity code.
I have also tried entering mLocationListener in the place of 'this' but doesn't work and I get errors which are listed below too.
ANY HELP IS GREATLY APPRECIATED. THANKS!
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private static final int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 2;
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private LocationManager mLocationManager;
private Location mLastLocation;
private LocationListener mLocationListener;
private String mLatitude;
private String mLongitude;
#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);
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
//create instance of location manager and get location service
mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
/**
* 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
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
//mLocationManager.removeUpdates((LocationManager) this);
super.onStop();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(true);
criteria.setBearingRequired(true);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = mLocationManager.getBestProvider(criteria, true);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager.requestLocationUpdates(provider, 5000, 0, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation != null){
mLatitude = String.valueOf(mLastLocation.getLatitude());
mLongitude = String.valueOf(mLastLocation.getLongitude());
Toast.makeText(this, mLatitude + " , " + mLongitude, Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Permission denied, please accept permission..", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults){
switch (requestCode){
case MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION:{
//if request cancelled the results array is empty
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//do task you wish to do
//Intent intent = (new Intent(this, MapsActivity.class));
//startActivity(intent);
}else{
//permission denied, disable functionality(GPS)
}
return;
}
//other cases go here
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
}
}
Casting errors -
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.a8460p.locationotes, PID: 23305
java.lang.ClassCastException: com.example.a8460p.locationotes.MapsActivity cannot be cast to android.location.LocationListener
at com.example.a8460p.locationotes.MapsActivity.onConnected(MapsActivity.java:106)
at com.google.android.gms.common.internal.zzm.zzq(Unknown Source)
at com.google.android.gms.internal.zzaal.zzo(Unknown Source)
at com.google.android.gms.internal.zzaaj.zzvE(Unknown Source)
at com.google.android.gms.internal.zzaaj.onConnected(Unknown Source)
at com.google.android.gms.internal.zzaan.onConnected(Unknown Source)
at com.google.android.gms.internal.zzzy.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzl$1.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzf$zzj.zzwZ(Unknown Source)
at com.google.android.gms.common.internal.zzf$zza.zzc(Unknown Source)
at com.google.android.gms.common.internal.zzf$zza.zzu(Unknown Source)
at com.google.android.gms.common.internal.zzf$zze.zzxa(Unknown Source)
at com.google.android.gms.common.internal.zzf$zzd.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:234)
at android.app.ActivityThread.main(ActivityThread.java:5526)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Replacing 'this' with mLocationListener errors -
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.a8460p.locationotes, PID: 24073
java.lang.IllegalArgumentException: invalid listener: null
at android.location.LocationManager.checkListener(LocationManager.java:1733)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:461)
at com.example.a8460p.locationotes.MapsActivity.onConnected(MapsActivity.java:106)
at com.google.android.gms.common.internal.zzm.zzq(Unknown Source)
at com.google.android.gms.internal.zzaal.zzo(Unknown Source)
at com.google.android.gms.internal.zzaaj.zzvE(Unknown Source)
at com.google.android.gms.internal.zzaaj.onConnected(Unknown Source)
at com.google.android.gms.internal.zzaan.onConnected(Unknown Source)
at com.google.android.gms.internal.zzzy.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzl$1.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzf$zzj.zzwZ(Unknown Source)
at com.google.android.gms.common.internal.zzf$zza.zzc(Unknown Source)
at com.google.android.gms.common.internal.zzf$zza.zzu(Unknown Source)
at com.google.android.gms.common.internal.zzf$zze.zzxa(Unknown Source)
at com.google.android.gms.common.internal.zzf$zzd.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:234)
at android.app.ActivityThread.main(ActivityThread.java:5526)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Make MapsActivity implements android.location.LocationListener instead of com.google.android.gms.location.LocationListener
For First crash: this crash is occuring due to the incorrect import for location listener class which you have implements to your Activity.
Change com.google.android.gms.location.LocationListener with android.location.LocationListener
and for second crash use bellow LocationListener, this crash is occuring due your null reference of location listener object.
private LocationListener mLocationListener = new LocationListener() {
#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) {
}
};
Your requestLocationUpdates could not find instance of Listener so add MapsActivity.this to requestLocationUpdates
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager.requestLocationUpdates(provider, 5000, 0, MapsActivity.this);//Changed here
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation != null){
mLatitude = String.valueOf(mLastLocation.getLatitude());
mLongitude = String.valueOf(mLastLocation.getLongitude());
Toast.makeText(this, mLatitude + " , " + mLongitude, Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Permission denied, please accept permission..", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
I'm following this tutorial to use place picker. Here It is not mentioned that where should be the onActivityResult() method placed. So I've tried following code to get details of selected place. But can't get any responses.
My main activity named MapActivity:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#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);
}
/**
* 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.
*/
int PLACE_PICKER_REQUEST = 1;
#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));
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
try {
startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST);
}
catch (Exception e){
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(this, data);
String toastMsg = String.format("Place: %s", place.getName());
Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
}
}
}
}
I also don't know where PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder(); should be placed.
I've tried many time to search for this, but I can't get perfect solution. Any help will be appreciated.
Thanks in Advance!
You shouldn't call this code startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST); in a Map activity, it should be called from a non-map activity, probably after a button click (it's up to you).
Example with some pseudocode:
public class MyActivity extends AppCompatActivity {
private Button mButton;
#Override
onCreate(Bundle savedInstanceState) {
mButton.setOnCLickListener(...);
}
private void onButtonClicked() {
// this opens a new activity with a place picker
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
startActivityForResult(builder.build(this),PLACE_PICKER_REQUEST);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// when you click back from place picker, it is handled in this method
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(this, data);
String toastMsg = String.format("Place: %s", place.getName());
Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
}
}
}