com.sean.nanastudio.taoyuanstreetparking.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.sean.nanastudio.taoyuanstreetparking.MainActivity.java

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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.sean.nanastudio.taoyuanstreetparking;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.jakewharton.rxbinding.support.v7.widget.RxRecyclerView;
import com.jakewharton.rxbinding.support.v7.widget.RxSearchView;
import com.jakewharton.rxbinding.view.RxView;
import com.tbruyelle.rxpermissions.RxPermissions;

import java.util.List;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity
        implements MainView, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private static final int PERMISSION_REQUEST_LOCATION = 10001;

    private MainPresenter presenter;
    private GoogleApiClient googleApiClient;
    private Location lastLocation;

    private SearchView searchView;
    private MenuItem searchItem;

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

        presenter = new MainPresenterImpl(this, new MainModelImpl());
        presenter.onCreate();

    }

    @Override
    protected void onStart() {
        presenter.onStart();
        super.onStart();
    }

    @Override
    protected void onStop() {
        presenter.onStop();
        super.onStop();
    }

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

        if (presenter.viewIsInSearch()) {
            presenter.clearQueryStr();

        } else {
            finish();
        }
    }

    @Override
    public void setLayoutContentView() {
        setContentView(R.layout.activity_main);
    }

    @Override
    public void setActionBar() {

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(false);
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.search, menu);

        setSearchView(menu);

        searchItem = menu.findItem(R.id.action_search);
        MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                return true;
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                presenter.clearQueryStr();
                getStreetParkingInfosFromAPI();
                return true;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }

    private void setSearchView(Menu menu) {

        searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));

        SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        RxSearchView.queryTextChanges(searchView).subscribe(charSequence -> {
            presenter.search(String.valueOf(charSequence));
        });

        searchView.setOnQueryTextFocusChangeListener((view, b) -> {
            if (b)
                getFabLocation().hide();
            else
                getFabLocation().show();
        });
    }

    @Override
    public void getStreetParkingInfosFromAPI() {

        Observable.fromCallable(() -> presenter.getStreetParkingInfos()).subscribeOn(Schedulers.io())
                .doOnSubscribe(this::showProgress).subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(streetParkingInfos -> {
                    setRvStreetParking(streetParkingInfos);
                    hideProgressAndRefresh();
                });

    }

    @Override
    public void setRvStreetParking(List<StreetParkingInfo> streetParkingInfos) {

        getRvStreetParking().setHasFixedSize(true);
        getRvStreetParking().setLayoutManager(new LinearLayoutManager(this));
        getRvStreetParking().setAdapter(new StringParkingAdapter(this, streetParkingInfos));

        // Set listener
        setScrollListener();
        setSwipeRefreshLayout();
    }

    private void setScrollListener() {

        RxRecyclerView.scrollEvents(getRvStreetParking()).subscribe(recyclerViewScrollEvent -> {
            if (recyclerViewScrollEvent.dy() > 0) {
                getFabLocation().hide();

            } else {
                getFabLocation().show();
            }
        });

        RxRecyclerView.scrollStateChanges(getRvStreetParking()).subscribe(integer -> {
            if (integer == 0) {
                getFabLocation().show();
            }
        });

    }

    private void setSwipeRefreshLayout() {
        getSrlStreetParking().setOnRefreshListener(() -> presenter.refresh());
    }

    @Override
    public void setFabLocationListener() {

        RxView.clicks(getFabLocation()).throttleFirst(1, TimeUnit.SECONDS)
                .compose(RxPermissions.getInstance(this).ensure(Manifest.permission.ACCESS_COARSE_LOCATION))
                .subscribe(granted -> {
                    if (granted) {
                        getLocation(lastLocation);

                    } else {
                        requestLocationPermission();
                    }

                });

    }

    @Override
    public void requestLocationPermission() {
        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {

                new AlertDialog.Builder(MainActivity.this)
                        .setTitle(getResources().getString(R.string.location_permission_title))
                        .setMessage(getResources().getString(R.string.location_permission_message))
                        .setPositiveButton(getResources().getString(R.string.grant), (dialogInterface, i) -> {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[] { Manifest.permission.ACCESS_COARSE_LOCATION },
                                    PERMISSION_REQUEST_LOCATION);
                        }).setNegativeButton(getResources().getString(R.string.deny), (dialogInterface, i) -> {
                            dialogInterface.dismiss();
                        }).show();

            } else {

                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[] { Manifest.permission.ACCESS_COARSE_LOCATION }, PERMISSION_REQUEST_LOCATION);

            }

        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
        case PERMISSION_REQUEST_LOCATION: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getLocation(lastLocation);

            } else {
                Snackbar.make(getContainer(), getResources().getString(R.string.location_permission_deny),
                        Snackbar.LENGTH_LONG).setAction(getResources().getString(R.string.setting), view -> {
                            startInstalledAppDetailsActivity(MainActivity.this);
                        }).show();
            }
            break;
        }
        }
    }

    private void getLocation(final Location location) {

        Observable.fromCallable(() -> presenter.getLocation(location)).subscribeOn(Schedulers.io())
                .doOnSubscribe(this::showProgress).subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(s -> {
                    if (!"".equals(s.trim())) {
                        boolean hasResult = presenter.search(s);
                        if (!hasResult) {
                            showNoResult(s);
                        }

                    } else {
                        showNoResult(s);

                    }

                    hideProgressAndRefresh();
                });
    }

    public static void startInstalledAppDetailsActivity(final Activity context) {
        if (context == null) {
            return;
        }
        final Intent i = new Intent();
        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.setData(Uri.parse("package:" + context.getPackageName()));
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(i);
    }

    // Google api control

    @Override
    public void initialGoogleApiClient() {
        if (googleApiClient == null) {
            googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
        }
    }

    @Override
    public void connectGoogleApiClient() {
        if (googleApiClient != null)
            googleApiClient.connect();
    }

    @Override
    public void disconnectGoogleApiClient() {
        if (googleApiClient != null)
            googleApiClient.disconnect();
    }

    @Override
    public String getApiKey() {
        return getResources().getString(R.string.API_KEY);
    }

    // Google service callback

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    }

    @Override
    public void onConnectionSuspended(int i) {
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    // Ui control

    @Override
    public void showProgress() {
        if (!getSrlStreetParking().isRefreshing())
            getSrlStreetParking().setRefreshing(true);
    }

    @Override
    public void hideProgressAndRefresh() {
        getSrlStreetParking().setRefreshing(false);
    }

    @Override

    public void showNoResult(String queryStr) {

        String snackBarMessage;

        if ("".equals(queryStr.trim())) {
            snackBarMessage = getResources().getString(R.string.no_result);

        } else {
            snackBarMessage = String.format("%s %s %s", getResources().getString(R.string.no_result_1), queryStr,
                    getResources().getString(R.string.no_result_2));
        }

        presenter.clearQueryStr();

        Snackbar.make(getContainer(), snackBarMessage, Snackbar.LENGTH_LONG)
                .setAction(getResources().getString(R.string.search_by_user_self), view -> {

                    searchItem.expandActionView();
                    searchView.onActionViewExpanded();
                    searchView.setFocusable(true);
                    searchView.setIconified(false);
                    searchView.setQuery("", false);
                    searchView.requestFocus();
                    searchView.requestFocusFromTouch();
                }).show();
    }

    // Get views's id..

    private CoordinatorLayout getContainer() {
        return (CoordinatorLayout) findViewById(R.id.container);
    }

    private SwipeRefreshLayout getSrlStreetParking() {
        return (SwipeRefreshLayout) findViewById(R.id.swlStreetParking);
    }

    private RecyclerView getRvStreetParking() {
        return (RecyclerView) findViewById(R.id.rvStreetParking);
    }

    private FloatingActionButton getFabLocation() {
        return (FloatingActionButton) findViewById(R.id.fabLocation);
    }

}