Android Open Source - android-friend-smash-v2 Home Activity






From Project

Back to project page android-friend-smash-v2.

License

The source code is released under:

Copyright (c) 2014, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or bi...

If you think the Android project android-friend-smash-v2 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright 2012 Facebook/*w  w w  .  ja va 2 s . com*/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook.android.friendsmash;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import com.facebook.AppEventsLogger;
import com.facebook.FacebookRequestError;
import com.facebook.Request;
import com.facebook.RequestBatch;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphUser;
import com.facebook.widget.LoginButton;
import com.parse.LogInCallback;
import com.parse.ParseException;
import com.parse.ParseFacebookUtils;
import com.parse.ParseUser;

/**
 *  Entry point for the app that represents the home screen with the Play button etc. and
 *  also the login screen for the social version of the app - these screens will switch
 *  within this activity using Fragments.
 */
public class HomeActivity extends FragmentActivity {
  
  // Tag used when logging messages
    private static final String TAG = HomeActivity.class.getSimpleName();
    
    // Uri used in handleError() below
    private static final Uri M_FACEBOOK_URL = Uri.parse("http://m.facebook.com");

  // Declare the UiLifecycleHelper for Facebook session management
    private UiLifecycleHelper fbUiLifecycleHelper;

  // Fragment attributes
    private static final int FB_LOGGED_OUT_HOME = 0;
    private static final int HOME = 1;
    private static final int FRAGMENT_COUNT = HOME +1;
    private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
   
   // Boolean recording whether the activity has been resumed so that
   // the logic in onSessionStateChange is only executed if this is the case
   private boolean isResumed = false;
    
   // Constructor
   public HomeActivity() {
     super();
   }
   
   // Getter for the fbUiLifecycleHelper
   public UiLifecycleHelper getFbUiLifecycleHelper() {
    return fbUiLifecycleHelper;
  }
   
   
   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
              
      // Instantiate the fbUiLifecycleHelper and call onCreate() on it
        fbUiLifecycleHelper = new UiLifecycleHelper(this, new Session.StatusCallback() {
        @Override
      public void call(Session session, SessionState state,
          Exception exception) {
        // Add code here to accommodate session changes
          Log.d(TAG, "Session state changed: " + state + "  permissions: " + session.getPermissions());
          
          if (exception != null) 
            Log.e(TAG, "UiLifecycleHelper exception: " + exception.getMessage());
          
          updateView();
          if (fragments[HOME] != null) {
            if (state.isOpened()) {
              if (state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
                // Only callback if the opened token has been updated - i.e. the user
                // has provided write permissions
                ((HomeFragment) fragments[HOME]).tokenUpdated();

                Log.d(TAG, "Session state changed: " + state + "  permissions: " + session.getPermissions());
                  Log.d(TAG, "Session state changed2222: " + state + "  permissions: " + Session.getActiveSession().getPermissions());

                      }
            }
          }
      }
      });
        fbUiLifecycleHelper.onCreate(savedInstanceState);
        
    setContentView(R.layout.home);
    
    FragmentManager fm = getSupportFragmentManager();
        fragments[FB_LOGGED_OUT_HOME] = fm.findFragmentById(R.id.fbLoggedOutHomeFragment);
        fragments[HOME] = fm.findFragmentById(R.id.homeFragment);

        FragmentTransaction transaction = fm.beginTransaction();
        for(int i = 0; i < fragments.length; i++) {
            transaction.hide(fragments[i]);
        }
        transaction.commit();
    
    // Restore the logged-in user's information if it has been saved and the existing data in the application
    // has been destroyed (i.e. the app hasn't been used for a while and memory on the device is low)
    // - only do this if the session is open for the social version only
     if (FriendSmashApplication.IS_SOCIAL) {
      // loggedIn
       if (savedInstanceState != null) {
        boolean loggedInState = savedInstanceState.getBoolean(FriendSmashApplication.getLoggedInKey(), false);
         ((FriendSmashApplication)getApplication()).setLoggedIn(loggedInState);
         
         if ( ((FriendSmashApplication)getApplication()).isLoggedIn() &&
            ( ((FriendSmashApplication)getApplication()).getFriends() == null ||
              ((FriendSmashApplication)getApplication()).getCurrentFBUser() == null) ) {
           try {
             // currentFBUser
             String currentFBUserJSONString = savedInstanceState.getString(FriendSmashApplication.getCurrentFbUserKey());
             if (currentFBUserJSONString != null) {
               GraphUser currentFBUser = GraphObject.Factory.create(new JSONObject(currentFBUserJSONString), GraphUser.class);
               ((FriendSmashApplication)getApplication()).setCurrentFBUser(currentFBUser);
             }
                 
                 // friends
             ArrayList<String> friendsJSONStringArrayList = savedInstanceState.getStringArrayList(FriendSmashApplication.getFriendsKey());
             if (friendsJSONStringArrayList != null) {
               ArrayList<GraphUser> friends = new ArrayList<GraphUser>();
               Iterator<String> friendsJSONStringArrayListIterator = friendsJSONStringArrayList.iterator();
               while (friendsJSONStringArrayListIterator.hasNext()) {
                   friends.add(GraphObject.Factory.create(new JSONObject(friendsJSONStringArrayListIterator.next()), GraphUser.class));
               }
               ((FriendSmashApplication)getApplication()).setFriends(friends);
             }
           } catch (JSONException e) {
             Log.e(FriendSmashApplication.TAG, e.toString());
           }
         }
       }
     }
    }
   
   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);
     
     // Call onActivityResult on fbUiLifecycleHelper
      fbUiLifecycleHelper.onActivityResult(requestCode, resultCode, data);
    }
  
   @Override
    protected void onResumeFragments() {
    super.onResumeFragments();
    if (!FriendSmashApplication.IS_SOCIAL) {
      showFragment(HOME, false);
    } else {
      Session session = Session.getActiveSession();
      if (session != null && session.isOpened() && ((FriendSmashApplication)getApplication()).getCurrentFBUser() != null) {
        showFragment(HOME, false);
      } else {
        showFragment(FB_LOGGED_OUT_HOME, false);
      }
    }
    }
  
  @Override
    public void onResume() {
        super.onResume();
        isResumed = true;
        
        // Call onResume on fbUiLifecycleHelper
      fbUiLifecycleHelper.onResume();
        
        // Hide the notification bar
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
     
     // Measure mobile app install ads
     // Ref: https://developers.facebook.com/docs/tutorials/mobile-app-ads/
     AppEventsLogger.activateApp(this, ((FriendSmashApplication)getApplication()).getString(R.string.app_id));
    }

    @Override
    public void onPause() {
        super.onPause();
        isResumed = false;
        
        // Call onPause on fbUiLifecycleHelper
      fbUiLifecycleHelper.onPause();
    }
  
  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    
    // Call onSaveInstanceState on fbUiLifecycleHelper
      fbUiLifecycleHelper.onSaveInstanceState(outState);
        
      // Save the logged-in state
      outState.putBoolean(FriendSmashApplication.getLoggedInKey(), ((FriendSmashApplication)getApplication()).isLoggedIn());
      
        // Save the currentFBUser
        if (((FriendSmashApplication)getApplication()).getCurrentFBUser() != null) {
          outState.putString(FriendSmashApplication.getCurrentFbUserKey(),
              ((FriendSmashApplication)getApplication()).getCurrentFBUser().getInnerJSONObject().toString());
        }
        
        // Save the logged-in user's list of friends
        if (((FriendSmashApplication)getApplication()).getFriends() != null) {
          outState.putStringArrayList(FriendSmashApplication.getFriendsKey(),
              ((FriendSmashApplication)getApplication()).getFriendsAsArrayListOfStrings());
        }
  }
  
  @Override
    public void onDestroy() {
     super.onDestroy();
     
     // Call onDestroy on fbUiLifecycleHelper
      fbUiLifecycleHelper.onDestroy();
    }
  
  public void buyBombs() {
    // Update bomb and coins count (5 coins per bomb).
    FriendSmashApplication app = (FriendSmashApplication) getApplication();
    
    // check to see that we have enough coins.
    if (app.getCoins() - 5 < 0) {
      Toast.makeText(this, "Not enough coins.", Toast.LENGTH_LONG).show();
      return;
    }
    
    app.setBombs(app.getBombs()+1);
    app.setCoins(app.getCoins()-5);

    // save inventory values
    app.saveInventory();
        
        // Reload inventory values in fragment.
        loadInventoryFragment();
  }
  
    private void showFragment(int fragmentIndex, boolean addToBackStack) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        for (int i = 0; i < fragments.length; i++) {
            if (i == fragmentIndex) {
                transaction.show(fragments[i]);
            } else {
                transaction.hide(fragments[i]);
            }
        }
        if (addToBackStack) {
            transaction.addToBackStack(null);
        }
        transaction.commit();
        
        // Do other changes depending on the fragment that is now showing
        if (FriendSmashApplication.IS_SOCIAL) {
          switch (fragmentIndex) {
            case FB_LOGGED_OUT_HOME:
              // Hide the progressContainer in FBLoggedOutHomeFragment 
              if (fragments[FB_LOGGED_OUT_HOME] != null && ((FBLoggedOutHomeFragment)fragments[FB_LOGGED_OUT_HOME]) != null) {
                ((FBLoggedOutHomeFragment)fragments[FB_LOGGED_OUT_HOME]).progressContainer.setVisibility(View.INVISIBLE);
              }
              // Set the loggedIn attribute
              ((FriendSmashApplication)getApplication()).setLoggedIn(false);
              break;
            case HOME:
              // Set the loggedIn attribute
              ((FriendSmashApplication)getApplication()).setLoggedIn(true);
              break;
          }
        }
    }
  
  /* Facebook Integration Only ... */

  // Call back on HomeActivity when the session state changes to update the view accordingly
  private void updateView() {
    if (isResumed) {
      Session session = Session.getActiveSession();
      if (session.isOpened() && !((FriendSmashApplication)getApplication()).isLoggedIn() && fragments[HOME] != null) {
        // Not logged in, but should be, so fetch the user information and log in (load the HomeFragment)
        fetchUserInformationAndLogin();
          } else if (session.isClosed() && ((FriendSmashApplication)getApplication()).isLoggedIn() && fragments[FB_LOGGED_OUT_HOME] != null) {
        // Logged in, but shouldn't be, so load the FBLoggedOutHomeFragment
            logout();
            showFragment(FB_LOGGED_OUT_HOME, false);
          }
      
      // Note that error checking for failed logins is done as within an ErrorListener attached to the
      // LoginButton within FBLoggedOutHomeFragment
    }
  }
  
  // Fetch user information and login (i.e switch to the personalized HomeFragment)
  private void fetchUserInformationAndLogin() {
    final Session session = Session.getActiveSession();        
    if (session != null && session.isOpened()) {
      // If the session is open, make an API call to get user information required for the app
      
      // Show the progress spinner during this network call
      if (fragments[FB_LOGGED_OUT_HOME] != null && 
          ((FBLoggedOutHomeFragment)fragments[FB_LOGGED_OUT_HOME]).progressContainer != null) {
        ((FBLoggedOutHomeFragment)fragments[FB_LOGGED_OUT_HOME]).progressContainer.setVisibility(View.VISIBLE);
      }
      
      // Create a RequestBatch and add a callback once the batch of requests completes
      RequestBatch requestBatch = new RequestBatch();

      // Get a list of friends who have _not installed_ the game. 
      Request invitableFriendsRequest = Request.newGraphPathRequest(session, 
          "/me/invitable_friends", new Request.Callback() {
        
        @Override
        public void onCompleted(Response response) {

          FacebookRequestError error = response.getError();
          if (error != null) {
            Log.e(FriendSmashApplication.TAG, error.toString());
            handleError(error, true);
          } else if (session == Session.getActiveSession()) {
            if (response != null) {
              // Get the result
              GraphObject graphObject = response.getGraphObject();
              JSONArray dataArray = (JSONArray)graphObject.getProperty("data");

              List<JSONObject> invitableFriends = new ArrayList<JSONObject>();
              if (dataArray.length() > 0) {
                // Ensure the user has at least one friend ...

                for (int i=0; i<dataArray.length(); i++) {
                  invitableFriends.add(dataArray.optJSONObject(i));
                }
              }
                            
              ((FriendSmashApplication)getApplication()).setInvitableFriends(invitableFriends);              
            }
          }
        }
        
      });
      Bundle invitableParams = new Bundle();
      invitableParams.putString("fields", "id,first_name,picture");
      invitableFriendsRequest.setParameters(invitableParams);
      requestBatch.add(invitableFriendsRequest);
      
      
      // Check to see that the user granted the user_friends permission before loading friends.
      // This only loads friends who've installed the game.
      if (session.getPermissions().contains("user_friends")) {
        // Get the user's list of friends
        Request friendsRequest = Request.newMyFriendsRequest(session, 
            new Request.GraphUserListCallback() {
  
          @Override
          public void onCompleted(List<GraphUser> users, Response response) {
            FacebookRequestError error = response.getError();
            if (error != null) {
              Log.e(FriendSmashApplication.TAG, error.toString());
              handleError(error, true);
            } else if (session == Session.getActiveSession()) {
              // Set the friends attribute
              ((FriendSmashApplication)getApplication()).setFriends(users);
            }
          }
        });
        Bundle params = new Bundle();
        params.putString("fields", "name,first_name,last_name");
        friendsRequest.setParameters(params);
        requestBatch.add(friendsRequest);
      }
      
      // Get current logged in user information
      Request meRequest = Request.newMeRequest(session, 
          new Request.GraphUserCallback() {
        
        @Override
        public void onCompleted(GraphUser user, Response response) {
          FacebookRequestError error = response.getError();
          if (error != null) {
            Log.e(FriendSmashApplication.TAG, error.toString());
            handleError(error, true);
          } else if (session == Session.getActiveSession()) {
            // Set the currentFBUser attribute
            ((FriendSmashApplication)getApplication()).setCurrentFBUser(user);
            
            // Now save the user into Parse.
                        saveUserToParse(user, session);
          }
        }
      });
      requestBatch.add(meRequest);

      requestBatch.addCallback(new RequestBatch.Callback() {

        @Override
        public void onBatchCompleted(RequestBatch batch) {
          if ( ((FriendSmashApplication)getApplication()).getCurrentFBUser() != null) {
            // Login by switching to the personalized HomeFragment
            loadPersonalizedFragment();
          } else {
            showError(getString(R.string.error_fetching_profile), true);
          }
        }
      });
      
      // Execute the batch of requests asynchronously
      requestBatch.executeAsync();
    }
  }
  
  private void saveUserToParse(GraphUser fbUser, Session session) {
    ParseFacebookUtils.logIn(fbUser.getId(), session.getAccessToken(), 
        session.getExpirationDate(), new LogInCallback() {
      @Override
      public void done(ParseUser parseUser, ParseException err) {                   
        if (parseUser != null) {
          // The user has been saved to Parse.
          if (parseUser.isNew()) {
            // This user was created during this session with Facebook Login.                       
            Log.d(TAG, "ParseUser created.");

            // Call saveInventory() which will save data to Parse if connected. 
            FriendSmashApplication app = ((FriendSmashApplication)getApplication());
            app.saveInventory();
          } else {
            Log.d(TAG, "User exists in Parse. Pull their values: " + parseUser);

            // This user existed before. Call loadInventory() which has logic
            // to check Parse if connected.
            FriendSmashApplication app = ((FriendSmashApplication)getApplication());
            app.loadInventory();
          }

          loadInventoryFragment();
        } else {
          // The user wasn't saved. Check the exception.
          Log.d(TAG, "User was not saved to Parse: " + err.getMessage());
        }
      }
    });
  }

  // Loads the inventory portion of the HomeFragment. 
    private void loadInventoryFragment() {
      Log.d(TAG, "Loading inventory fragment");
      if (isResumed) {
      ((HomeFragment)fragments[HOME]).loadInventory();
    } else {
      showError(getString(R.string.error_switching_screens), true);
    }
    }

  // Switches to the personalized HomeFragment as the user has just logged in
  private void loadPersonalizedFragment() {
    if (isResumed) {
      // Personalize the HomeFragment
      ((HomeFragment)fragments[HOME]).personalizeHomeFragment();
      
      // Load the HomeFragment personalized
      showFragment(HOME, false);
    } else {
      showError(getString(R.string.error_switching_screens), true);
    }
  }
  
    void handleError(FacebookRequestError error, boolean logout) {
      Log.d(TAG, "handleError: " + error.getErrorMessage());
      
        DialogInterface.OnClickListener listener = null;
        String dialogBody = null;

        if (error == null) {
            dialogBody = getString(R.string.error_dialog_default_text);
        } else {
            switch (error.getCategory()) {
                case AUTHENTICATION_RETRY:
                    // tell the user what happened by getting the message id, and
                    // retry the operation later
                    String userAction = (error.shouldNotifyUser()) ? "" :
                            getString(error.getUserActionMessageId());
                    dialogBody = getString(R.string.error_authentication_retry, userAction);
                    listener = new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            Intent intent = new Intent(Intent.ACTION_VIEW, M_FACEBOOK_URL);
                            startActivity(intent);
                        }
                    };
                    break;

                case AUTHENTICATION_REOPEN_SESSION:
                    // close the session and reopen it.
                    dialogBody = getString(R.string.error_authentication_reopen);
                    listener = new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            Session session = Session.getActiveSession();
                            if (session != null && !session.isClosed()) {
                                session.closeAndClearTokenInformation();
                            }
                        }
                    };
                    break;

                case PERMISSION:
                    // request the publish permission
                    dialogBody = getString(R.string.error_permission);
                    listener = new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                          if (fragments[HOME] != null) {
                            ((HomeFragment) fragments[HOME]).setPendingPost(true);
                            ((HomeFragment) fragments[HOME]).requestPublishPermissions();
                          }
                        }
                    };
                    break;

                case SERVER:
                case THROTTLING:
                    // this is usually temporary, don't clear the fields, and
                    // ask the user to try again
                    dialogBody = getString(R.string.error_server);
                    break;

                case BAD_REQUEST:
                    // this is likely a coding error, ask the user to file a bug
                    dialogBody = getString(R.string.error_bad_request, error.getErrorMessage());
                    break;

                case CLIENT:
                  // this is likely an IO error, so tell the user they have a network issue
                  dialogBody = getString(R.string.network_error);
                    break;
                    
                case OTHER:
                default:
                    // an unknown issue occurred, this could be a code error, or
                    // a server side issue, log the issue, and either ask the
                    // user to retry, or file a bug
                    dialogBody = getString(R.string.error_unknown, error.getErrorMessage());
                    break;
            }
        }

        new AlertDialog.Builder(this)
                .setPositiveButton(R.string.error_dialog_button_text, listener)
                .setTitle(R.string.error_dialog_title)
                .setMessage(dialogBody)
                .show();
        
        if (logout) {
          logout();
        }
    }
  
  // Show user error message as a toast
  void showError(String error, boolean logout) {
    Toast.makeText(this, error, Toast.LENGTH_LONG).show();
    if (logout) {
      logout();
    }
  }
  
    private void logout() {
      Log.d(TAG, "Logging user out.");
      
      // log user out of Parse
      if (ParseUser.getCurrentUser() != null)
        ParseUser.logOut();
      
      // Close the session, which will cause a callback to show the logout screen
    Session.getActiveSession().closeAndClearTokenInformation();
    
    // Clear any permissions associated with the LoginButton
    LoginButton loginButton = (LoginButton) findViewById(R.id.loginButton);
    if (loginButton != null) {
      loginButton.clearPermissions();
    }
    }
  
}




Java Source Code List

com.facebook.android.friendsmash.FBLoggedOutHomeFragment.java
com.facebook.android.friendsmash.FBLoggedOutHomeFragment.java
com.facebook.android.friendsmash.FriendSmashApplication.java
com.facebook.android.friendsmash.FriendSmashApplication.java
com.facebook.android.friendsmash.GameActivity.java
com.facebook.android.friendsmash.GameActivity.java
com.facebook.android.friendsmash.GameFragment.java
com.facebook.android.friendsmash.GameFragment.java
com.facebook.android.friendsmash.HomeActivity.java
com.facebook.android.friendsmash.HomeActivity.java
com.facebook.android.friendsmash.HomeFragment.java
com.facebook.android.friendsmash.HomeFragment.java
com.facebook.android.friendsmash.InviteUserArrayAdapter.java
com.facebook.android.friendsmash.InviteUserArrayAdapter.java
com.facebook.android.friendsmash.RequestUserArrayAdapter.java
com.facebook.android.friendsmash.RequestUserArrayAdapter.java
com.facebook.android.friendsmash.ScoreboardActivity.java
com.facebook.android.friendsmash.ScoreboardActivity.java
com.facebook.android.friendsmash.ScoreboardEntry.java
com.facebook.android.friendsmash.ScoreboardEntry.java
com.facebook.android.friendsmash.ScoreboardFragment.java
com.facebook.android.friendsmash.ScoreboardFragment.java
com.facebook.android.friendsmash.SingleFragmentActivity.java
com.facebook.android.friendsmash.SingleFragmentActivity.java
com.facebook.android.friendsmash.UserImageView.java
com.facebook.android.friendsmash.UserImageView.java