jp.co.ipublishing.esnavi.activities.ShelterDetailActivity.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.ipublishing.esnavi.activities.ShelterDetailActivity.java

Source

/*
 * Copyright 2015 iPublishing Co., Ltd.
 *
 * 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 jp.co.ipublishing.esnavi.activities;

import android.content.Intent;
import android.graphics.Bitmap;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

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

import org.apache.commons.lang3.exception.ExceptionUtils;

import javax.inject.Inject;

import de.greenrobot.event.EventBus;
import icepick.Icepick;
import icepick.Icicle;
import jp.co.ipublishing.aeskit.helpers.dagger.ObjectGraph;
import jp.co.ipublishing.aeskit.shelter.ShelterManager;
import jp.co.ipublishing.aeskit.shelter.events.ShelterUpdatedCurrentNumberOfPeopleEvent;
import jp.co.ipublishing.aeskit.shelter.models.Shelter;
import jp.co.ipublishing.aeskit.shelter.models.ShelterNumberOfPeople;
import jp.co.ipublishing.esnavi.R;
import jp.co.ipublishing.esnavi.helpers.android.AppActivity;
import jp.co.ipublishing.esnavi.views.ArcView;
import jp.co.ipublishing.esnavi.factories.ShelterImageFactory;
import rx.Subscriber;
import rx.schedulers.Schedulers;

/**
 * ??
 */
public class ShelterDetailActivity extends AppActivity implements LocationListener {
    private static final String TAG = "ShelterDetailActivity";

    /**
     * Intent???ID????
     */
    public static final String EXTRA_SHELTER_ID = "SHELTER_ID";

    /**
     * ???????
     */
    private static final double OVER_CAPACITY_LIMIT = 0.85;

    /**
     * ???ID
     */
    private int mShelterId;

    /**
     * ??
     */
    @Nullable
    Shelter mShelter;

    /**
     * ??
     */
    @Icicle
    int mCurrentNumber = -1;

    /**
     * ???????[m]
     */
    @Icicle
    double mDistance = -1;

    /**
     * ??
     */
    @Nullable
    private LocationRequest mLocationRequest;

    /**
     * ???
     */
    @NonNull
    @Inject
    ShelterManager mShelterManager;

    /**
     * ??
     */
    @NonNull
    @Inject
    ShelterImageFactory mShelterImageFactory;

    /**
     * ??
     */
    @NonNull
    private ImageView mShelterImage;

    /**
     * ?
     */
    @NonNull
    private ArcView mPercentView;

    /**
     * 
     */
    @NonNull
    private TextView mCapacityValue;

    /**
     * ??
     */
    @NonNull
    private TextView mCurrentValue;

    /**
     * 
     */
    @NonNull
    private TextView mAltitudeValue;

    /**
     * ?????
     */
    @NonNull
    private TextView mDistanceValue;

    /**
     * ??
     */
    @NonNull
    private TextView mOverCapacityText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shelter_detail);

        setSupportActionBar((Toolbar) findViewById(R.id.detail_toolbar));
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        ObjectGraph.inject(this);

        Icepick.restoreInstanceState(this, savedInstanceState);

        mShelterId = getIntent().getIntExtra(EXTRA_SHELTER_ID, -1);

        mShelterImage = (ImageView) findViewById(R.id.shelter_image);
        mPercentView = (ArcView) findViewById(R.id.percent_view);
        mCapacityValue = (TextView) findViewById(R.id.capacity_value);
        mCurrentValue = (TextView) findViewById(R.id.current_value);
        mAltitudeValue = (TextView) findViewById(R.id.altitude_value);
        mDistanceValue = (TextView) findViewById(R.id.distance_value);
        mOverCapacityText = (TextView) findViewById(R.id.over_capacity_text);

        findViewById(R.id.navi_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startNavigation(mShelter);
            }
        });
        findViewById(R.id.other_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showOtherShelters(mShelter);
            }
        });

        updateLayout(mShelter, mCurrentNumber, mDistance);
    }

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

        EventBus.getDefault().register(this);

        if (mShelter == null) {
            updateShelter();
        } else {
            updateLayout(mShelter, mCurrentNumber, mDistance);
        }

        updateCurrentNumber();
    }

    @Override
    protected void onPause() {
        EventBus.getDefault().unregister(this);

        super.onPause();
    }

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

        Icepick.saveInstanceState(this, outState);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_detail, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final int id = item.getItemId();

        if (id == R.id.action_refresh) {
            onMenuRefresh();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConnected(Bundle bundle) {
        super.onConnected(bundle);

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(1000);

        LocationServices.FusedLocationApi.requestLocationUpdates(getGoogleApiClient(), mLocationRequest, this);
    }

    /**
     * ???????
     *
     * @param event 
     */
    public void onEvent(ShelterUpdatedCurrentNumberOfPeopleEvent event) {
        mCurrentNumber = event.getNumberOfPeople().getNumber(mShelterId);

        updateLayout(mShelter, mCurrentNumber, mDistance);
    }

    /**
     * ?
     */
    private void onMenuRefresh() {
        updateShelter();
        updateCurrentNumber();
    }

    /**
     * ?
     */
    private void updateShelter() {
        mShelterManager.fetchShelter(mShelterId).subscribeOn(Schedulers.newThread())
                .subscribe(new Subscriber<Shelter>() {
                    @Override
                    public void onCompleted() {
                        // Nothing to do
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, ExceptionUtils.getStackTrace(e));
                        showErrorDialog(R.string.dialog_title_failed, R.string.error_fetch_shelter, e);
                    }

                    @Override
                    public void onNext(Shelter shelter) {
                        mShelter = shelter;
                        updateLayout(mShelter, mCurrentNumber, mDistance);
                    }
                });
    }

    /**
     * ???
     */
    private void updateCurrentNumber() {
        mShelterManager.downloadNumberOfPeople().subscribeOn(Schedulers.newThread())
                .subscribe(new Subscriber<ShelterNumberOfPeople>() {
                    @Override
                    public void onCompleted() {
                        // Nothing to do
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, ExceptionUtils.getStackTrace(e));
                        showErrorDialog(R.string.dialog_title_failed, R.string.error_download_current_number, e);
                    }

                    @Override
                    public void onNext(ShelterNumberOfPeople shelterNumberOfPeople) {
                        mCurrentNumber = shelterNumberOfPeople.getNumber(mShelterId);
                        updateLayout(mShelter, mCurrentNumber, mDistance);
                    }
                });
    }

    /**
     * ??
     *
     * @param shelter       ?
     * @param currentNumber ??
     * @param distance      ?????
     */
    private void updateLayout(@Nullable final Shelter shelter, final int currentNumber, final double distance) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (shelter == null) {
                    setTitle("");
                    mShelterImage.setImageBitmap(null);
                    mPercentView.setPercent(-1);
                    mCapacityValue.setText(R.string.default_capacity);
                    mCurrentValue.setText(R.string.default_current);
                    mAltitudeValue.setText(R.string.default_altitude);
                    mDistanceValue.setText(R.string.default_distance);
                    mOverCapacityText.setVisibility(View.INVISIBLE);
                } else {
                    setTitle(shelter.getName());
                    mShelterImage.setImageBitmap(getShelterImageBitmap(shelter));

                    if (currentNumber == -1) {
                        mPercentView.setPercent(-1);
                    } else {
                        final int proportion = (int) ((currentNumber / shelter.getCapacity()) * 100.0);
                        mPercentView.setPercent(proportion);
                    }

                    if (shelter.getCapacity() == -1) {
                        mCapacityValue.setText(R.string.default_capacity);
                    } else {
                        mCapacityValue.setText(String.format(getResources().getString(R.string.format_capacity),
                                shelter.getCapacity()));
                    }

                    if (mCurrentNumber == -1) {
                        mCurrentValue.setText(R.string.default_current);
                    } else {
                        mCurrentValue.setText(
                                String.format(getResources().getString(R.string.format_current), currentNumber));
                    }

                    if (shelter.getAltitude() == -1) {
                        mAltitudeValue.setText(R.string.default_altitude);
                    } else {
                        mAltitudeValue.setText(String.format(getResources().getString(R.string.format_altitude),
                                shelter.getAltitude()));
                    }

                    updateDistance(distance);
                    updateOverCapacityText(shelter, currentNumber);
                }
            }
        });
    }

    /**
     * ??????
     */
    private void updateDistance(double distance) {
        if (mDistance == -1) {
            mDistanceValue.setText(R.string.default_distance);
        } else {
            mDistanceValue.setText(String.format(getResources().getString(R.string.format_distance), distance));
        }
    }

    /**
     * ?????
     *
     * @param shelter       ?
     * @param currentNumber ??
     */
    private void updateOverCapacityText(@Nullable Shelter shelter, int currentNumber) {
        if (currentNumber == -1 || shelter == null) {
            mOverCapacityText.setVisibility(View.INVISIBLE);
        } else {
            final double proportion = currentNumber / shelter.getCapacity();
            final boolean visible = proportion >= OVER_CAPACITY_LIMIT;
            mOverCapacityText.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
        }
    }

    /**
     * ????
     *
     * @param shelter ?
     * @return ??
     */
    @Nullable
    private Bitmap getShelterImageBitmap(@Nullable Shelter shelter) {
        if (shelter == null) {
            return null;
        }

        return mShelterImageFactory.getPhoto(this, shelter.getId());
    }

    /**
     * ?
     */
    private void startNavigation(@Nullable final Shelter shelter) {
        if (shelter == null) {
            // TODO: ?????
            return;
        }

        // TODO: ????
        final Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setClassName("com.google.android.apps.maps",
                "com.google.android.maps.driveabout.app.NavigationActivity");

        final Uri uri = Uri.parse(String.format("google.navigation:///?ll=%f,%f&q=%s&mode=w",
                shelter.getCoordinates().latitude, shelter.getCoordinates().longitude, shelter.getName()));

        intent.setData(uri);

        startActivity(intent);
    }

    /**
     * ????
     *
     * @param ignoreShelter ??
     */
    private void showOtherShelters(@Nullable Shelter ignoreShelter) {
        if (ignoreShelter == null) {
            return;
        }

        final Intent intent = new Intent(this, ShelterListActivity.class);
        intent.putExtra(ShelterListActivity.EXTRA_IGNORE_SHELTER_ID, ignoreShelter.getId());
        startActivity(intent);
    }

    @Override
    public void onLocationChanged(Location location) {
        if (mShelter == null) {
            return;
        }

        float[] results = new float[1];
        Location.distanceBetween(location.getLatitude(), location.getLongitude(),
                mShelter.getCoordinates().latitude, mShelter.getCoordinates().longitude, results);

        mDistance = results[0];

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateDistance(mDistance);
            }
        });
    }
}