package edu.washington.geopost; import android.app.Activity; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.facebook.Request; import com.facebook.Response; import com.facebook.Session; import com.facebook.model.GraphUser; import com.parse.LogInCallback; import com.parse.ParseException; import com.parse.ParseFacebookUtils; import com.parse.ParseQuery; import com.parse.ParseRelation; import com.parse.ParseUser; /** * This activity provides the functionality for users to log in to the app. * * @authors Megan Drasnin, Andrew Repp */ public class LoginActivity extends Activity { private Button loginButton; private Dialog progressDialog; /** * Displays the login button and skips to the main app if the user is * already logged in. * @param savedInstanceState the data saved by the app the last time it * shutdown, or null if there is no such data */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); loginButton = (Button) findViewById(R.id.loginButton); loginButton.setOnClickListener(new View.OnClickListener() { // Hooks up the login button to its listener @Override public void onClick(View v) { onLoginButtonClicked(); } }); // Check if there is a currently logged in user and they are linked to // a Facebook account. If they are, skip to the main map activity. ParseUser currentUser = ParseUser.getCurrentUser(); if ((currentUser != null) && ParseFacebookUtils.isLinked(currentUser)) { showMainActivity(false); } } /** * Finishes Facebook authentication. * @param requestCode the code identifying who made the request * @param resultCode the code containing information on the result * @param data the data returned by the activity, if any */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data); Log.d("DEBUG", "onActivityResult finished Authentication"); if (!isNetworkAvailable()) { Toast toast = Toast.makeText(getApplicationContext(), "Network unavailable", Toast.LENGTH_LONG); toast.show(); } } /** * Logs in the user when they press the login button. */ private void onLoginButtonClicked() { LoginActivity.this.progressDialog = ProgressDialog.show( LoginActivity.this, "", "Logging in...", true); List<String> permissions = Arrays.asList("public_profile", "user_friends"); // Attempt to log the user in. If the login is successful, save // important data for later and proceed to the main app. ParseFacebookUtils.logIn(permissions, this, new LogInCallback() { @Override public void done(ParseUser user, ParseException err) { LoginActivity.this.progressDialog.dismiss(); if (user == null) { // error Log.d("DEBUG", "User cancelled the Facebook login."); } else { // success boolean isNewUser = false; if (user.isNew()) { Log.d("DEBUG", "User signed up and logged in through" + "Facebook!"); isNewUser = true; } else { Log.d("DEBUG", "User logged in through Facebook!"); } saveUserInfo(); getFriends(); showMainActivity(isNewUser); } } }); } /** * Displays the map activity. * @param isNewUser true iff the user is new */ private void showMainActivity(boolean newUser) { Intent intent = new Intent(this, MainActivity.class); intent.putExtra("NewUser", newUser); startActivity(intent); } /** * Saves the user's Facebook ID and name from Facebook in the Parse * database. */ private void saveUserInfo() { Session session = ParseFacebookUtils.getSession(); if (session != null && session.isOpened()) { // Make the request to Facebook's Graph to get the data Request request = Request.newMeRequest(session, new Request.GraphUserCallback() { // handle response @Override public void onCompleted(GraphUser user, Response response) { if (user != null) { // successfully got data about user ParseUser currentUser = ParseUser.getCurrentUser(); currentUser.setUsername(user.getName()); currentUser.put("facebookID", user.getId()); currentUser.saveEventually(); } else if (response.getError() != null) { // error to display Log.d("DEBUG", response.getError().getErrorMessage()); } } }); request.executeAsync(); } } /** * Saves the user's Facebook friends in the Parse database. */ private void getFriends() { Session session = ParseFacebookUtils.getSession(); if (session != null && session.isOpened()) { // Make the request to Facebook's Graph to get the data Request request = Request.newMyFriendsRequest(session, new Request.GraphUserListCallback() { @Override public void onCompleted(List<GraphUser> users, Response response) { if (users != null) { // successfully got user's friends List<String> friendsList = new ArrayList<String>(); for (GraphUser user : users) { friendsList.add(user.getId()); } // Construct a ParseUser query that will find friends // whose Facebook IDs are contained in the current // user's friend list. ParseQuery<ParseUser> friendQuery = ParseUser.getQuery(); friendQuery.whereContainedIn("facebookID", friendsList); // find will return a a list of ParseUsers that are // friends with the current user List<ParseUser> friendUsers = null; try { friendUsers = friendQuery.find(); } catch (ParseException e) { // error finding friends Log.d("DEBUG", "Could not find facebook " + "friends."); return; } // Save the current user's Facebook friends in the // database in the user's friends relation ParseUser currentUser = ParseUser.getCurrentUser(); ParseRelation<ParseUser> friendsRelation = currentUser.getRelation("friends"); for (ParseUser friend : friendUsers) { friendsRelation.add(friend); } currentUser.saveEventually(); } } }); request.executeAsync(); } } /** * Determines if the phone is connected to a network. * @return true if the phone is connected to any network, false otherwise */ private boolean isNetworkAvailable() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } }