用firebase获取附近的用户android

时间:2017-07-01 23:04:17

标签: java android firebase geofire

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

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 个答案:

答案 0 :(得分:2)

对于任何会发现这个有用的人,我设法通过将addValueEventListener firebase的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); } 方法返回的String键作为我数据库引用中路径的一部分,

类似

test command

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