package org.fitchfamily.android.gsmlocation.ui.database; import android.Manifest; import android.annotation.TargetApi; import android.app.Activity; import android.content.pm.PackageManager; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.text.format.DateUtils; import android.view.View; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.ViewSwitcher; import com.octo.android.robospice.persistence.DurationInMillis; import com.octo.android.robospice.persistence.exception.SpiceException; import com.octo.android.robospice.request.listener.PendingRequestListener; import com.octo.android.robospice.request.listener.RequestCancellationListener; import com.octo.android.robospice.request.listener.RequestProgress; import com.octo.android.robospice.request.listener.RequestProgressListener; import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Click; import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.InstanceState; import org.androidannotations.annotations.UiThread; import org.androidannotations.annotations.ViewById; import org.fitchfamily.android.gsmlocation.R; import org.fitchfamily.android.gsmlocation.Settings; import org.fitchfamily.android.gsmlocation.async.DownloadSpiceRequest; import org.fitchfamily.android.gsmlocation.ui.base.BaseFragment; @EFragment(R.layout.fragment_update_database) public class UpdateDatabaseFragment extends BaseFragment implements PendingRequestListener<DownloadSpiceRequest.Result>, RequestCancellationListener, RequestProgressListener { private static final int PAGE_PROGRESS = 1; private static final int PAGE_INFO = 0; private static final int DETAILS_PAGE_BUTTON = 0; private static final int DETAILS_PAGE_LOG = 1; private static final int REQUEST_PERMISSION_STORAGE = 2; @ViewById protected TextView progressString; @ViewById protected ProgressBar progress; @ViewById protected ViewSwitcher switcher; @ViewById protected TextView lastUpdate; @ViewById protected ViewSwitcher detailsSwitcher; @ViewById protected TextView log; @ViewById protected TextView errorSources; @ViewById protected TextView errorPermission; @ViewById protected Button settings; @ViewById protected Button permissionAllow; @ViewById protected Button update; @InstanceState protected boolean showLog; private Listener listener; @AfterViews protected void init() { setShowLog(showLog); } @Override public void onStart() { super.onStart(); updateLastDatabaseUpdate(); updateShownErrors(); registerListener(); } private void registerListener() { onDownloadStarted(); getSpiceManager().addListenerIfPending(DownloadSpiceRequest.Result.class, DownloadSpiceRequest.CACHE_KEY, this); } @Click protected void update() { onDownloadStarted(); getSpiceManager().execute(new DownloadSpiceRequest(getContext()), DownloadSpiceRequest.CACHE_KEY, DurationInMillis.ALWAYS_EXPIRED, this); } @Click protected void cancel() { getSpiceManager().cancel(DownloadSpiceRequest.Result.class, DownloadSpiceRequest.CACHE_KEY); } @Click protected void details() { setShowLog(true); } @Click protected void settings() { listener.openSettings(); } @Click protected void permissionAllow() { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_STORAGE); } private void onDownloadDone() { switcher.setDisplayedChild(PAGE_INFO); setShowLog(false); } private void onDownloadStarted() { switcher.setDisplayedChild(PAGE_PROGRESS); resetProgress(); } void setProgress(int current, int max) { final boolean end = current == max; progress.setProgress(current); progress.setMax(max); progress.setIndeterminate(end); final float percent = ((float) current * 100.f) / ((float) max); progressString.setText(end ? null : (String.valueOf(Math.floor(percent * 10) / 10) + "%")); } private void resetProgress() { setProgress(100, 100); } private void updateShownErrors() { final boolean hasNoSources = !Settings.with(this).useMozillaLocationService() && !Settings.with(this).useOpenCellId() && !Settings.with(this).useLacells(); final boolean hasNoPermission = ContextCompat.checkSelfPermission( getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE ) != PackageManager.PERMISSION_GRANTED; final boolean hasProblem = hasNoSources | hasNoPermission; errorSources.setVisibility(hasNoSources ? View.VISIBLE : View.GONE); settings.setVisibility(hasNoSources ? View.VISIBLE : View.GONE); errorPermission.setVisibility(hasNoPermission ? View.VISIBLE : View.GONE); permissionAllow.setVisibility(hasNoPermission ? View.VISIBLE : View.GONE); update.setEnabled(!hasProblem); } @Background protected void updateLastDatabaseUpdate() { long time = Settings.with(this).databaseLastModified(); if (time != 0) { setLastUpdateString(getString( R.string.fragment_update_database_last_update, DateUtils.getRelativeTimeSpanString(time, System.currentTimeMillis(), DateUtils.DAY_IN_MILLIS) ), true); } else if (Settings.with(this).databaseFile() != null) { // exists but not readable setLastUpdateString(getString( R.string.fragment_update_database_no_permission, Settings.with(this).databaseFile() ), true); } else { // not found setLastUpdateString(getString(R.string.fragment_update_database_no_database_found), false); } } @UiThread void setLastUpdateString(String string, boolean is_update) { lastUpdate.setText(string); update.setText(is_update ? R.string.fragment_update_database_start_update : R.string.fragment_update_database_create_database); } private String getLog() { DownloadSpiceRequest last = DownloadSpiceRequest.lastInstance; return last == null ? null : last.getLog(); } private void updateLogView() { log.setText(getLog()); } private void setShowLog(boolean showLog) { this.showLog = showLog; detailsSwitcher.setDisplayedChild(showLog ? DETAILS_PAGE_LOG : DETAILS_PAGE_BUTTON); } @Override public void onAttach(Activity activity) { super.onAttach(activity); listener = (Listener) activity; } @Override public void onDetach() { super.onDetach(); listener = null; } // // LISTENERS // @Override public void onRequestNotFound() { onDownloadDone(); } @Override public void onRequestCancelled() { onDownloadDone(); } @Override public void onRequestFailure(SpiceException ex) { onDownloadDone(); DatabaseUpdateExceptionDialogFragment_.builder() .log(getLog()) .build() .show(getFragmentManager()); } @Override public void onRequestSuccess(DownloadSpiceRequest.Result result) { onDownloadDone(); updateLastDatabaseUpdate(); } @Override public void onRequestProgressUpdate(RequestProgress progress) { updateLogView(); setProgress((int) progress.getProgress(), DownloadSpiceRequest.PROGRESS_MAX); } @Override @TargetApi(23) public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_PERMISSION_STORAGE) { updateShownErrors(); updateLastDatabaseUpdate(); } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } public interface Listener { void openSettings(); } }