fr.cph.chicago.util.Util.java Source code

Java tutorial

Introduction

Here is the source code for fr.cph.chicago.util.Util.java

Source

/**
 * Copyright 2016 Carl-Philipp Harmant
 * <p>
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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 fr.cph.chicago.util;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import com.annimon.stream.Stream;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;

import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import fr.cph.chicago.R;
import fr.cph.chicago.core.App;
import fr.cph.chicago.data.Preferences;
import fr.cph.chicago.entity.BikeStation;
import fr.cph.chicago.entity.BusRoute;
import fr.cph.chicago.entity.Position;
import fr.cph.chicago.entity.enumeration.TrainLine;
import fr.cph.chicago.exception.ConnectException;
import fr.cph.chicago.exception.ParserException;

/**
 * Util class
 *
 * @author Carl-Philipp Harmant
 * @version 1
 */
public final class Util {

    public static final LatLng CHICAGO = new LatLng(41.8819, -87.6278);

    private static final Pattern PATTERN = Pattern.compile("(\\d{1,3})");

    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

    private Util() {
    }

    public static int generateViewId() {
        for (;;) {
            final int result = sNextGeneratedId.get();
            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
            int newValue = result + 1;
            if (newValue > 0x00FFFFFF)
                newValue = 1; // Roll over to 1, not 0.
            if (sNextGeneratedId.compareAndSet(result, newValue)) {
                return result;
            }
        }
    }

    /**
     * Add to train favorites
     *
     * @param stationId the station id
     * @param view      the view
     */
    public static void addToTrainFavorites(@NonNull final Integer stationId, @NonNull final View view) {
        final List<Integer> favorites = Preferences.getTrainFavorites(view.getContext(),
                App.PREFERENCE_FAVORITES_TRAIN);
        if (!favorites.contains(stationId)) {
            favorites.add(stationId);
            Preferences.saveTrainFavorites(view.getContext(), App.PREFERENCE_FAVORITES_TRAIN, favorites);
            showSnackBar(view, R.string.message_add_fav);
        }
    }

    /**
     * Remove train from favorites
     *
     * @param stationId the station id
     * @param view      the view
     */
    public static void removeFromTrainFavorites(@NonNull final Integer stationId, @NonNull final View view) {
        final List<Integer> favorites = Preferences.getTrainFavorites(view.getContext(),
                App.PREFERENCE_FAVORITES_TRAIN);
        favorites.remove(stationId);
        Preferences.saveTrainFavorites(view.getContext(), App.PREFERENCE_FAVORITES_TRAIN, favorites);
        showSnackBar(view, R.string.message_remove_fav);
    }

    /**
     * Remove from bus favorites
     *
     * @param busRouteId the bus route id
     * @param busStopId  the bus stop id
     * @param bound      the bus bound
     * @param view       the view
     */
    public static void removeFromBusFavorites(@NonNull final String busRouteId, @NonNull final String busStopId,
            @NonNull final String bound, @NonNull final View view) {
        final String id = busRouteId + "_" + busStopId + "_" + bound;
        final List<String> favorites = Preferences.getBusFavorites(view.getContext(), App.PREFERENCE_FAVORITES_BUS);
        favorites.remove(id);
        Preferences.saveBusFavorites(view.getContext(), App.PREFERENCE_FAVORITES_BUS, favorites);
        showSnackBar(view, R.string.message_remove_fav);
    }

    /**
     * Add to bus favorites
     *
     * @param busRouteId the bus route id
     * @param busStopId  the bus stop id
     * @param bound      the bus bound
     * @param view       the view
     */
    public static void addToBusFavorites(@NonNull final String busRouteId, @NonNull final String busStopId,
            @NonNull final String bound, @NonNull final View view) {
        final String id = busRouteId + "_" + busStopId + "_" + bound;
        final List<String> favorites = Preferences.getBusFavorites(view.getContext(), App.PREFERENCE_FAVORITES_BUS);
        if (!favorites.contains(id)) {
            favorites.add(id);
            Preferences.saveBusFavorites(view.getContext(), App.PREFERENCE_FAVORITES_BUS, favorites);
            showSnackBar(view, R.string.message_add_fav);
        }
    }

    public static void addToBikeFavorites(final int stationId, @NonNull final View view) {
        final List<String> favorites = Preferences.getBikeFavorites(view.getContext(),
                App.PREFERENCE_FAVORITES_BIKE);
        if (!favorites.contains(Integer.toString(stationId))) {
            favorites.add(Integer.toString(stationId));
            Preferences.saveBikeFavorites(view.getContext(), App.PREFERENCE_FAVORITES_BIKE, favorites);
            showSnackBar(view, R.string.message_add_fav);
        }
    }

    public static void removeFromBikeFavorites(final int stationId, @NonNull final View view) {
        final List<String> favorites = Preferences.getBikeFavorites(view.getContext(),
                App.PREFERENCE_FAVORITES_BIKE);
        favorites.remove(Integer.toString(stationId));
        Preferences.saveBikeFavorites(view.getContext(), App.PREFERENCE_FAVORITES_BIKE, favorites);
        showSnackBar(view, R.string.message_remove_fav);
    }

    /**
     * Decode bus favorites
     *
     * @param favorite the favorites
     * @return a tab containing the route id, the stop id and the bound
     */
    @NonNull
    public static String[] decodeBusFavorite(@NonNull final String favorite) {
        final int first = favorite.indexOf('_');
        final String routeId = favorite.substring(0, first);
        final int sec = favorite.indexOf('_', first + 1);
        final String stopId = favorite.substring(first + 1, sec);
        final String bound = favorite.substring(sec + 1, favorite.length());
        return new String[] { routeId, stopId, bound };
    }

    public static final Comparator<BikeStation> BIKE_COMPARATOR_NAME = new BikeStationComparator();

    private static final class BikeStationComparator implements Comparator<BikeStation> {
        @Override
        public int compare(final BikeStation station1, final BikeStation station2) {
            return station1.getName().compareTo(station2.getName());
        }
    }

    public static final Comparator<BusRoute> BUS_STOP_COMPARATOR_NAME = new BusStopComparator();

    private static final class BusStopComparator implements Comparator<BusRoute> {

        @Override
        public int compare(final BusRoute route1, final BusRoute route2) {
            final Matcher matcher1 = PATTERN.matcher(route1.getId());
            final Matcher matcher2 = PATTERN.matcher(route2.getId());
            if (matcher1.find() && matcher2.find()) {
                final int one = Integer.parseInt(matcher1.group(1));
                final int two = Integer.parseInt(matcher2.group(1));
                return one < two ? -1 : (one == two ? 0 : 1);
            } else {
                return route1.getId().compareTo(route2.getId());
            }
        }
    }

    public static boolean isNetworkAvailable(@NonNull final Context context) {
        final ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        final NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    public static int[] getScreenSize(@NonNull final Context context) {
        final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        final Display display = wm.getDefaultDisplay();
        final Point size = new Point();
        display.getSize(size);
        return new int[] { size.x, size.y };
    }

    /**
     * Google analytics track screen
     *
     * @param screen the screen name
     */
    public static void trackScreen(final Context context, final String screen) {
        final Tracker t = App.getTracker(context);
        t.setScreenName(screen);
        t.send(new HitBuilders.ScreenViewBuilder().build());
    }

    public static void trackAction(@NonNull final Context context, final int category, final int action,
            final String label, final int value) {
        new Thread(() -> {
            final Tracker tracker = App.getTracker(context.getApplicationContext());
            tracker.send(new HitBuilders.EventBuilder().setCategory(context.getString(category))
                    .setAction(context.getString(action)).setLabel(label).setValue(value).build());
        }).start();
    }

    public static void setWindowsColor(@NonNull final Activity activity, @NonNull final Toolbar toolbar,
            @NonNull final TrainLine trainLine) {
        int backgroundColor = 0;
        int statusBarColor = 0;
        //int navigationBarColor = 0;
        int textTitleColor = R.color.white;
        switch (trainLine) {
        case BLUE:
            backgroundColor = R.color.blueLine;
            statusBarColor = R.color.blueLineDark;
            break;
        case BROWN:
            backgroundColor = R.color.brownLine;
            statusBarColor = R.color.brownLineDark;
            break;
        case GREEN:
            backgroundColor = R.color.greenLine;
            statusBarColor = R.color.greenLineDark;
            break;
        case ORANGE:
            backgroundColor = R.color.orangeLine;
            statusBarColor = R.color.orangeLineDarker;
            break;
        case PINK:
            backgroundColor = R.color.pinkLine;
            statusBarColor = R.color.pinkLineDark;
            break;
        case PURPLE:
            backgroundColor = R.color.purpleLine;
            statusBarColor = R.color.purpleLineDark;
            break;
        case RED:
            backgroundColor = R.color.redLine;
            statusBarColor = R.color.redLineDark;
            break;
        case YELLOW:
            backgroundColor = R.color.yellowLine;
            statusBarColor = R.color.yellowLineDark;
            break;
        case NA:
            backgroundColor = R.color.primaryColor;
            statusBarColor = R.color.primaryColorDark;
            break;
        }
        toolbar.setBackgroundColor(ContextCompat.getColor(activity.getApplicationContext(), backgroundColor));
        toolbar.setTitleTextColor(ContextCompat.getColor(activity.getApplicationContext(), textTitleColor));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().setStatusBarColor(ContextCompat.getColor(activity, statusBarColor));
            activity.getWindow()
                    .setNavigationBarColor(ContextCompat.getColor(activity, R.color.primaryColorDarker));
        }
    }

    public static int getRandomColor() {
        final Random random = new Random();
        final List<TrainLine> keys = Collections.unmodifiableList(Arrays.asList(TrainLine.values()));
        return keys.get(random.nextInt(keys.size())).getColor();
    }

    public static void centerMap(@NonNull final SupportMapFragment mapFragment, @NonNull final Activity activity,
            @Nullable final Position position) {
        mapFragment.getMapAsync(googleMap -> {
            if (ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(activity,
                            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION }, 1);
                return;
            }
            googleMap.setMyLocationEnabled(true);
            if (position != null) {
                final LatLng latLng = new LatLng(position.getLatitude(), position.getLongitude());
                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
            } else {
                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CHICAGO, 10));
            }
        });
    }

    public static boolean textNumberToBoolean(@NonNull final String number) {
        return Boolean.parseBoolean(number);
    }

    @NonNull
    public static MultiValuedMap<String, String> getFavoritesTrainParams(@NonNull final Context context) {
        final MultiValuedMap<String, String> paramsTrain = new ArrayListValuedHashMap<>();
        final List<Integer> favorites = Preferences.getTrainFavorites(context, App.PREFERENCE_FAVORITES_TRAIN);
        Stream.of(favorites).forEach(
                favorite -> paramsTrain.put(context.getString(R.string.request_map_id), favorite.toString()));
        return paramsTrain;
    }

    @NonNull
    public static MultiValuedMap<String, String> getFavoritesBusParams(@NonNull final Context context) {
        final MultiValuedMap<String, String> paramsBus = new ArrayListValuedHashMap<>();
        final List<String> busFavorites = Preferences.getBusFavorites(context, App.PREFERENCE_FAVORITES_BUS);
        Stream.of(busFavorites).map(Util::decodeBusFavorite).forEach(fav -> {
            paramsBus.put(context.getString(R.string.request_rt), fav[0]);
            paramsBus.put(context.getString(R.string.request_stop_id), fav[1]);
        });
        return paramsBus;
    }

    /**
     * Function to show settings alert dialog
     */
    static void showSettingsAlert(@NonNull final Activity activity) {
        new Thread() {
            public void run() {
                activity.runOnUiThread(() -> {
                    final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
                    alertDialogBuilder.setTitle("GPS settings");
                    alertDialogBuilder.setMessage(
                            "GPS is not enabled. Do you want to go to settings main.java.fr.cph.chicago.res.menu?");
                    alertDialogBuilder.setCancelable(false).setPositiveButton("Yes", (dialog, id) -> {
                        final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        activity.startActivity(intent);
                    }).setNegativeButton("No", (dialog, id) -> dialog.cancel());
                    final AlertDialog alertDialog = alertDialogBuilder.create();
                    alertDialog.show();
                });
            }
        }.start();
    }

    public static int convertDpToPixel(@NonNull final Context context, final int dp) {
        float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                context.getResources().getDisplayMetrics());
        return (int) pixels;
    }

    public static void showNetworkErrorMessage(@NonNull final Activity activity) {
        showSnackBar(activity, R.string.message_network_error);
    }

    public static void showNetworkErrorMessage(@NonNull final View view) {
        showSnackBar(view, R.string.message_network_error);
    }

    public static void showMessage(@NonNull final Activity activity, final int message) {
        showSnackBar(activity, message);
    }

    public static void showMessage(@NonNull final View view, final int message) {
        showSnackBar(view, message);
    }

    private static void showSnackBar(@NonNull final Activity activity, final int message) {
        if (activity.getCurrentFocus() != null) {
            Snackbar.make(activity.getCurrentFocus(), activity.getString(message), Snackbar.LENGTH_SHORT).show();
        } else {
            Toast.makeText(activity, activity.getString(message), Toast.LENGTH_LONG).show();
        }
    }

    private static void showSnackBar(@NonNull final View view, final int message) {
        Snackbar.make(view, view.getContext().getString(message), Snackbar.LENGTH_SHORT).show();
    }

    public static void showOopsSomethingWentWrong(@NonNull final View view) {
        Snackbar.make(view, view.getContext().getString(R.string.message_something_went_wrong),
                Snackbar.LENGTH_SHORT).show();
    }

    public static void handleConnectOrParserException(@NonNull final Throwable throwable,
            @Nullable final Activity activity, @Nullable final View connectView, @NonNull final View parserView) {
        if (throwable.getCause() instanceof ConnectException) {
            if (activity != null) {
                showNetworkErrorMessage(activity);
            } else if (connectView != null) {
                showNetworkErrorMessage(connectView);
            }
        } else if (throwable.getCause() instanceof ParserException) {
            showOopsSomethingWentWrong(parserView);
        }
    }

    @NonNull
    public static String trimBusStopNameIfNeeded(@NonNull final String name) {
        if (name.length() > 25) {
            return name.substring(0, 24).trim() + "...";
        } else {
            return name;
        }
    }

    public static void setLocationOnMap(@NonNull final Activity activity, @NonNull final GoogleMap googleMap) {
        if (ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(activity,
                        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION }, 1);
            return;
        }
        googleMap.setMyLocationEnabled(true);
    }
}