org.croudtrip.activities.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.croudtrip.activities.MainActivity.java

Source

/*
 * The CroudTrip! application aims at revolutionizing the car-ride-sharing market with its easy,
 * user-friendly and highly automated way of organizing shared Trips. Copyright (C) 2015  Nazeeh Ammari,
 *  Philipp Eichhorn, Ricarda Hohn, Vanessa Lange, Alexander Popp, Frederik Simon, Michael Weber
 * This program is free software: you can redistribute it and/or modify  it under the terms of the GNU
 *  Affero General Public License as published by the Free Software Foundation, either version 3 of the
 *   License, or (at your option) any later version.
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero General Public License for more details.
 *  You should have received a copy of the GNU Affero General Public License along with this program.
 *    If not, see http://www.gnu.org/licenses/.
 */

package org.croudtrip.activities;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.location.LocationManager;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;

import com.google.android.gms.location.LocationRequest;

import org.croudtrip.Constants;
import org.croudtrip.R;
import org.croudtrip.account.AccountManager;
import org.croudtrip.api.TripsResource;
import org.croudtrip.api.account.User;
import org.croudtrip.fragments.ProfileFragment;
import org.croudtrip.fragments.SettingsFragment;
import org.croudtrip.fragments.join.JoinDispatchFragment;
import org.croudtrip.fragments.offer.DispatchOfferTripFragment;
import org.croudtrip.gcm.GcmManager;
import org.croudtrip.location.LocationUpdater;
import org.croudtrip.location.LocationUploadTimerReceiver;
import org.croudtrip.utils.CrashCallback;
import org.croudtrip.utils.DefaultTransformer;

import java.io.InputStream;
import java.net.URL;

import javax.inject.Inject;
import javax.net.ssl.HttpsURLConnection;

import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer;
import it.neokree.materialnavigationdrawer.elements.MaterialAccount;
import it.neokree.materialnavigationdrawer.elements.MaterialSection;
import pl.charmas.android.reactivelocation.ReactiveLocationProvider;
import rx.Observable;
import rx.Subscription;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.subscriptions.CompositeSubscription;
import timber.log.Timber;

/**
 * We will probably use fragments, so this activity works as a container for all these fragments and will probably do
 * some initialization and stuff
 */
public class MainActivity extends AbstractRoboDrawerActivity {

    //******************************** Variables ***********************************//

    // If a notification arrives this sometimes has to change the displayed screen.
    // These constants are used to determine which screen should be shown.
    public final static String ACTION_SHOW_JOIN_TRIP_REQUESTS = "SHOW_JOIN_TRIP_REQUESTS";
    public final static String ACTION_SHOW_REQUEST_ACCEPTED = "SHOW_REQUEST_ACCEPTED";
    public final static String ACTION_SHOW_REQUEST_DECLINED = "SHOW_REQUEST_DECLINED";
    public final static String ACTION_SHOW_FOUND_MATCHES = "SHOW_FOUND_MATCHES";
    public final static String ACTION_SHOW_JOIN_TRIP_FRAGMENT = "SHOW_JOIN_TRIP_FRAGMENT";

    @Inject
    private GcmManager gcmManager;
    @Inject
    private LocationUpdater locationUpdater;
    @Inject
    private TripsResource tripsResource;

    private CompositeSubscription subscriptions = new CompositeSubscription();
    private Subscription locationUpdateSubscription;

    //********************************* Methods ************************************//
    @Override
    protected void onNewIntent(Intent intent) {
        if (intent.getAction() != null && intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
            //user scanned an NFC tag -> notify the passenger driving UI to save new status and maybe update UI
            Intent startingIntent = new Intent(Constants.EVENT_NFC_TAG_SCANNED);
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(startingIntent);
        } else {
            Timber.d("Another Intent or detected some other NFC stuff...");
        }
    }

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

    @Override
    public void init(Bundle savedInstanceState) {

        // Configure Navigation Drawer
        this.disableLearningPattern();
        this.allowArrowAnimation();
        this.setBackPattern(MaterialNavigationDrawer.BACKPATTERN_BACK_TO_FIRST);
        this.setDrawerHeaderImage(R.drawable.background_drawer);

        // Get all the saved user data to display some info in the navigation drawer
        showUserInfoInNavigationDrawer();

        SharedPreferences prefs = getSharedPreferences(Constants.SHARED_PREF_FILE_PREFERENCES,
                Context.MODE_PRIVATE);

        // Start timer to update the user's offers all the time
        if (AccountManager.isUserLoggedIn(this)) {
            Intent alarmIntent = new Intent(this, LocationUploadTimerReceiver.class);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);

            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            alarmManager.cancel(pendingIntent);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 120 * 1000,
                    pendingIntent);
        }

        // Subscribe to location updates
        LocationRequest request = LocationRequest.create() //standard GMS LocationRequest
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(10000);

        ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(this);
        Subscription locationUpdateSubscription = locationProvider.getUpdatedLocation(request)
                .subscribe(new Action1<Location>() {
                    @Override
                    public void call(Location location) {
                        locationUpdater.setLastLocation(location);
                    }
                });

        subscriptions.add(locationUpdateSubscription);

        // GPS availability
        if (!GPSavailable()) {
            checkForGPS();
        }

        // Registration for GCM, if we are not registered yet
        if (!gcmManager.isRegistered()) {
            Subscription subscription = gcmManager.register().compose(new DefaultTransformer<Void>()).retry(3)
                    .subscribe(new Action1<Void>() {
                        @Override
                        public void call(Void aVoid) {
                            Timber.d("Registered at GCM.");
                        }
                    }, new CrashCallback(this, "failed to register for GCM"));
            subscriptions.add(subscription);
        }

        fillNavigationDrawer();
    }

    @Override
    public void onBackPressed() {
        if (getCurrentSection().getTargetFragment() instanceof JoinDispatchFragment) {
            JoinDispatchFragment currentFragment = (JoinDispatchFragment) getCurrentSection().getTargetFragment();
            if (!currentFragment.allowBackPressed()) {
                return;
            }
        }
        super.onBackPressed();
    }

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

        subscriptions.unsubscribe();
        subscriptions.clear();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

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

    private boolean GPSavailable() {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    private void checkForGPS() {
        final SharedPreferences prefs = getSharedPreferences(Constants.SHARED_PREF_FILE_PREFERENCES,
                Context.MODE_PRIVATE);
        final SharedPreferences.Editor editor = prefs.edit();

        AlertDialog.Builder adb = new AlertDialog.Builder(this);
        LayoutInflater adbInflater = LayoutInflater.from(this);
        View dialogLayout = adbInflater.inflate(R.layout.dialog_enable_gps, null);
        final CheckBox dontShowAgain = (CheckBox) dialogLayout.findViewById(R.id.skip);
        adb.setView(dialogLayout);
        adb.setTitle(getResources().getString(R.string.enable_gps_title));
        adb.setMessage(getResources().getString(R.string.enable_gps_description));
        adb.setPositiveButton(getResources().getString(R.string.enable_gps_ok),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        if (dontShowAgain.isChecked()) {
                            editor.putBoolean(Constants.SHARED_PREF_KEY_SKIP_ENABLE_GPS, true);
                            editor.apply();
                        }
                        startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));

                        return;
                    }
                });

        adb.setNegativeButton(getResources().getString(R.string.enable_gps_cancel),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        return;
                    }
                });

        adb.show();
    }

    public void showUserInfoInNavigationDrawer() {

        // Get logged-in user and his data
        User user = AccountManager.getLoggedInUser(getApplicationContext());
        String firstName = (user == null || user.getFirstName() == null) ? "" : user.getFirstName();
        String lastName = (user == null || user.getLastName() == null) ? "" : user.getLastName();
        String email = (user == null || user.getEmail() == null) ? "" : user.getEmail();
        final String avatarUrl = (user == null || user.getAvatarUrl() == null) ? null : user.getAvatarUrl();
        Timber.i("Nav drawer avatarUrl is: " + avatarUrl);
        final MaterialAccount account = new MaterialAccount(this.getResources(), firstName + " " + lastName, email,
                R.drawable.profile, R.drawable.background_drawer);
        this.addAccount(account);
        // Download his avatar
        if (avatarUrl != null) {
            Observable.defer(new Func0<Observable<Bitmap>>() {
                @Override
                public Observable<Bitmap> call() {
                    try {
                        URL url = new URL(avatarUrl);
                        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                        connection.setDoInput(true);
                        connection.connect();
                        InputStream input = connection.getInputStream();
                        return Observable.just(BitmapFactory.decodeStream(input));
                    } catch (Exception e) {
                        return Observable.error(e);
                    }
                }
            }).compose(new DefaultTransformer<Bitmap>()).subscribe(new Action1<Bitmap>() {
                @Override
                public void call(Bitmap avatar) {
                    Timber.d("avatar is null " + (avatar == null));
                    Timber.d("" + avatar.getWidth());
                    account.setPhoto(avatar);
                    notifyAccountDataChanged();
                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    Timber.e(throwable, "failed to download avatar");
                }
            });
        }
    }

    private void fillNavigationDrawer() {

        // Check the action that was given to the activity to determine the sections that
        // should be shown
        Intent intent = getIntent();
        String action = intent.getAction();
        action = (action == null) ? "" : action;

        // (0) JOIN TRIP
        JoinDispatchFragment joinDispatchFragment = new JoinDispatchFragment();
        joinDispatchFragment.setArguments(getIntent().getExtras());
        this.addSection(
                newSection(getString(R.string.menu_join_trip), R.drawable.hitchhiker, joinDispatchFragment));

        // (1) OFFER TRIP
        String offerName = getString(R.string.menu_offer_trip);
        SharedPreferences prefs = getSharedPreferences(Constants.SHARED_PREF_FILE_PREFERENCES, MODE_PRIVATE);
        if (prefs.getBoolean(Constants.SHARED_PREF_KEY_RUNNING_TRIP_OFFER, false)) {
            offerName = getString(R.string.menu_my_trip);
        }

        DispatchOfferTripFragment dispatchOfferTripFragment = new DispatchOfferTripFragment();
        dispatchOfferTripFragment.setArguments(getIntent().getExtras());
        this.addSection(newSection(offerName, R.drawable.ic_directions_car_white, dispatchOfferTripFragment));

        // (2) PROFILE
        if (AccountManager.isUserLoggedIn(this)) {
            // Only logged-in users can view their profile
            this.addSection(newSection(getString(R.string.menu_profile), R.drawable.ic_person_black_36dp,
                    new ProfileFragment()));
        }

        // (3) SETTINGS
        this.addBottomSection(
                newSection(getString(R.string.menu_settings), R.drawable.ic_settings, new SettingsFragment()));

        // Set the section that should be loaded at the start of the application
        if (action.equalsIgnoreCase(ACTION_SHOW_REQUEST_DECLINED) || action.equals(ACTION_SHOW_FOUND_MATCHES)) {
            this.setDefaultSectionLoaded(0);
            MaterialSection section = this.getSectionByTitle(getString(R.string.menu_my_trip));

            Bundle extras = getIntent().getExtras();
            Bundle bundle = new Bundle();
            bundle.putAll(extras);

            Fragment requestFrag = (Fragment) section.getTargetFragment();
            requestFrag.setArguments(bundle);

        } else if (action.equalsIgnoreCase(ACTION_SHOW_JOIN_TRIP_REQUESTS)) {
            this.setDefaultSectionLoaded(1); // Offer trip (My trip)
        } else if (action.equalsIgnoreCase(ACTION_SHOW_JOIN_TRIP_FRAGMENT)) {
            this.setDefaultSectionLoaded(0); //Join trip
        }
    }
}