Java tutorial
/* * 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); } }); } }