diff options
| -rw-r--r-- | main/libs/rxjava-android-0.15.1.jar | bin | 0 -> 16776 bytes | |||
| -rw-r--r-- | main/libs/rxjava-core-0.15.1.jar | bin | 0 -> 496439 bytes | |||
| -rw-r--r-- | main/proguard-project.txt | 5 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/CgeoApplication.java | 11 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/StatusFragment.java | 129 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/network/StatusUpdater.java | 57 |
6 files changed, 93 insertions, 109 deletions
diff --git a/main/libs/rxjava-android-0.15.1.jar b/main/libs/rxjava-android-0.15.1.jar Binary files differnew file mode 100644 index 0000000..4e50a44 --- /dev/null +++ b/main/libs/rxjava-android-0.15.1.jar diff --git a/main/libs/rxjava-core-0.15.1.jar b/main/libs/rxjava-core-0.15.1.jar Binary files differnew file mode 100644 index 0000000..5759337 --- /dev/null +++ b/main/libs/rxjava-core-0.15.1.jar diff --git a/main/proguard-project.txt b/main/proguard-project.txt index 03ef6b3..eae0a42 100644 --- a/main/proguard-project.txt +++ b/main/proguard-project.txt @@ -13,6 +13,11 @@ # apache.commons.collections has some bean related collections, which are undefined in Android -dontwarn java.beans.* +# rxjava includes references to the test frameworks within their class files +-dontwarn org.mockito.** +-dontwarn org.junit.** +-dontwarn org.robolectric.** + #-dontnote org.apache.commons.logging.** -keep public class cgeo.geocaching.* diff --git a/main/src/cgeo/geocaching/CgeoApplication.java b/main/src/cgeo/geocaching/CgeoApplication.java index f4cf6c9..265e7eb 100644 --- a/main/src/cgeo/geocaching/CgeoApplication.java +++ b/main/src/cgeo/geocaching/CgeoApplication.java @@ -1,6 +1,5 @@ package cgeo.geocaching; -import cgeo.geocaching.network.StatusUpdater; import cgeo.geocaching.ui.dialog.Dialogs; import cgeo.geocaching.utils.IObserver; import cgeo.geocaching.utils.Log; @@ -19,7 +18,6 @@ public class CgeoApplication extends Application { private boolean forceRelog = false; // c:geo needs to log into cache providers public boolean showLoginToast = true; //login toast shown just once. private boolean liveMapHintShown = false; // livemap hint has been shown - final private StatusUpdater statusUpdater = new StatusUpdater(); private static CgeoApplication instance; public CgeoApplication() { @@ -35,11 +33,6 @@ public class CgeoApplication extends Application { } @Override - public void onCreate() { - new Thread(statusUpdater).start(); - } - - @Override public void onLowMemory() { Log.i("Cleaning applications cache."); DataStore.removeAllFromCache(); @@ -128,10 +121,6 @@ public class CgeoApplication extends Application { return currentDirObject().getMemory(); } - public StatusUpdater getStatusUpdater() { - return statusUpdater; - } - public boolean isLiveMapHintShown() { return liveMapHintShown; } diff --git a/main/src/cgeo/geocaching/StatusFragment.java b/main/src/cgeo/geocaching/StatusFragment.java index 4f70f0e..a4b5973 100644 --- a/main/src/cgeo/geocaching/StatusFragment.java +++ b/main/src/cgeo/geocaching/StatusFragment.java @@ -1,15 +1,17 @@ package cgeo.geocaching; +import cgeo.geocaching.network.StatusUpdater; import cgeo.geocaching.network.StatusUpdater.Status; -import cgeo.geocaching.utils.IObserver; import cgeo.geocaching.utils.Log; +import rx.Subscription; +import rx.android.observables.AndroidObservable; +import rx.util.functions.Action1; + import android.content.Intent; import android.content.res.Resources; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; @@ -20,91 +22,68 @@ import android.widget.TextView; public class StatusFragment extends Fragment { - private ViewGroup status; - private ImageView statusIcon; - private TextView statusMessage; - - final private StatusHandler statusHandler = new StatusHandler(); + private Subscription statusSubscription; @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); - status = (ViewGroup) inflater.inflate(R.layout.status, container, false); - statusIcon = (ImageView) status.findViewById(R.id.status_icon); - statusMessage = (TextView) status.findViewById(R.id.status_message); - return status; - } - - @Override - public void onResume() { - super.onResume(); - CgeoApplication.getInstance().getStatusUpdater().addObserver(statusHandler); - } - - @Override - public void onPause() { - CgeoApplication.getInstance().getStatusUpdater().deleteObserver(statusHandler); - super.onPause(); - } - - private class StatusHandler extends Handler implements IObserver<Status> { - - @Override - public void update(final Status data) { - obtainMessage(0, data).sendToTarget(); - } - - @Override - public void handleMessage(final Message msg) { - final Status data = (Status) msg.obj; - updateDisplay(data != null && data.message != null ? data : Status.defaultStatus()); - } - - private void updateDisplay(final Status data) { - - if (data == null) { - status.setVisibility(View.INVISIBLE); - return; - } - - final Resources res = getResources(); - final String packageName = getActivity().getPackageName(); + final ViewGroup statusGroup = (ViewGroup) inflater.inflate(R.layout.status, container, false); + final ImageView statusIcon = (ImageView) statusGroup.findViewById(R.id.status_icon); + final TextView statusMessage = (TextView) statusGroup.findViewById(R.id.status_message); + statusSubscription = AndroidObservable.fromFragment(this, StatusUpdater.latestStatus).subscribe(new Action1<Status>() { + @Override + public void call(final Status status) { + if (status == null) { + statusGroup.setVisibility(View.INVISIBLE); + return; + } - if (data.icon != null) { - final int iconId = res.getIdentifier(data.icon, "drawable", packageName); - if (iconId != 0) { - statusIcon.setImageResource(iconId); - statusIcon.setVisibility(View.VISIBLE); + final Resources res = getResources(); + final String packageName = getActivity().getPackageName(); + + if (status.icon != null) { + final int iconId = res.getIdentifier(status.icon, "drawable", packageName); + if (iconId != 0) { + statusIcon.setImageResource(iconId); + statusIcon.setVisibility(View.VISIBLE); + } else { + Log.w("StatusHandler: could not find icon corresponding to @drawable/" + status.icon); + statusIcon.setVisibility(View.GONE); + } } else { - Log.w("StatusHandler: could not find icon corresponding to @drawable/" + data.icon); statusIcon.setVisibility(View.GONE); } - } else { - statusIcon.setVisibility(View.GONE); - } - String message = data.message; - if (data.messageId != null) { - final int messageId = res.getIdentifier(data.messageId, "string", packageName); - if (messageId != 0) { - message = res.getString(messageId); + String message = status.message; + if (status.messageId != null) { + final int messageId = res.getIdentifier(status.messageId, "string", packageName); + if (messageId != 0) { + message = res.getString(messageId); + } } - } - statusMessage.setText(message); - status.setVisibility(View.VISIBLE); + statusMessage.setText(message); + statusGroup.setVisibility(View.VISIBLE); - if (data.url != null) { - status.setOnClickListener(new OnClickListener() { - @Override - public void onClick(final View v) { - startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(data.url))); - } - }); - } else { - status.setClickable(false); + if (status.url != null) { + statusGroup.setOnClickListener(new OnClickListener() { + @Override + public void onClick(final View v) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(status.url))); + } + }); + } else { + statusGroup.setClickable(false); + } } - } + }); + return statusGroup; + } + @Override + public void onDestroy() { + statusSubscription.unsubscribe(); + super.onDestroy(); } + } diff --git a/main/src/cgeo/geocaching/network/StatusUpdater.java b/main/src/cgeo/geocaching/network/StatusUpdater.java index cb4c7f4..40281ad 100644 --- a/main/src/cgeo/geocaching/network/StatusUpdater.java +++ b/main/src/cgeo/geocaching/network/StatusUpdater.java @@ -1,21 +1,22 @@ package cgeo.geocaching.network; import cgeo.geocaching.CgeoApplication; -import cgeo.geocaching.utils.MemorySubject; -import cgeo.geocaching.utils.PeriodicHandler; -import cgeo.geocaching.utils.PeriodicHandler.PeriodicHandlerListener; import cgeo.geocaching.utils.Version; import org.json.JSONException; import org.json.JSONObject; +import rx.Observable; +import rx.concurrency.Schedulers; +import rx.subjects.BehaviorSubject; +import rx.util.functions.Func1; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; -import android.os.Looper; import java.util.Locale; +import java.util.concurrent.TimeUnit; -public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implements Runnable, PeriodicHandlerListener { +public class StatusUpdater { static public class Status { final public String message; @@ -30,24 +31,41 @@ public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implement this.url = url; } + Status(final JSONObject response) { + message = get(response, "message"); + messageId = get(response, "message_id"); + icon = get(response, "icon"); + url = get(response, "url"); + } + final static public Status closeoutStatus = new Status("", "status_closeout_warning", "attribute_abandonedbuilding", "http://faq.cgeo.org/#7_69"); - final static public Status defaultStatus() { + final static public Status defaultStatus(final Status upToDate) { + if (upToDate != null && upToDate.message != null) { + return upToDate; + } return VERSION.SDK_INT < VERSION_CODES.ECLAIR_MR1 ? closeoutStatus : null; } } - @Override - public void onPeriodic() { - final JSONObject response = - Network.requestJSON("http://status.cgeo.org/api/status.json", - new Parameters("version_code", String.valueOf(Version.getVersionCode(CgeoApplication.getInstance())), - "version_name", Version.getVersionName(CgeoApplication.getInstance()), - "locale", Locale.getDefault().toString())); - if (response != null) { - notifyObservers(new Status(get(response, "message"), get(response, "message_id"), get(response, "icon"), get(response, "url"))); - } + final static private Observable<Status> statusObservable = + Observable.interval(30, TimeUnit.MINUTES).startWith(-1L).flatMap(new Func1<Long, Observable<Status>>() { + @Override + public Observable<Status> call(Long id) { + final JSONObject response = + Network.requestJSON("http://status.cgeo.org/api/status.json", + new Parameters("version_code", String.valueOf(Version.getVersionCode(CgeoApplication.getInstance())), + "version_name", Version.getVersionName(CgeoApplication.getInstance()), + "locale", Locale.getDefault().toString())); + return response != null ? Observable.just(Status.defaultStatus((new Status(response)))) : Observable.<Status>empty(); + } + }).subscribeOn(Schedulers.threadPoolForIO()); + + final static public BehaviorSubject<Status> latestStatus = BehaviorSubject.create(Status.defaultStatus(null)); + + static { + statusObservable.subscribe(latestStatus); } private static String get(final JSONObject json, final String key) { @@ -58,11 +76,4 @@ public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implement } } - @Override - public void run() { - Looper.prepare(); - new PeriodicHandler(1800000L, this).start(); - Looper.loop(); - } - } |
