me.trashout.fragment.EventTrashSelectorFragment.java Source code

Java tutorial

Introduction

Here is the source code for me.trashout.fragment.EventTrashSelectorFragment.java

Source

/*
 * TrashOut is an environmental project that teaches people how to recycle
 * and showcases the worst way of handling waste - illegal dumping.All you need is a smart phone.
 * 
 * 
 * There are 10 types of programmers - those who are helping TrashOut and those who are not.
 * Clean up our code, so we can clean up our planet.
 * Get in touch with us: help@trashout.ngo
 * 
 * Copyright 2017 TrashOut, n.f.
 * 
 * This file is part of the TrashOut project.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 * 
 * See the GNU General Public License for more details: <https://www.gnu.org/licenses/>.
 */

package me.trashout.fragment;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.util.ArrayList;
import java.util.HashMap;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import me.trashout.R;
import me.trashout.activity.MainActivity;
import me.trashout.api.base.ApiResult;
import me.trashout.api.base.ApiUpdate;
import me.trashout.api.result.ApiGetTrashListResult;
import me.trashout.fragment.base.BaseFragment;
import me.trashout.fragment.base.ITrashFragment;
import me.trashout.model.Trash;
import me.trashout.service.GetTrashListService;
import me.trashout.service.base.BaseService;

public class EventTrashSelectorFragment extends BaseFragment
        implements BaseService.UpdateServiceListener, ITrashFragment {

    private static final int GET_TRASH_LIST_REQUEST_ID = 202;
    private static final String BUNDLE_MEETING_POINT = "BUNDLE_MEETING_POINT";
    private static final String BUNDLE_SELECTED_TRASH_LIST = "BUNDLE_SELECTED_TRASH_LIST";

    @BindView(R.id.my_location_fab)
    FloatingActionButton myLocationFab;

    private GoogleMap mMap;
    private SupportMapFragment mMapFragment;

    private ArrayList<Trash> mTrashList = new ArrayList<>();

    private HashMap<Marker, Trash> markersTrashMap = new HashMap<>();
    private ArrayList<Long> selectedTrashIdList = new ArrayList<>();

    private LatLng mMeetingPoint;

    private EventCreateFragment.OnSelectTrashIdsOnMapListener mCallback;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        try {
            mCallback = (EventCreateFragment.OnSelectTrashIdsOnMapListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement OnHeadlineSelectedListener");
        }
    }

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

    public static EventTrashSelectorFragment newInstance(LatLng meetingPoint, ArrayList<Long> selectedTrashIdList) {
        Bundle b = new Bundle();
        b.putParcelable(BUNDLE_MEETING_POINT, meetingPoint);
        if (selectedTrashIdList != null && !selectedTrashIdList.isEmpty()) {
            long[] selectedTrashIdArray = new long[selectedTrashIdList.size()];
            for (int i = 0; i < selectedTrashIdArray.length; i++) {
                selectedTrashIdArray[i] = selectedTrashIdList.get(i);
            }
            b.putLongArray(BUNDLE_SELECTED_TRASH_LIST, selectedTrashIdArray);
        }
        EventTrashSelectorFragment ret = new EventTrashSelectorFragment();
        ret.setArguments(b);
        return ret;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_event_trash_selector, container, false);
        ButterKnife.bind(this, view);

        selectedTrashIdList = getSelectedTrashIdList();
        if (selectedTrashIdList == null) {
            selectedTrashIdList = new ArrayList<>();
        }

        if (mMapFragment == null) {
            mMapFragment = SupportMapFragment.newInstance();
        }
        if (!checkMapFragment()) {
            FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
            fragmentTransaction.add(R.id.mapContainer, mMapFragment, "event_trash_map");
            fragmentTransaction.commit();
        }

        preSetupMapIfNeeded();

        GetTrashListService.startForEventTrashMapRequest(getActivity(), GET_TRASH_LIST_REQUEST_ID, null,
                getMeetingPoint());
        return view;
    }

    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_event_select_trash, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {

        case R.id.action_save:
            if (selectedTrashIdList != null && !selectedTrashIdList.isEmpty() && mCallback != null) {
                mCallback.onTrashIdsOnMapSelected(selectedTrashIdList);
                finish();
            }
            return true;
        default:
            break;
        }

        return false;
    }

    private LatLng getMeetingPoint() {
        if (mMeetingPoint == null)
            mMeetingPoint = getArguments().getParcelable(BUNDLE_MEETING_POINT);
        return mMeetingPoint;
    }

    private ArrayList<Long> getSelectedTrashIdList() {
        ArrayList<Long> lastSelectedTrashIds = new ArrayList<>();
        long[] selectgadTrasArray = getArguments().getLongArray(BUNDLE_SELECTED_TRASH_LIST);
        if (selectgadTrasArray != null) {
            for (int i = 0; i < selectgadTrasArray.length; i++) {
                lastSelectedTrashIds.add(selectgadTrasArray[i]);
            }
        }
        return lastSelectedTrashIds;
    }

    /**
     * Check if map fragment was created
     *
     * @return
     */
    private boolean checkMapFragment() {
        Fragment mFragment = getChildFragmentManager().findFragmentByTag("map");
        return mFragment != null && mFragment instanceof SupportMapFragment;
    }

    /**
     * Prepare map and setup map data
     */
    private void preSetupMapIfNeeded() {
        if (mMap == null) {
            mMapFragment.getMapAsync(new OnMapReadyCallback() {
                @Override
                public void onMapReady(GoogleMap googleMap) {
                    mMap = googleMap;
                    setUpMapIfNeeded();
                    prepareMapObject(mTrashList);

                    if (getMeetingPoint() != null) {
                        goToMeetingPoint(getMeetingPoint());
                    } else {
                        goToMyLocation();
                    }
                }
            });
        } else {
            prepareMapObject(mTrashList);

            if (getMeetingPoint() != null) {
                goToMeetingPoint(getMeetingPoint());
            } else {
                goToMyLocation();
            }
        }
    }

    private void prepareMapObject(ArrayList<Trash> trashList) {
        if (mMap == null)
            return;

        Marker marker;

        mMap.clear();

        if (trashList != null) {
            for (Trash trash : trashList) {
                if (trash.getPosition() == null) {
                    continue;
                }
                marker = mMap.addMarker(createMarkerOptions(trash));
                markersTrashMap.put(marker, trash);
            }
        }

        mMap.addMarker(new MarkerOptions().position(getMeetingPoint())
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_map_marker_meeting_point)));

        mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                Trash markerTrash = markersTrashMap.get(marker);
                if (markerTrash == null) {
                    return false;
                }
                if (selectedTrashIdList.contains(markerTrash.getId())) {
                    selectedTrashIdList.remove(markerTrash.getId());
                    marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.ic_map_marker_reported));
                } else {
                    selectedTrashIdList.add(markerTrash.getId());
                    marker.setIcon(
                            BitmapDescriptorFactory.fromResource(R.drawable.ic_map_marker_reported_selected));
                }
                return false;
            }
        });
    }

    private MarkerOptions createMarkerOptions(Trash trash) {
        MarkerOptions markerOptions = new MarkerOptions().position(trash.getPosition())
                .icon(BitmapDescriptorFactory.fromResource(
                        selectedTrashIdList.contains(trash.getId()) ? R.drawable.ic_map_marker_reported_selected
                                : R.drawable.ic_map_marker_reported));
        return markerOptions;
    }

    /**
     * setup map and check location permission
     */
    private void setUpMapIfNeeded() {
        if (mMap != null) {
            if (ActivityCompat.checkSelfPermission(this.getActivity(),
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(this.getActivity(),
                            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "setUpMapIfNeeded: permission check");

                requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION }, 1);

                return;
            } else {
                mMap.setMyLocationEnabled(true);
            }

            mMap.getUiSettings().setMyLocationButtonEnabled(false);
            mMap.getUiSettings().setCompassEnabled(true);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == 1) {
            setUpMapIfNeeded();
        } else if (requestCode == 2) {
            goToMyLocation();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        ((MainActivity) getActivity()).setToolbarTitle("Nearby dumps");
    }

    private void goToMeetingPoint(LatLng meetingPoint) {
        if (mMap != null) {
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(meetingPoint, 15);
            mMap.animateCamera(cameraUpdate);
        }
    }

    /**
     * Go to my actual position
     */
    private void goToMyLocation() {

        if (ContextCompat.checkSelfPermission(this.getActivity(),
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this.getActivity(),
                        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "setUpMapIfNeeded: permission check");
            requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION }, 2);
        } else {
            GoogleApiClient mGoogleApiClient = ((MainActivity) getActivity()).getGoogleApiClient();
            Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (mLastLocation != null) {
                LatLng latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 15);
                mMap.animateCamera(cameraUpdate);
            }
        }
    }

    // SERVICE
    @Override
    protected BaseService.UpdateServiceListener getUpdateServiceListener() {
        return EventTrashSelectorFragment.this;
    }

    @Override
    protected ArrayList<Class<?>> getServiceClass() {
        ArrayList<Class<?>> serviceClass = new ArrayList<>();
        serviceClass.add(GetTrashListService.class);
        return serviceClass;
    }

    @Override
    public void onNewResult(ApiResult apiResult) {
        if (apiResult.getRequestId() == GET_TRASH_LIST_REQUEST_ID) {

            if (apiResult.isValidResponse()) {
                ApiGetTrashListResult apiGetTrashListResult = (ApiGetTrashListResult) apiResult.getResult();
                mTrashList = new ArrayList<>(apiGetTrashListResult.getTrashList());
                prepareMapObject(mTrashList);
            } else {
                showToast(R.string.global_error_api_text);
            }
        }
    }

    @Override
    public void onNewUpdate(ApiUpdate apiUpdate) {

    }

    @OnClick(R.id.my_location_fab)
    public void onClick() {
        goToMyLocation();
    }
}