Logowanie do aplikacji przez Web Service

Nastał ten piękny moment kiedy kilka modułów aplikacji zostało sklejonych i pojawiają się coraz większe zalążki całej aplikacji. W tym poście przedstawię proces dodawania i modyfikowania poprzedniego stworzonego kodu, efektem działań jest logowanie do aplikacji za pomocą aplikacji i możliwość wyświetlenia swojego profilu.

pexels-photo-219003

Klasa FacebookLogin

Klasa została prawie cała przebudowana. Dodane zostały funkcjonalności pozwalające zapisać nowego użytkownika do bazy oraz zapisanie zalogowanego użytkownika do klasy SaveSharedPreference, o której za chwilę. Poniżej umieszczam aktualny kod klasy FacebookLogin, trzeba przyznać, że trochę się rozrosła w porównaniu do pierwszej wersji.

public class FacebookLogin extends Fragment {

    private CallbackManager callbackManager;
    private LoginButton loginButton;
    private boolean postingEnabled = false;
    private ProfileTracker profileTracker;
    private TextView greeting;
    private String url;
    private String emailCheckStatus;
    private FacebookLogin instance;
    private String lastLocalization;
    private String addingNewUser;
    private int userId;
    private AccessTokenTracker fbTracker;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        instance = this;

        FacebookSdk.sdkInitialize(getActivity());
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }

    @Nullable
    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.facebook_login, parent, false);
        greeting = (TextView) v.findViewById(R.id.greeting);

        loginButton = (LoginButton) v.findViewById(R.id.login_button);
        loginButton.setFragment(this);
        loginButton.setReadPermissions(Arrays.asList(
                "public_profile", "email", "user_birthday", "user_location"));
        callbackManager = CallbackManager.Factory.create();
        loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                Toast toast = Toast.makeText(getActivity(), "Logged In", Toast.LENGTH_SHORT);
                postingEnabled = true;

                GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
                        new GraphRequest.GraphJSONObjectCallback() {
                            @Override
                            public void onCompleted(JSONObject object, GraphResponse response) {
                                try {
                                    String first_name = object.getString("first_name");
                                    String last_name = object.getString("last_name");
                                    String email = object.getString("email");
                                    String birthdaySource = object.getString("birthday");
                                    String[] date = birthdaySource.split("/");
                                    String birthday = date[2] + ", " + date[1] + ", " + date[0];
                                    String city = object.getJSONObject("location").getString("name");

                                    url = "http://chinet.cba.pl/meethere.php?thatEmail=" + email;

                                    try {
                                        emailCheckStatus = new dbOperation(instance).execute().get();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    } catch (ExecutionException e) {
                                        e.printStackTrace();
                                    }

                                    if (Objects.equals(emailCheckStatus, "success")) {
                                        LocationTracker locationTracker = LocationTracker.getInstance();

                                        if (locationTracker.canGetLocation()) {
                                            lastLocalization = locationTracker.getLatitude()
                                                    + ", " + locationTracker.getLongitude();
                                        }
                                        locationTracker.stopUsingGPS();

                                        url = "http://chinet.cba.pl/meethere.php?addUser="
                                                + first_name + "&surname=" + last_name + "&email="
                                                + email + "&city=" + city + "&dayOfBirthday="
                                                + birthday + "&lastLocalization=" + lastLocalization;

                                        try {
                                            addingNewUser = new dbOperation(instance).execute().get();
                                            userId = Integer.parseInt(addingNewUser);
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        } catch (ExecutionException e) {
                                            e.printStackTrace();
                                        }
                                    } else {
                                        Log.d("Email check", "fail");
                                        userId = Integer.parseInt(emailCheckStatus);
                                    }

                                    SaveSharedPreference.setPrefId(getContext(), userId);

                                    Log.d("UserFacebookData", email + birthday + city);
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                Bundle parameters = new Bundle();
                parameters.putString("fields", "id,first_name,last_name,birthday,location,link,email");
                request.setParameters(parameters);
                request.executeAsync();

                loginButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        LoginManager.getInstance().logInWithReadPermissions(getActivity(), Arrays.asList("public_profile"));
                        if(!postingEnabled) {
                            postingEnabled = true;
                        }else{
                            postingEnabled = false;

                        }
                    }
                });

                toast.show();
                updateUI();
            }

            @Override
            public void onCancel() {
                updateUI();
            }

            @Override
            public void onError(FacebookException exception) {
                updateUI();

            }
        });

        fbTracker = new AccessTokenTracker() {
            @Override
            protected void onCurrentAccessTokenChanged(AccessToken accessToken, AccessToken accessToken2) {
                if (accessToken2 == null) {
                    Log.d("FB", "User Logged Out.");
                    SharedPreferences.Editor editor = getSharedPreferences(getContext()).edit();
                    editor.clear();
                    editor.commit();
                }
            }
        };

        profileTracker = new ProfileTracker() {
            @Override
            protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
                updateUI();
            }
        };

        return v;
    }

    @Override
    public void onResume() {
        super.onResume();

        // Call the 'activateApp' method to log an app event for use in analytics and advertising
        // reporting.  Do so in the onResume methods of the primary Activities that an app may be
        // launched into.
        AppEventsLogger.activateApp(getActivity());

        updateUI();
    }

    @Override
    public void onPause() {
        super.onPause();

        // Call the 'deactivateApp' method to log an app event for use in analytics and advertising
        // reporting.  Do so in the onPause methods of the primary Activities that an app may be
        // launched into.
        AppEventsLogger.deactivateApp(getActivity());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        profileTracker.stopTracking();
    }

    private void updateUI() {
        boolean enableButtons = AccessToken.getCurrentAccessToken() != null;

        Profile profile = Profile.getCurrentProfile();
        if (enableButtons && profile != null) {
            greeting.setText(getString(R.string.hello_user, profile.getFirstName()));
        } else {
            greeting.setText(null);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    private class dbOperation extends AsyncTask<String, Void, String> {

        private static final String TAG = "dbOperation";
        private FacebookLogin facebookLogin;

        public dbOperation(FacebookLogin facebookLogin) {
            this.facebookLogin = facebookLogin;
        }

        @Override
        protected String doInBackground(String... strings) {

            WebServiceHandler webServiceHandler = new WebServiceHandler();
            String jsonStr = webServiceHandler.makeServiceCall(url);

            Log.d(TAG, "Response form url: " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject jsonObject = new JSONObject(jsonStr);
                    String response = jsonObject.getString("operation");
                    String id = jsonObject.getString("id");

                    if (Objects.equals(response, "success")) {
                        return "success";
                    } else {
                        return id;
                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return "fail";
        }
    }
}

Z racji, że klasa FacebookLogin dziedziczy teraz po klasie Fragment, potrzebne jest jej wywołanie w LoginActivity:

FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);

if (fragment == null) {
    fragment = new FacebookLogin();
    fm.beginTransaction()
            .add(R.id.fragment_container, fragment)
            .commit();
}

Plik z layoutem FacebookLogin wygląda następująco:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:facebook="http://schemas.android.com/apk/res-auto"     android:orientation="vertical"     android:layout_width="match_parent"     android:layout_height="match_parent">

    <TextView         android:id="@+id/greeting"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_marginLeft="10dp"         android:layout_gravity="center"         android:textColor="#333"         android:textSize="18sp"/>

    <com.facebook.login.widget.LoginButton         android:id="@+id/login_button"         android:layout_width="250dp"         android:layout_height="wrap_content"         android:layout_marginTop="5dp"         android:layout_gravity="center_horizontal"         facebook:com_facebook_confirm_logout="true"         facebook:com_facebook_tooltip_mode="never_display"         />

</LinearLayout>

Przechowywanie zalogowanego użytkownika w pamięci

Zanim przejdziemy do klasy odpowiedzialnej za całą magię, wypadałoby wspomnieć o modyfikacjach jakich dokonałem w klasie UserActivity. Klasa pobiera ID użytkownika z klasy SaveSharedPreference i sprawdza czy to ID nie jest równe 0. Jeśli tak oznacza to, że użytkownik nie jest zalogowany i jest przekierowywany do aktywności logowania, w przeciwnym wypadku kod klasy wykonywany jest normalnie.

userId = SaveSharedPreference.getId(getApplicationContext());

if (userId == 0) {
    Intent intent = new Intent(this, LoginActivity.class);
    startActivity(intent);

} else {
//UserActivity code
}

Nadszedł czas na klasę SaveSharedPreference jej zadaniem jest przechowywanie numeru ID zalogowanego użytkownika. Jeśli ktoś będzie chciał pobrać ID, kiedy nikt nie jest zalogowany zostanie mu zwrócone 0 oznaczające brak takiego użytkownika.

public class SaveSharedPreference {

    static final String PREF_ID = "ID";

    static SharedPreferences getSharedPreferences(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context);
    }

    public static void setPrefId(Context context, int id) {
        Editor editor = getSharedPreferences(context).edit();
        editor.putInt(PREF_ID, id);
        editor.commit();
    }

    public static int getId(Context context) {
        if (getSharedPreferences(context).contains(PREF_ID)) {
            return getSharedPreferences(context).getInt(PREF_ID, ' ');
        } else {
            return 0;
        }
    }
}

Przede mną jeszcze dużo pracy nad aplikacją, ale pierwsze widoczne, działające zalążki gotowej aplikacji tylko motywują do dalszej pracy.

2 uwagi do wpisu “Logowanie do aplikacji przez Web Service

  1. Fajna sprawa!
    Jak będziesz miał chwilę to postaraj się trochę „uszczuplić” metodę onCreateView – z tego co widzę ma ok.130 linii – warto ją rozbić na kilka ‚podmetod’. Żeby powrót do kodu po większej przerwie nie był kłopotem 🙂

    Dobra robota! 🙂

    Polubienie

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s