This has been bugging me for a while now. For some reason, the markers from the firebase is not showing in the map. I have been searching for a while now and I almost looked into different answered questions here. Its either not applicable to my application, or it really doesn't work.
I tried to add static, hardcoded latlongs for markers. Added a bunch, and the app complies. It shows all the static, hardcoded markers. Unfortunately, together with the firebase call for loop code to create markers still doesn't show.
MapsActivity.java
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener, GoogleMap.OnMarkerClickListener, GoogleMap.OnMyLocationButtonClickListener, GoogleMap.OnMyLocationClickListener, GoogleMap.OnInfoWindowClickListener {
private GoogleMap mMap;
private UiSettings mUiSettings;
static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private DatabaseReference mBlog;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mToggle;
Marker marker;
List<Blogzone> mapList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initDrawer();
mapList = new ArrayList<Marker>();
mBlog = FirebaseDatabase.getInstance().getReference().child("Blogzone");
mBlog.push().setValue(marker);
//Firebase Auth
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (mAuth.getCurrentUser() == null) {
Intent loginIntent = new Intent(MapsActivity.this, LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(loginIntent);
}
}
};
}
#Override
public void onMapReady(GoogleMap googleMap) {
mAuth.addAuthStateListener(mAuthListener);
mMap = googleMap;
mUiSettings = mMap.getUiSettings();
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) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
return;
}
mMap.setMyLocationEnabled(true);
// UI Settings state
mUiSettings.setZoomControlsEnabled(true);
mUiSettings.setMyLocationButtonEnabled(true);
//Post Markers
mMap.setOnMarkerClickListener(this);
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.setOnInfoWindowClickListener(this);
mMap.clear();
final LatLng PH = new LatLng(16.566233,121.262634);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(PH, 6));
mBlog.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot s : dataSnapshot.getChildren()){
Blogzone here = s.getValue(Blogzone.class);
double latitude = Double.parseDouble(here.latitude);
double longitude = Double.parseDouble(here.longitude);
mapList.add(here);
for (int i = 0; i < mapList.size(); i++)
{
LatLng LOC = new LatLng(latitude,longitude);
if (mMap != null) {
Log.d("the locations", "Get location: " + latitude + ", " + longitude + " at " + here.title);
marker = mMap.addMarker(new MarkerOptions().position(LOC).title(here.title));
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Blogzone.class
public class Blogzone {
public String title, desc, imageUrl, username;
public String latitude, longitude;
public Blogzone(String title, String desc, String imageUrl, String username, String latitude, String longitude) {
this.title = title;
this.desc = desc;
this.imageUrl=imageUrl;
this.username = username;
this.latitude = latitude;
this.longitude = longitude;
}
public Blogzone() {
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public void setUsername(String username) {
this.username = username;
}
public void setTitle(String title) {
this.title = title;
}
public void setDesc(String desc) { this.desc = desc; }
public void setlatitude(String latitude) { this.latitude = latitude; }
public void setLongitude(String longitude) { this.longitude = longitude; }
public String getUsername() {
return username;
}
public String getImageUrl() {
return imageUrl;
}
public String getTitle() {
return title;
}
public String getDesc() {
return desc;
}
public String getLatitude() {
return latitude;
}
public String getLongitude() {
return longitude;
}
}
edit:
Here's the logs.
there are some null string error but I think it doesn't affect the problem
Note that this is just a project app and I just learned from different tutorials and demos around the web. I just started coding Java last year.
I hope someone could help me soon.
Related
Im trying to get realtime location with pointing on the Google Map. Currently i successfully get the latitude and longitude in realtime and it will update everytime to a getter, setter class called sosrecord.getLatitude() and sosrecord.getLongitude(). I want to point the google map based on the updated latitude and longitude. But everytime when i put the getter on the LatLng latLng = new LatLng(sosrecord.getLatitude(), sosrecord.getLongitude()); it will return me Null and eventually crash the app due to java.lang.NullPointerException: Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference It should point the current location when user click on a button. Sorry if the code sample below is messy, hope someone could help me with this issue. Thanks.
Main.java
public class MainActivity extends FragmentActivity{
private Handler mHandler = new Handler();
DatabaseReference reff;
SosRecords sosrecords;
boolean startclicked =true;
String selectedOfficer = "Police";
private static final String TAG = "MainActivity";
int LOCATION_REQUEST_CODE = 1001;
SupportMapFragment smf;
FusedLocationProviderClient fusedLocationProviderClient;
LocationRequest locationRequest;
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult <------This function will get the lat and long and set the value to sosrecordlocationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
double lat = location.getLatitude();
double lon = location.getLongitude();
sosrecords.setLatitude(lat);
sosrecords.setLongitude(lon);
}
}
};
private void showOptionDialog() {
String[] officers = {"Police", "Hospital", "Bomba"};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Choose SOS types");
builder.setSingleChoiceItems(officers, 0, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
selectedOfficer = officers[which];
}
});
builder.setPositiveButton("Proceed", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
sosrecords.setCallFor(selectedOfficer);{
onStart();
startclicked= false;
//GET ALL INFORMATION FROM FIRESTORE AND SEND TO REALTIME DATABASE
if(FirebaseAuth.getInstance().getCurrentUser()!= null){
DocumentReference df = FirebaseFirestore.getInstance().collection("Users").document(FirebaseAuth.getInstance().getCurrentUser().getUid());
df.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if(documentSnapshot.getString("FullName")!= null){
String id = reff.push().getKey();
Log.d(TAG, "asdasd"+id);
SosRecords sosRecords = new SosRecords(documentSnapshot.getString("FullName"), (documentSnapshot.getString("PhoneNumber")), (documentSnapshot.getString("UserEmail") ),sosrecords.getLatitude(),sosrecords.getLongitude(),sosrecords.getCallFor() );
reff.child(id).setValue(sosRecords);
sosrecords.setRecordID(id);
btnStartSOS.setEnabled(false);
btnStopSOS.setEnabled(true);
Toast.makeText(MainActivity.this, "You're are now activating SOS request !", Toast.LENGTH_SHORT).show();
LatLonLoop.run();
smf.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng latLng = new LatLng(sosrecords.getLatitude(),sosrecords.getLongitude());
MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("Here");
googleMap.addMarker(markerOptions);
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15));
}
});
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(getApplicationContext(),Login.class));
finish();
}
});
}
if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
checkSettingsAndStartLocationUpdates();
}else{
askLocationPermission();
}
}
dialog.dismiss();
}
});
My get/set class
package com.example.sossystem;
public class SosRecords {
String RecordID;
String FullName;
String PhoneNumber;
String EmailAddress;
Double Latitude;
Double Longitude;
String CallFor;
public SosRecords(){
}
public SosRecords(String fullName, String phoneNumber, String userEmail, Double latitude, Double longitude, String callFor) {
FullName = fullName;
PhoneNumber = phoneNumber;
EmailAddress = userEmail;
Latitude = latitude;
Longitude = longitude;
CallFor = callFor;
}
public String getRecordID() {
return RecordID;
}
public void setRecordID(String recordID) {
RecordID = recordID;
}
public String getFullName() {
return FullName;
}
public void setFullName(String fullName) {
FullName = fullName;
}
public String getPhoneNumber() {
return PhoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
PhoneNumber = phoneNumber;
}
public String getEmailAddress() {
return EmailAddress;
}
public void setEmailAddress(String emailAddress) {
EmailAddress = emailAddress;
}
public Double getLatitude() {
return Latitude;
}
public void setLatitude(Double latitude) {
Latitude = latitude;
}
public Double getLongitude() {
return Longitude;
}
public void setLongitude(Double longitude) {
Longitude = longitude;
}
public String getCallFor() {
return CallFor;
}
public boolean setCallFor(String callFor) {
CallFor = callFor;
return false;
}
}
The thing is that when you open MainActiity that time onMapReady() called first automatically before LocationCallback. Eventually, it will return null latitude and Longitude.
However, your problem is that you haven't assigned your map fragment.
first of all, you need to assign in onLocationResult() below the for loop.
SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(MapsActivity.this);
Secondly, remove smf.getMapAsync() from onMapReady().
Instead of,
smf.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng latLng = new LatLng(sosrecords.getLatitude()
,sosrecords.getLongitude());
MarkerOptions markerOptions = new MarkerOptions().
position(latLng).title("Here");
googleMap.addMarker(markerOptions);
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15));
}
});
Replace,
// declare googlemap as a globally
private GoogleMap mMap;
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng latLng = new LatLng(sosrecords.getLatitude()
,sosrecords.getLongitude());
MarkerOptions markerOptions = new MarkerOptions().
position(latLng).title("Here");
googleMap.addMarker(markerOptions);
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15));
}
});
I have a Firebase Realtime database, where I store Google Maps Marker data. It looks like this: Firebase Database
My application has the option to add your own marker to the database, my problem is that my application only reads the info from Studio 1 and T1, not from the random key added by .push(). when i add a marker via the app. Any ideas on how to get it to read the marker info that is under the random key? My code looks as follows:
public class MapsActivity extends FragmentActivity implements
OnMapReadyCallback, GoogleMap.OnMarkerClickListener {
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference mProfileRef = firebaseDatabase.getReference("Studios");
ChildEventListener mChildEventListener;
#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);
Button addAStudio = (Button) findViewById(R.id.addAStudio);
addAStudio.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(MapsActivity.this, Rent.class);
startActivity(intent);
}
});
}
#Override
public void onMapReady(GoogleMap googleMap){
googleMap.setOnMarkerClickListener(this);
LatLng Copenhagen = new LatLng(55.67, 12.56);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Copenhagen, 18));
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//get marker info from Firebase Database and add to map
addMarkersToMap(googleMap);
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) {
return;
}
googleMap.setMyLocationEnabled(true);
}
#Override
public void onStop(){
if(mChildEventListener != null)
mProfileRef.removeEventListener(mChildEventListener);
super.onStop();
}
private void addMarkersToMap(final GoogleMap map){
mChildEventListener = mProfileRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
FirebaseMarker marker = dataSnapshot.getValue(FirebaseMarker.class);
String StudioName = marker.getStudioName();
String StudioAdress = marker.getStudioAddress();
String StudioDescription = marker.getStudioDescription();
double latitude = marker.getLatitude();
double longitude = marker.getLongitude();
LatLng location = new LatLng(latitude, longitude);
map.addMarker(new MarkerOptions()
.position(location)
.title(StudioName)
.snippet(StudioAdress)
.snippet(StudioDescription))
.showInfoWindow();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public boolean onMarkerClick(Marker marker) {
return false;
}
And
public class FirebaseMarker {
public String studioName;
public String studioDescription;
public String studioAddress;
public double latitude;
public double longitude;
//required empty constructor
public FirebaseMarker() {
}
public FirebaseMarker(String studioName, String studioDescription, String studioAdress, double latitude, double longitude) {
this.studioName = studioName;
this.studioDescription = studioDescription;
this.studioAddress = studioAdress;
this.latitude = latitude;
this.longitude = longitude;
}
public String getStudioName() {
return studioName;
}
public void setStudioName(String studioName) {
this.studioName = studioName;
}
public String getStudioDescription() {
return studioDescription;
}
public void setStudioDescription(String studioDescription) {
this.studioDescription = studioDescription;
}
public String getStudioAddress() {
return studioAddress;
}
public void setStudioAddress(String studioAddress) {
this.studioAddress = studioAddress;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
}
and finally where add a new marker to the database:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rent);
saveStudio = findViewById(R.id.saveStudio);
studioNameTextField = findViewById(R.id.studioNameTextField);
studioInfoTextField = findViewById(R.id.studioInfoTextField);
studioAdressTextField = findViewById(R.id.studioAdressTextField);
mDatabase = FirebaseDatabase.getInstance();
mDataBaseRef = mDatabase.getReference("Studios");
saveStudio = findViewById(R.id.saveStudio);
saveStudio.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Map<String, FirebaseMarker> newStudioAdd = new HashMap<>();
newStudioAdd.put(studioNameTextField.getText().toString(),
new FirebaseMarker(
studioNameTextField.getText().toString(),
studioInfoTextField.getText().toString(),
studioAdressTextField.getText().toString(),
53.669115, 12.560311
)
);
mDataBaseRef.push().setValue(newStudioAdd);
Intent intent = new Intent(Rent.this, MapsActivity.class);
startActivity(intent);
}
});
}
as of now the latitude and longitude are hardcoded, as i want it to read the markers before i continue.
This is happening because Studio 1 and T1 have different paths than the T2. As I see in your database schema, your T2 as an extra child (-LH-3 ... GbsF) which is generated by the push() method. In order to display all those objects correctly, you need to have the same paths for all objects. So you can achieve this, either by adding Studio 1 and T1 in the same way, using the push() method or by adding the T2 without using the push() method.
FirebaseMarker firebaseMarker = new FirebaseMarker(
studioNameTextField.getText().toString(),
studioInfoTextField.getText().toString(),
studioAdressTextField.getText().toString(),
53.669115, 12.560311);
mDataBaseRef.push().setValue(firebaseMarker);
Assuming that the Studios node is a direct child of your Firebase database, here is how you can add the markers on the map:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference studiosRef = rootRef.child("Studios");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
FirebaseMarker marker = dataSnapshot.getValue(FirebaseMarker.class);
String StudioName = marker.getStudioName();
String StudioAdress = marker.getStudioAddress();
String StudioDescription = marker.getStudioDescription();
double latitude = marker.getLatitude();
double longitude = marker.getLongitude();
LatLng location = new LatLng(latitude, longitude);
map.addMarker(new MarkerOptions()
.position(location)
.title(StudioName)
.snippet(StudioAdress)
.snippet(StudioDescription))
.showInfoWindow();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
studiosRef.addListenerForSingleValueEvent(valueEventListener);
The user must add a marker by tapping the map. My goal is to send the Name, Category, Latitude and Longitude to a SQL database. I followed this issue: How can you pass multiple primitive parameters to AsyncTask?,
but the app crashes when I hit the button which calls the shopReg.
Also, maybe there is something wrong with the communication between my app and the WampServer. I wonder if the connection URL is correct. I found on the Internet that the default WAMP localhost IP is 10.0.2.2. See the code:
AddShopActivity.java
public class AddShopActivity extends MainScreen implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
Spinner spinner;
ArrayAdapter<CharSequence> adapter;
GoogleMap mGoogleMap;
GoogleApiClient mGoogleApiClient;
String Name, Category;
Double Latitude, Longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_shop);
initMap();
spinner = (Spinner) findViewById(R.id.spinner);
adapter = ArrayAdapter.createFromResource(this, R.array.eidoskatastimatos, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
private void initMap() {
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.mapFragment);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
LocationRequest mLocationsRequest;
#Override
public void onConnected(Bundle bundle) {
mLocationsRequest = LocationRequest.create();
mLocationsRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationsRequest.setInterval(5000);
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) {
// 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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationsRequest, this);
mGoogleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
EditText shop_name = (EditText)findViewById(R.id.editName);
Spinner shop_category = (Spinner)findViewById(R.id.spinner);
MarkerOptions marker = new MarkerOptions()
.position(new LatLng(latLng.latitude, latLng.longitude))
.draggable(true)
.title(shop_name.getText().toString())
.snippet(shop_category.getSelectedItem().toString());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng, 16);
mGoogleMap.animateCamera(update);
mGoogleMap.clear();
mGoogleMap.addMarker(marker);
Name = shop_name.getText().toString();
Category = shop_category.getSelectedItem().toString();
Latitude = latLng.latitude;
Longitude = latLng.longitude;
}
});
}
public void shopReg(View view)
{
String method = "save";
BackgroundTask backgroundTask = new BackgroundTask(this);
new BackgroundTask(method,Name,Category,Latitude,Longitude).execute();
finish();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
if (location == null){
Toast.makeText(this, "Can't get current location", Toast.LENGTH_LONG).show();
} else {
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, 16);
mGoogleMap.animateCamera(update);
}
}
}
BackgroundTask.java
public class BackgroundTask extends AsyncTask<String,Void,String> {
String Name, Category;
Double Latitude, Longitude;
BackgroundTask(String method, String Name, String Category, Double Latitude, Double Longitude) {
this.Name = Name;
this.Category = Category;
this.Latitude = Latitude;
this.Longitude = Longitude;
}
Context ctx;
BackgroundTask(Context ctx){
this.ctx = ctx;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String reg_url = "http://10.0.2.2/shop/register.php";
String method = params[0];
if(method.equals("save"))
{
String Name = params[1];
String Category = params[2];
Double Latitude = Double.parseDouble(params[3]);
Double Longitude = Double.parseDouble(params[4]);
try {
URL url = new URL(reg_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
OutputStream OS = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(OS, "UTF-8"));
String data = URLEncoder.encode("Name", "UTF-8") +"="+URLEncoder.encode(Name,"UTF-8")+"&"+
URLEncoder.encode("Category", "UTF-8") +"="+URLEncoder.encode(Category,"UTF-8")+"&"+
URLEncoder.encode("Latitude", "UTF-8") +"="+URLEncoder.encode(String.valueOf(Latitude),"UTF-8")+"&"+
URLEncoder.encode("Longitude", "UTF-8") +"="+URLEncoder.encode(String.valueOf(Longitude),"UTF-8");
bufferedWriter.write(data);
bufferedWriter.flush();
bufferedWriter.close();
OS.close();
InputStream IS = httpURLConnection.getInputStream();
IS.close();
return "Το κατάστημα προστέθηκε!";
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(ctx,result,Toast.LENGTH_LONG).show();
}
}
register.php
<?php
require"init.php";
$Name=$_POST["Name"];
$Category=$_POST["Category"];
$Latitude=$_POST["Latitude"];
$Longitude=$_POST["Longitude "];
$sql_query="insert into shop_info
values('$Name','$Category','$Latitude','$Longidude');";
?>
init.php
<?php
$db_name="shops";
$mysql_user="root";
$mysql_pass="";
$server_name="localhost";
?>
Context - ctx is null and will result in crash
#Override
protected void onPostExecute(String result) {
Toast.makeText(ctx,result,Toast.LENGTH_LONG).show();
}
backgroundTask is not used after initialisation.
BackgroundTask backgroundTask = new BackgroundTask(this);
For below async task which you execute, context - ctx is null.
new BackgroundTask(method,Name,Category,Latitude,Longitude).execute();
Please add one more parameter and pass context as well like below:
new BackgroundTask(ctx, method,Name,Category,Latitude,Longitude).execute();
Actually it was very obvious, but I didn't see it. The String method = "save";accepts only String type and I was trying to pass double with Latitude and Longitude. So I just turned doubles to Strings using;
Latitude = String.valueOf(latLng.latitude);
Longitude = String.valueOf(latLng.longitude);
Thanks for help!
I want to place a marker on a specific location. At first, I thought this would be simple to do but somehow I'm getting confused and I haven't found something that actually gives me what I need. I've tried to base my activity on whats it's done in this video https://www.youtube.com/watch?v=HD48FBwY9U0
My activity starts by receiving an object information on a getIntent() which I then extract the information. In that object (in this case, a car), there is a lot of properties and 2 of them, are the latitude and longitude. The previous are in Double values.
The problem that I am facing is that I don't know how to input the information that I got from the object into the program. I'm placing the code below. Any suggestions?
public class Geolocalizcao extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
private GoogleApiClient client;
private LocationRequest locationRequest;
private Location lastLocation;
private Marker currentLocationMarker;
public static final int REQUEST_LOCATION_CODE = 99;
public static int REQUEST_ERROR_CODE;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geolocalizcao);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
Intent i = getIntent();
CarDataset cardata = (CarDataset) i.getExtras().getParcelable("select");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
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)
{
buildGoogleApiClient();
return;
}
}
protected synchronized void buildGoogleApiClient()
{
client = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
client.connect();
}
#Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Here!");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker());
currentLocationMarker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(3));
if(client != null)
{
LocationServices.FusedLocationApi.removeLocationUpdates(client, this);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1000);
locationRequest.setFastestInterval(1000);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
public boolean checkLocationPermission()
{
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION_CODE);
}
else
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION_CODE);
}
return false;
}
else
return false;
}
#Override
// When connection is lost...
public void onConnectionSuspended(int i)
{
Toast.makeText(this, "Lost connection. Trying to reconnect...", Toast.LENGTH_SHORT);
client.connect();
}
#Override
// Called when the API client doesnt sucessufly connect
public void onConnectionFailed(#NonNull ConnectionResult connectionResult)
{
if (!connectionResult.hasResolution())
{
GoogleApiAvailability.getInstance().getErrorDialog(this, connectionResult.getErrorCode(), 0).show();
return;
}
try
{
connectionResult.startResolutionForResult(this, REQUEST_ERROR_CODE );
} catch (IntentSender.SendIntentException e)
{
Log.e("LOG", "Exception:", e);
}
}
Here's the class CarDataset that I use:
public class CarDataset implements Parcelable
{
int vehicleID;
String model;
String licencePlate;
String brand;
Double latitude;
Double longitude;
public CarDataset(Integer nVehicleID, String nModel, String nLicencePlate, String nBrand, Double nLatitude, Double nLongitude)
{
this.vehicleID = nVehicleID;
this.model = nModel;
this.licencePlate = nLicencePlate;
this.brand = nBrand;
this.latitude = nLatitude;
this.longitude = nLongitude;
}
public int getVehicleID() {
return vehicleID;
}
public void setVehicleID(int vehicleID) {
this.vehicleID = vehicleID;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getLicencePlate() {
return licencePlate;
}
public void setLicencePlate(String licencePlate) {
this.licencePlate = licencePlate;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
#Override
public int describeContents()
{
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(vehicleID);
dest.writeString(model);
dest.writeString(licencePlate);
dest.writeString(brand);
dest.writeDouble(latitude);
dest.writeDouble(longitude);
}
public static final Parcelable.Creator<CarDataset> CREATOR
= new Parcelable.Creator<CarDataset>()
{
public CarDataset createFromParcel(Parcel input)
{
return new CarDataset(input);
}
public CarDataset[] newArray(int size)
{
return new CarDataset[size];
}
};
private CarDataset(Parcel input)
{
vehicleID = input.readInt();
model = input.readString();
licencePlate = input.readString();
brand = input.readString();
latitude = input.readDouble();
longitude = input.readDouble();
}
}
All you need to do is create a LatLng object with the latitude and longitude from the CarDataset object that you get from the Intent.
Marker carMarker;
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (cardata != null) {
LatLng latLngCar = new LatLng(cardata.latitude, cardata.longitude);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLngCar);
markerOptions.title("Car");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker());
carMarker = mMap.addMarker(markerOptions);
}
//.............
}
You will also need to modify onCreate() so that cardata is an instance variable:
CarDataset cardata;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geolocalizcao);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
Intent i = getIntent();
//use instance variable:
cardata = (CarDataset) i.getExtras().getParcelable("select");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(3));
mMap.addMarker(new MarkerOptions()
.title("Here!")
.icon(BitmapDescriptorFactory.defaultMarker())
.position(latlng_object));
i have two simple classes. Main and some kind of gps helper. I'm trying to reach distance when gps posiotion has change (on Location change). It works and Toast good but when i try to save variable dis using setter, and reach it in my MainActivity(last method called ObliczanieOdl) a allways have 0.0. Why? Any suggestions?
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
#BindView(R.id.butStop)
Button butStop;
#BindView(R.id.butWynik)
Button butKoniec;
private GoogleMap mMap;
private String dlugosc;
private String szerokosc;
private LatLng StartP, StopP;
private Date czasS;
private DatabaseHelper mDatabaseHelper;
private String adres;
private int Dystans;
private boolean oneStop = false;
private GPStracker gpStracker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
ButterKnife.bind(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 123);
Intent intent = getIntent();
gpStracker = new GPStracker(getApplicationContext());
dlugosc = intent.getStringExtra("dlugosc");
szerokosc = intent.getStringExtra("szerokosc");
StartP = new LatLng(Double.parseDouble(szerokosc), Double.parseDouble(dlugosc));
czasS = new Date();
mDatabaseHelper = new DatabaseHelper(this);
mDatabaseHelper.setStartP(getAdres(StartP));//wyciągnięcie adresu rozpoczęcia podróży
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
addMarker(StartP);
}
private void addMarker(LatLng pozycja) {
mMap.addMarker(new MarkerOptions().position(pozycja));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(pozycja)
.zoom(10).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
#OnClick(R.id.butStop)
public void butStop() {
if (oneStop == false) {
oneStop = true;
Location location = gpStracker.getlocation();
if (location != null) {
StopP = new LatLng(location.getLatitude(), location.getLongitude());
}
addMarker(StopP);
mDatabaseHelper.setKoniecP(getAdres(StopP)); //wyciągnięcie adresu zakonczenia podróży
//wyciągnięcie odległości i czasu podróży
mDatabaseHelper.setCzasP(String.valueOf(ObliczanieOdl(StartP, StopP)) + " KM " + "w czasie: " + WyliczCzas());
boolean insertData = mDatabaseHelper.addData();
} else {
toastMessage("Twoja podróż została zakończona");
}
}
#OnClick(R.id.butWynik)
public void butKoniec() {
if (oneStop == false) {
toastMessage("Musisz zakończyć podróż wciskając STOP");
} else {
Intent intent = new Intent(MapsActivity.this, ListDataActivity.class);
startActivity(intent);
}
}
public double ObliczanieOdl() {
Double metry = gpStracker.getDis();
return metry;
}
}
and second as a GPS Helper:
public class GPStracker implements LocationListener {
Context context;
double plat;
double plon;
double clat;
double clon;
public double dis;
public GPStracker(Context c) {
context = c;
}
public Location getlocation() {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, "Uprawnienia nie przyznane", Toast.LENGTH_SHORT).show();
}
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean isGPSenabled;
isGPSenabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSenabled) {
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 1, this);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
return location;
} else {
Toast.makeText(context, "Proszę włączyć GPS", Toast.LENGTH_LONG).show();
}
return null;
}
#Override
public void onLocationChanged(Location location) {
clat = location.getLatitude();
clon = location.getLongitude();
if (clat != plat || clon != plon) {
dis += getDistance(plat, plon, clat, clon);
plat = clat;
plon = clon;
setDis(dis);
}
Toast.makeText(context, String.valueOf(dis), Toast.LENGTH_SHORT).show();
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
public double getDistance(double lat1, double lon1, double lat2, double lon2) {
double latA = Math.toRadians(lat1);
double lonA = Math.toRadians(lon1);
double latB = Math.toRadians(lat2);
double lonB = Math.toRadians(lon2);
double cosAng = (Math.cos(latA) * Math.cos(latB) * Math.cos(lonB - lonA)) +
(Math.sin(latA) * Math.sin(latB));
double ang = Math.acos(cosAng);
double dist = ang * 6371;
return dist;
}
public double getDis() {
return dis;
}
public void setDis(double dis) {
this.dis = dis;
}
}