问题
i am using firebase realtime database to store two types of users for two apps, users A will use App A to update their info and such, and users B will use app B to search nearby users A that they need their services from. I have been successful in uploading user A info from app A, even with location using geofire, now what i need is to show a list of usera A inside app B that are nearby. please help with answers regarding best ways/practices and if this here isnt the best method then suggestions are welcome..... thanks
public class MainActivity extends AppCompatActivity implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,Home.OnFragmentInteractionListener
{
public static String userId;
public static final int MY_REQUEST_PERMISSION_LOCATION = 1;
private long UPDATE_INTERVAL = 10 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
private static final String TAG_HOME = "home";
private static final String TAG_MY_PREF = "my__preferences";
private static final String TAG_NOTIFICATIONS = "notifications";
private static final String TAG_SETTINGS = "settings";
public static String CURRENT_TAG = TAG_HOME;
private String [] activityTitles;
SharedPreferences sharedPreferences;
String name;
String imageURI;
private boolean shouldLoadHomeFragOnBackPress = true;
private Handler mHandler;
Toolbar toolbar;
DrawerLayout drawer;
NavigationView navigationView;
private View navHeader;
private static int navItemIndex = 0;
private ImageView imgProfile;
private TextView txtName, txtEmail;
private DatabaseReference mDatabase;
GoogleApiClient mGoogleApiClient;
private boolean isPermissionGranted = false;
private LocationRequest mLocationRequest;
public double lat, lng;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById (R.id.toolbar);
setSupportActionBar(toolbar);
mHandler = new Handler ();
mGoogleApiClient = new GoogleApiClient . Builder (this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
activityTitles = getResources().getStringArray(R.array.nav_item_activity_titles);
drawer = (DrawerLayout) findViewById (R.id.drawer_layout);
navigationView = (NavigationView) findViewById (R.id.nav_view);
navHeader = navigationView.getHeaderView(0);
txtName = (TextView) navHeader . findViewById (R.id.username);
imgProfile = (ImageView) navHeader . findViewById (R.id.smallProfile);
setUpNavigationView();
if (savedInstanceState == null) {
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
loadHomeFragment();
}
sharedPreferences = getSharedPreferences(UserData, Context.MODE_PRIVATE);
name = sharedPreferences.getString(full_name, null);
imageURI = sharedPreferences.getString(imagesrc, null);
upload();
Glide.with(MainActivity.this).load(Uri.parse(imageURI)).into(imgProfile);
loadNavHeader();
}
public void loadNavHeader() {
txtName.setText(name);
}
private void loadHomeFragment() {
selectNavMenu();
// set toolbar title
setToolbarTitle();
// if user select the current navigation menu again, don't do anything
// just close the navigation drawer
if (getSupportFragmentManager().findFragmentByTag(CURRENT_TAG) != null) {
drawer.closeDrawers();
// show or hide the fab button
return;
}
Runnable mPendingRunnable = new Runnable() {
@Override
public void run() {
// update the main content by replacing fragments
Fragment fragment = getHomeFragment ();
FragmentTransaction fragmentTransaction = getSupportFragmentManager ().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,
android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commitAllowingStateLoss();
}
};
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
}
//Closing drawer on item click
drawer.closeDrawers();
// refresh toolbar menu
invalidateOptionsMenu();
}
private void upload() {
userId = sharedPreferences.getString("UID", null);
String username = sharedPreferences . getString (full_name, null);
String photoUri = sharedPreferences . getString (imagesrc, null);
mDatabase = FirebaseDatabase.getInstance().getReference("users/B");
mDatabase.child(userId).child("name").setValue(username);
mDatabase.child(userId).child("imageuri").setValue(photoUri);
}
@Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
public void onStop() {
super.onStop();
if (isPermissionGranted) {
mGoogleApiClient.disconnect();
}
}
public void onPause() {
if (isPermissionGranted)
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
super.onPause();
}
public void onResume() {
if (isPermissionGranted) {
if (mGoogleApiClient.isConnected())
startLocationUpdates();
}
super.onResume();
}
private Fragment getHomeFragment() {
switch(navItemIndex) {
case 0:
// home
Home home = new Home();
return home;
case 1:
//subjects
MYPref myPref = new MYPref();
return myPref;
case 2:
//
NotificationFragment notificationsFragment = new NotificationFragment();
return notificationsFragment;
case 3:
Settings settings = new Settings();
return settings;
default:
return new Home ();
}
}
private void setToolbarTitle() {
getSupportActionBar().setTitle(activityTitles[navItemIndex]);
}
private void selectNavMenu() {
navigationView.getMenu().getItem(navItemIndex).setChecked(true);
}
private void setUpNavigationView() {
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView . OnNavigationItemSelectedListener () {
// This method will trigger on item Click of navigation menu
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Check to see which item was being clicked and perform appropriate action
switch(menuItem.getItemId()) {
//Replacing the main content with ContentFragment Which is our Inbox View;
case R . id . nav_home :
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
break;
case R . id . nav_my_subjects :
navItemIndex = 1;
CURRENT_TAG = TAG_MY_PREF;
break;
case R . id . nav_notification :
navItemIndex = 2;
CURRENT_TAG = TAG_NOTIFICATIONS;
break;
case R . id . nav_settings :
navItemIndex = 3;
CURRENT_TAG = TAG_SETTINGS;
break;
case R . id . nav_logout :
LoginManager.getInstance().logOut();
FirebaseAuth.getInstance().signOut();
Intent i = new Intent(MainActivity.this, LoginActivity.class);
startActivity(i);
finish();
default:
navItemIndex = 0;
}
//Checking if the item is in checked state or not, if not make it in checked state
if (menuItem.isChecked()) {
menuItem.setChecked(false);
} else {
menuItem.setChecked(true);
}
menuItem.setChecked(true);
loadHomeFragment();
return true;
}
});
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
@Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
@Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawer.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessary or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
@Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawers();
return;
}
// This code loads home fragment when back key is pressed
// when user is in other fragment than home
if (shouldLoadHomeFragOnBackPress) {
// checking if user is on other navigation menu
// rather than home
if (navItemIndex != 0) {
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
loadHomeFragment();
return;
}
}
super.onBackPressed();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String []{ Manifest.permission.ACCESS_COARSE_LOCATION }, MY_REQUEST_PERMISSION_LOCATION);
}
return;
}
Location mCurrentLocation = LocationServices . FusedLocationApi . getLastLocation (mGoogleApiClient);
// Note that this can be NULL if last location isn't already known.
if (mCurrentLocation != null) {
// Print current location if not null
Log.d("DEBUG", "current location: " + mCurrentLocation.toString());
mDatabase = FirebaseDatabase.getInstance().getReference("users/B");
GeoFire gf = new GeoFire(mDatabase.child(userId));
gf.setLocation("location", new GeoLocation (mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()));
lat = mCurrentLocation.getLatitude();
lng = mCurrentLocation.getLongitude();
}
// Begin polling for new location updates.
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
if (i == CAUSE_SERVICE_DISCONNECTED) {
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
} else if (i == CAUSE_NETWORK_LOST) {
Toast.makeText(this, "Network lost. Please re-connect.", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
String msg = "Updated Location: "+
Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
protected void startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String []{ Manifest.permission.ACCESS_COARSE_LOCATION }, MY_REQUEST_PERMISSION_LOCATION);
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
return;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode) {
case MY_REQUEST_PERMISSION_LOCATION :
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
isPermissionGranted = true;
} else {
isPermissionGranted = false;
}
}
}
@Override
public void onFragmentInteraction() {
}
}
my firebase database
回答1:
For anyone who will find this useful i managed to do it by placing the addValueEventListener
method of firebase within the addQueryEventListener
and pass the String key that is returned by the onKeyEntered
method as part of the path in my database reference,
something like this
temp2=FirebaseDatabase.getInstance().getReference("users/A");
GeoFire geofire=new GeoFire(temp2.child("A_location"));
GeoQuery geoQuery=geofire.queryAtLocation(new GeoLocation(lat,lng),10);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
temp2.child(key).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Person person1 = dataSnapshot.getValue(Person.class);
String name = person1.getName();
String imageUri = person1.getImageUri();
System.out.print(name + " " + imageUri);
Toast.makeText(getActivity(),name,Toast.LENGTH_LONG).show();
personList.add(new Person(name, imageUri));
RVAdapter adapter=new RVAdapter(getActivity(),personList);
rv.setAdapter(adapter);
}
My only question is now is this method efficient if there are alot of users?
来源:https://stackoverflow.com/questions/44866113/getting-nearby-users-android-with-firebase