使用Firebase获取附近的用户Android



我正在使用Firebase实时数据库为两个应用存储两种类型的用户,用户A将使用应用A更新其信息等,用户B将使用应用B搜索他们需要服务的附近用户A。我已经成功地从应用程序 A 上传用户 A 信息,即使使用地火的位置,现在我需要的是显示附近的应用程序 B 内的用户 A 列表。请帮助回答有关最佳方法/实践的答案,如果这不是最佳方法,那么欢迎提出建议.....谢谢

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() {
}
}

我的 Firebase 数据库

对于任何会发现这有用的人,我设法通过将 Firebase 的addValueEventListener方法放在addQueryEventListener中并将onKeyEntered方法返回的字符串键作为数据库参考中路径的一部分,

像这样的东西

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);
}

我现在唯一的问题是,如果有很多用户,这种方法是否有效?

最新更新