Git Product home page Git Product logo

murraycu / android-galaxyzoo Goto Github PK

View Code? Open in Web Editor NEW
11.0 11.0 13.0 87.48 MB

This Android app lets you classify Galaxy Zoo subjects. It is available in the Google Play Store: https://play.google.com/store/apps/details?id=com.murrayc.galaxyzoo.app . Try beta versions early here: https://play.google.com/apps/testing/com.murrayc.galaxyzoo.app . See also the iPhone app for Galaxy Zoo: https://github.com/murraycu/ios-galaxyzoo/

License: GNU General Public License v3.0

Java 99.93% Python 0.07%

android-galaxyzoo's People

Contributors

avitaker avatar egore avatar hobeika avatar murraycu avatar pandermusubi avatar stream101 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

android-galaxyzoo's Issues

Crash in getShowDiscussQuestionFromSharedPrefs() from abandonItem().

Here's a backtrace from a crash reported with version 1.36 on Android 4.4. There is only one report of this crash so far:

java.lang.NullPointerException
at com.murrayc.galaxyzoo.app.Utils.getShowDiscussQuestionFromSharedPrefs(Unknown Source)
                                   abandonItem
at com.murrayc.galaxyzoo.app.ItemFragment.abandonItem(Unknown Source)
at com.murrayc.galaxyzoo.app.SubjectFragment$2.onError(Unknown Source)
at com.squareup.picasso.ImageViewAction.complete(Unknown Source)
                                        error
at com.squareup.picasso.Picasso.cancelRequest(Unknown Source)
                                load
                                load
                                getRequestHandlers
                                transformRequest
                                defer
                                enqueueAndSubmit
                                complete
                                deliverAction
                                cancelExistingRequest
                                with
                                access$000
at com.squareup.picasso.Picasso.cancelRequest(Unknown Source)
                                load
                                load
                                getRequestHandlers
                                transformRequest
                                defer
                                enqueueAndSubmit
                                complete
                                deliverAction
                                cancelExistingRequest
                                with
                                access$000
at com.squareup.picasso.Picasso$1.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)

Crash: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

I, and at least one other user, have seen this crash. It might be happening when ClassifyFragment is trying to show the AlertDialog about generic network problems, via its warnAboutNetworkProblemWithRetry() method.

This is part of the stacktrace seems to be relevant:

at com.murrayc.galaxyzoo.app.ClassifyFragment.void showChildFragments(boolean)(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void showLoadingInProgress(boolean)(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void warnAboutNetworkProblemWithRetry(android.app.Activity,java.lang.String)(Unknown Source)

The complete deobfuscated/retraced stacktrace looks like this:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.void checkStateLoss()(Unknown Source)
at android.support.v4.app.FragmentManagerImpl.void throwException(java.lang.RuntimeException)(Unknown Source)
                                              android.support.v4.app.FragmentTransaction beginTransaction()
                                              void putFragment(android.os.Bundle,java.lang.String,android.support.v4.app.Fragment)
                                              android.support.v4.app.Fragment getFragment(android.os.Bundle,java.lang.String)
                                              void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[])
                                              android.view.animation.Animation makeOpenCloseAnimation(android.content.Context,float,float,float,float)
                                              android.view.animation.Animation makeFadeAnimation(android.content.Context,float,float)
                                              android.view.animation.Animation loadAnimation(android.support.v4.app.Fragment,int,boolean,int)
                                              void performPendingDeferredStart(android.support.v4.app.Fragment)
                                              void moveToState(android.support.v4.app.Fragment,int,int,int,boolean)
                                              void moveToState(int,boolean)
                                              void moveToState(int,int,int,boolean)
                                              void addFragment(android.support.v4.app.Fragment,boolean)
                                              void removeFragment(android.support.v4.app.Fragment,int,int)
                                              android.support.v4.app.Fragment findFragmentById(int)
                                              android.support.v4.app.Fragment findFragmentByTag(java.lang.String)
                                              void enqueueAction(java.lang.Runnable,boolean)
                                              int allocBackStackIndex(android.support.v4.app.BackStackRecord)
                                              void setBackStackIndex(int,android.support.v4.app.BackStackRecord)
                                              boolean popBackStackState(android.os.Handler,java.lang.String,int,int)
                                              void restoreAllState(android.os.Parcelable,java.util.ArrayList)
                                              void attachActivity(android.support.v4.app.FragmentActivity,android.support.v4.app.FragmentContainer,android.support.v4.app.Fragment)
                                              void dispatchConfigurationChanged(android.content.res.Configuration)
                                              boolean dispatchCreateOptionsMenu(android.view.Menu,android.view.MenuInflater)
                                              boolean dispatchPrepareOptionsMenu(android.view.Menu)
                                              boolean dispatchOptionsItemSelected(android.view.MenuItem)
at android.support.v4.app.BackStackRecord.void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[])(Unknown Source)
                                          void dump(java.lang.String,java.io.PrintWriter,boolean)
                                          void addOp(android.support.v4.app.BackStackRecord$Op)
                                          android.support.v4.app.FragmentTransaction add(int,android.support.v4.app.Fragment,java.lang.String)
                                          void doAddOp(int,android.support.v4.app.Fragment,java.lang.String,int)
                                          android.support.v4.app.FragmentTransaction replace(int,android.support.v4.app.Fragment)
                                          android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment)
                                          void bumpBackStackNesting(int)
                                          int commit()
                                          int commitInternal(boolean)
                                          void setFirstOut(android.util.SparseArray,android.support.v4.app.Fragment)
                                          void calculateBackFragments(android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState popFromBackStack(boolean,android.support.v4.app.BackStackRecord$TransitionState,android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState beginTransition(android.util.SparseArray,android.util.SparseArray,boolean)
                                          java.lang.Object getEnterTransition(android.support.v4.app.Fragment,boolean)
                                          java.lang.Object getSharedElementTransition(android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean)
                                          java.lang.Object captureExitingViews(java.lang.Object,android.support.v4.app.Fragment,java.util.ArrayList,android.support.v4.util.ArrayMap)
                                          android.support.v4.util.ArrayMap remapSharedElements(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,boolean)
                                          boolean configureTransitions(int,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.util.SparseArray,android.util.SparseArray)
                                          void prepareSharedElementTransition(android.support.v4.app.BackStackRecord$TransitionState,android.view.View,java.lang.Object,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,java.util.ArrayList)
                                          void callSharedElementEnd(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void setEpicenterIn(android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          android.support.v4.util.ArrayMap mapSharedElementsIn(android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          android.support.v4.util.ArrayMap remapNames(java.util.ArrayList,java.util.ArrayList,android.support.v4.util.ArrayMap)
                                          void excludeHiddenFragmentsAfterEnter(android.view.View,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void excludeHiddenFragments(android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void setNameOverride(android.support.v4.util.ArrayMap,java.lang.String,java.lang.String)
                                          void setNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,java.util.ArrayList,java.util.ArrayList)
                                          void setBackNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.util.ArrayMap,boolean)
                                          android.support.v4.util.ArrayMap access$000(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          void access$100(android.support.v4.app.BackStackRecord,android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          void access$200(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void access$300(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
at android.support.v4.app.BackStackRecord.void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[])(Unknown Source)
                                          void dump(java.lang.String,java.io.PrintWriter,boolean)
                                          void addOp(android.support.v4.app.BackStackRecord$Op)
                                          android.support.v4.app.FragmentTransaction add(int,android.support.v4.app.Fragment,java.lang.String)
                                          void doAddOp(int,android.support.v4.app.Fragment,java.lang.String,int)
                                          android.support.v4.app.FragmentTransaction replace(int,android.support.v4.app.Fragment)
                                          android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment)
                                          void bumpBackStackNesting(int)
                                          int commit()
                                          int commitInternal(boolean)
                                          void setFirstOut(android.util.SparseArray,android.support.v4.app.Fragment)
                                          void calculateBackFragments(android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState popFromBackStack(boolean,android.support.v4.app.BackStackRecord$TransitionState,android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState beginTransition(android.util.SparseArray,android.util.SparseArray,boolean)
                                          java.lang.Object getEnterTransition(android.support.v4.app.Fragment,boolean)
                                          java.lang.Object getSharedElementTransition(android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean)
                                          java.lang.Object captureExitingViews(java.lang.Object,android.support.v4.app.Fragment,java.util.ArrayList,android.support.v4.util.ArrayMap)
                                          android.support.v4.util.ArrayMap remapSharedElements(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,boolean)
                                          boolean configureTransitions(int,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.util.SparseArray,android.util.SparseArray)
                                          void prepareSharedElementTransition(android.support.v4.app.BackStackRecord$TransitionState,android.view.View,java.lang.Object,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,java.util.ArrayList)
                                          void callSharedElementEnd(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void setEpicenterIn(android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          android.support.v4.util.ArrayMap mapSharedElementsIn(android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          android.support.v4.util.ArrayMap remapNames(java.util.ArrayList,java.util.ArrayList,android.support.v4.util.ArrayMap)
                                          void excludeHiddenFragmentsAfterEnter(android.view.View,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void excludeHiddenFragments(android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void setNameOverride(android.support.v4.util.ArrayMap,java.lang.String,java.lang.String)
                                          void setNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,java.util.ArrayList,java.util.ArrayList)
                                          void setBackNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.util.ArrayMap,boolean)
                                          android.support.v4.util.ArrayMap access$000(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          void access$100(android.support.v4.app.BackStackRecord,android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          void access$200(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void access$300(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void showChildFragments(boolean)(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void showLoadingInProgress(boolean)(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void warnAboutNetworkProblemWithRetry(android.app.Activity,java.lang.String)(Unknown Source)
                                              android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle)
                                              void onCreateOptionsMenu(android.view.Menu,android.view.MenuInflater)
                                              android.support.v4.content.Loader onCreateLoader(int,android.os.Bundle)
                                              void onLoadFinished(android.support.v4.content.Loader,android.database.Cursor)
                                              void onLoaderReset(android.support.v4.content.Loader)
                                              void onLoadFinished(android.support.v4.content.Loader,java.lang.Object)
                                              void access$000(com.murrayc.galaxyzoo.app.ClassifyFragment)
                                              android.app.AlertDialog access$102(com.murrayc.galaxyzoo.app.ClassifyFragment,android.app.AlertDialog)
at android.support.v4.app.LoaderManagerImpl.android.support.v4.app.LoaderManagerImpl$LoaderInfo createLoader(int,android.os.Bundle,android.support.v4.app.LoaderManager$LoaderCallbacks)(Unknown Source)
                                            void doStop()
at android.support.v4.app.LoaderManagerImpl.android.support.v4.app.LoaderManagerImpl$LoaderInfo createAndInstallLoader(int,android.os.Bundle,android.support.v4.app.LoaderManager$LoaderCallbacks)(Unknown Source)
                                            void doRetain()
at android.support.v4.app.LoaderManagerImpl.android.support.v4.content.Loader restartLoader(int,android.os.Bundle,android.support.v4.app.LoaderManager$LoaderCallbacks)(Unknown Source)
                                            void doStart()
at com.murrayc.galaxyzoo.app.ClassifyFragment.void update()(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyActivity.void startNextClassification()(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyActivity.void onClassificationFinished()(Unknown Source)
at com.murrayc.galaxyzoo.app.QuestionFragment$SaveClassificationTask.java.lang.Void doInBackground(java.lang.Void[])(Unknown Source)
                                                                     void onPostExecute(java.lang.Void)
at com.murrayc.galaxyzoo.app.QuestionFragment$SaveClassificationTask.void onPostExecute(java.lang.Object)(Unknown Source)
at android.os.AsyncTask.finish(AsyncTask.java:602)
at android.os.AsyncTask.access$600(AsyncTask.java:156)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4507)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:978)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
at dalvik.system.NativeStart.main(Native Method)

Crash: java.util.ConcurrentModificationException

I've seen one crash report with this stacktrace, though the stacktrace is rather hard to understand. Maybe the retrace (in proguardgui) failed somehow.

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com.murrayc.galaxyzoo.app.QuestionFragment.android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle)(Unknown Source)
                                              void onCreateOptionsMenu(android.view.Menu,android.view.MenuInflater)
                                              void onPrepareOptionsMenu(android.view.Menu)
                                              boolean onOptionsItemSelected(android.view.MenuItem)
                                              void onAttach(android.app.Activity)
                                              android.widget.TableRow addRowToTable(android.app.Activity,android.widget.TableLayout)
                                              void insertButtonInRow(android.content.Context,android.widget.TableRow,android.view.View)
                                              android.widget.Button createAnswerButton(android.app.Activity,com.murrayc.galaxyzoo.app.DecisionTree$Answer)
                                              void onAnswerButtonClicked(java.lang.String,java.lang.String)
                                              void saveClassificationSync(com.murrayc.galaxyzoo.app.QuestionFragment$ClassificationInProgress)
                                              android.support.v4.content.Loader onCreateLoader(int,android.os.Bundle)
                                              void onLoadFinished(android.support.v4.content.Loader,android.database.Cursor)
                                              void onLoaderReset(android.support.v4.content.Loader)
                                              void onLoadFinished(android.support.v4.content.Loader,java.lang.Object)
                                              void access$000(com.murrayc.galaxyzoo.app.QuestionFragment,java.lang.String,java.lang.String)
                                              void access$100(com.murrayc.galaxyzoo.app.QuestionFragment,com.murrayc.galaxyzoo.app.QuestionFragment$ClassificationInProgress)
                                              void access$200(com.murrayc.galaxyzoo.app.QuestionFragment)
at com.murrayc.galaxyzoo.app.QuestionFragment.android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle)(Unknown Source)
                                              void onCreateOptionsMenu(android.view.Menu,android.view.MenuInflater)
                                              void onPrepareOptionsMenu(android.view.Menu)
                                              boolean onOptionsItemSelected(android.view.MenuItem)
                                              void onAttach(android.app.Activity)
                                              android.widget.TableRow addRowToTable(android.app.Activity,android.widget.TableLayout)
                                              void insertButtonInRow(android.content.Context,android.widget.TableRow,android.view.View)
                                              android.widget.Button createAnswerButton(android.app.Activity,com.murrayc.galaxyzoo.app.DecisionTree$Answer)
                                              void onAnswerButtonClicked(java.lang.String,java.lang.String)
                                              void saveClassificationSync(com.murrayc.galaxyzoo.app.QuestionFragment$ClassificationInProgress)
                                              android.support.v4.content.Loader onCreateLoader(int,android.os.Bundle)
                                              void onLoadFinished(android.support.v4.content.Loader,android.database.Cursor)
                                              void onLoaderReset(android.support.v4.content.Loader)
                                              void onLoadFinished(android.support.v4.content.Loader,java.lang.Object)
                                              void access$000(com.murrayc.galaxyzoo.app.QuestionFragment,java.lang.String,java.lang.String)
                                              void access$100(com.murrayc.galaxyzoo.app.QuestionFragment,com.murrayc.galaxyzoo.app.QuestionFragment$ClassificationInProgress)
                                              void access$200(com.murrayc.galaxyzoo.app.QuestionFragment)
at com.murrayc.galaxyzoo.app.QuestionFragment$SaveClassificationTask.java.lang.Void doInBackground(java.lang.Void[])(Unknown Source)
                                                                     void onPostExecute(java.lang.Void)
at com.murrayc.galaxyzoo.app.QuestionFragment$SaveClassificationTask.java.lang.Object doInBackground(java.lang.Object[])(Unknown Source)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)

Allow user registration in the app

Currently, the Register button takes the user to this page on the website:
https://www.zooniverse.org/accounts/register
They then have to enter their password again to actually login (which happens inside the app).
(Strangely, that page's Register button doesn't always show a result. It often succeeds silently, and you then see an error message, about the user already existing, if you press it again.)

If we did the registration from inside the app, we could use the api_key that we get from the successful registration, without asking the user for the password again.

That page seems to use websockets (wss:// POSTs) to register the user, but the similar login form on www.galaxyzoo.org uses simpler GET requests like so:
https://www.galaxyzoo.org/_ouroboros_api/projects/galaxy_zoo/signup?username=someusername&email=something%40example.com&password=somepassword
and returns a boolean success in a JSON response.

It seems unwise to use any server API for this unless we can be sure that it is a stable API, ideally with some documentation.

Crash while loading translations

A user, apparently using the Italian locale, reported this crash, apparently while loading the Italian translation .json file in version 1.44:

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
Caused by: java.lang.NullPointerException: asset
at android.content.res.AssetManager.getAssetRemainingLength(Native Method)
at android.content.res.AssetManager.access$300(AssetManager.java:35)
at android.content.res.AssetManager$AssetInputStream.available(AssetManager.java:554)
at java.io.InputStreamReader.read(InputStreamReader.java:234)
at android.util.JsonReader.fillBuffer(JsonReader.java:739)
at android.util.JsonReader.nextNonWhitespace(JsonReader.java:779)
at android.util.JsonReader.nextValue(JsonReader.java:692)
at android.util.JsonReader.peek(JsonReader.java:334)
at android.util.JsonReader.expect(JsonReader.java:308)
at android.util.JsonReader.beginObject(JsonReader.java:293)
at com.murrayc.galaxyzoo.app.DecisionTree.void loadTranslation(java.io.InputStream)(Unknown Source)
                                          void readJsonQuestions(android.util.JsonReader)
                                          void readJsonQuestion(android.util.JsonReader,com.murrayc.galaxyzoo.app.DecisionTree$Question)
                                          com.murrayc.galaxyzoo.app.DecisionTree$Answer getAnswerWithId(java.util.List,java.lang.String)
                                          com.murrayc.galaxyzoo.app.DecisionTree$Question getQuestionOrFirst(java.lang.String)
                                          com.murrayc.galaxyzoo.app.DecisionTree$Question getNextQuestionForAnswer(java.lang.String,java.lang.String)
                                          java.util.List getAllQuestions()
                                          java.util.List getChildrenByTagName(org.w3c.dom.Element,java.lang.String)
                                          com.murrayc.galaxyzoo.app.DecisionTree$Question loadQuestion(org.w3c.dom.Element)
                                          void setDiscussQuestion(com.murrayc.galaxyzoo.app.DecisionTree$DiscussQuestion)
at com.murrayc.galaxyzoo.app.DecisionTree.<init>(Unknown Source)
at com.murrayc.galaxyzoo.app.Singleton.<init>(Unknown Source)
at com.murrayc.galaxyzoo.app.Singleton.<init>(Unknown Source)
at com.murrayc.galaxyzoo.app.Singleton$InitAsyncTask.java.lang.Void doInBackground(android.content.Context[])(Unknown Source)
                                                     void onPostExecute(java.lang.Void)
at com.murrayc.galaxyzoo.app.Singleton$InitAsyncTask.java.lang.Object doInBackground(java.lang.Object[])(Unknown Source)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)

New subjects - what do you need to prep?

Hi @murraycu - we have two new sets of subjects that should be put into Galaxy Zoo by next week. Both will have new survey names, but will use existing workflows. Can you tell me what you need in order for the app to be compatible with these new subjects?

Viewing example images doesn't use the changeImageTransform transformation/animation

Opening already-classified item from the list view shows a nice move+expand animation as the large version of the image is shown in the new activity.

However, the same thing doesn't work when opening an example image from the help activity(QuestionHelpActivity/QuestionHelpFragment). For instance, click on the ? action icon and then click on an image thumbnail.

This should work:

Both the thumbnail and the larger image are marked with the same transitionName:
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/java/com/murrayc/galaxyzoo/app/QuestionHelpFragment.java#L153
and
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/res/layout/fragment_example_viewer.xml#L23

and the ExampleViewerActivity is started with the appropriate transition options bundle:
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/java/com/murrayc/galaxyzoo/app/QuestionHelpFragment.java#L194

and the transitions are specified in the theme:
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/res/values-v21/styles.xml#L15
which refers to this:
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/res/transition/change_image_transform.xml

Identify classifications as coming from the app

From a data analysis standpoint, we'd like to know which classifications users made through the app as opposed to the browser. Can you add a field to the final upload that indicates this? Something like:

{
interface: "android_app"
}

or equivalent would be fine.

@camallen suggested that it'd probably be done here:

private boolean doUploadSync(final String itemId, final String subjectId, final String authName, final String authApiKey) {

Add to F-Droid

It would be handy to have this app distributed through F-Droid. Do you think that would be feasible?

Crash in getAccountLoginDetails() during uploadOutstandingClassifications().

A user reported this crash with version 1.44. This is the first, and so far, only report of this with any version.

Android version: Android 4.0.3 - 4.0.41
Device: Galaxy Tab 7.0 Plus (GT-P6211)

java.lang.NullPointerException
at com.murrayc.galaxyzoo.app.LoginUtils.com.murrayc.galaxyzoo.app.LoginUtils$LoginDetails getAccountLoginDetails(android.content.Context)(Unknown Source)
                                        boolean getBooleanPref(android.content.Context,int)
at com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter.boolean uploadOutstandingClassifications()(Unknown Source)
at com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter.void doRegularTasks()(Unknown Source)
                                                     void requestMoreItemsAsync(int)
                                                     void removeItem(java.lang.String)
                                                     boolean doUploadSync(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
                                                     void onQueryTaskFinished(java.util.List)
                                                     void onUploadTaskFinished(boolean,java.lang.String)
                                                     void access$000(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,java.util.List)
                                                     boolean access$102(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,boolean)
                                                     boolean access$200(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
                                                     android.os.Handler access$300(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter)
                                                     void access$400(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,boolean,java.lang.String)
at com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter.void onPerformSync(android.accounts.Account,android.os.Bundle,java.lang.String,android.content.ContentProviderClient,android.content.SyncResult)(Unknown Source)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:247)

SyncAdapter: CursorWindowAllocationException

There has been one crash report with this (deobfuscated) backtrace, in version 1.40 on Android 3.2:

android.database.CursorWindowAllocationException: Cursor Window allocation of 4096 kb failed. # Open Cursors=241 (# cursors opened by this proc=241)
at android.database.CursorWindow.printDebugMsgIfError(CursorWindow.java:72)
at android.database.CursorWindow.<init>(CursorWindow.java:64)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:445)
at android.content.ContentResolver.query(ContentResolver.java:304)
at com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter.void doRegularTasks()(Unknown Source)
                                                     void requestMoreItemsAsync(int)
                                                     void removeItem(java.lang.String)
                                                     boolean doUploadSync(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
                                                     void onQueryTaskFinished(java.util.List)
                                                     void onUploadTaskFinished(boolean,java.lang.String)
                                                     void access$000(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,java.util.List)
                                                     boolean access$102(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,boolean)
                                                     boolean access$200(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
                                                     android.os.Handler access$300(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter)
                                                     void access$400(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,boolean,java.lang.String)
at com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter.void doRegularTasks()(Unknown Source)
                                                     void requestMoreItemsAsync(int)
                                                     void removeItem(java.lang.String)
                                                     boolean doUploadSync(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
                                                     void onQueryTaskFinished(java.util.List)
                                                     void onUploadTaskFinished(boolean,java.lang.String)
                                                     void access$000(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,java.util.List)
                                                     boolean access$102(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,boolean)
                                                     boolean access$200(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,java.lang.String,java.lang.String,java.lang.String,java.lang.String)
                                                     android.os.Handler access$300(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter)
                                                     void access$400(com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter,boolean,java.lang.String)
at com.murrayc.galaxyzoo.app.syncadapter.SyncAdapter$UploadTask.void run()(Unknown Source)
at java.lang.Thread.run(Thread.java:1028)

This seems to be happening somewhere in SyncAdapter.doRegularTasks(). It suggests a leaked Cursor, but I can't find any there that are not closed:
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/java/com/murrayc/galaxyzoo/app/syncadapter/SyncAdapter.java

Cannot download new subjects to classify

I installed the Galaxy Zoo app for my Android (Huawei Y350 running Android 4.4.2).

I log in, it thinks a bit, and says
"Cannot download new subjects to classify".
I am able to log in to the web site without problems.
The network is working fine on the phone. I'm on wireless right now.
I've tried it for two days now -- never downloads anything.

Poor use of vertical screen real estate on small devices

Here's a 4" Huawei Y360.

The full image fails to fill the breadth of the screen by almost a cm, evidently because of excessive vertical use of the screen.

This has the corrollary problem that the object at the horizontal center of the screen is no longer the object of the evaluation.

At the very top is the Android bar... I don't know if that can or should be disabled.
Then a very wide banner, mostly to say in big letters the name of the app. That could be reduced.
At the bottom are textual instructions and large buttons. They are larger than is appropriate on this device.

screenshot_galaxyzoo_y360

Incorrect classifications for goods_full and candels_2epoch

I've been looking at the data for both the candels_2epoch and goods_full subjects classified through the Android app. I'm worried that about 1 in 5 classifications seem to be using the wrong workflow; for example, there are about 500 rows that recorded candels_2epoch classifications for a goods_full galaxy, and 500 that did vice versa. We've only seen this behavior in the Android app, not in the main web interface.

Do you know what might be causing this?

Problematic timeout setting for volley request ?

Hi there,

I found that a network timeout setting is kind of problematic. The following is a code snippet from HttpUtils.java:

public static final int TIMEOUT_MILLIS = 20000; //20 seconds. Long but not too short for GPRS connections and not endless.
try {
            response = futureListener.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
        } catch (final InterruptedException | ExecutionException e) {
            Log.error("cacheUriToFile(): Exception from request.", e);
            throw new FileCacheException("Exception from request.", e);
        } catch (final TimeoutException e) {
            Log.error("cacheUriToFile(): Timeout Exception from request.", e);
            throw new FileCacheException("Timeout Exception from request.", e);

        }

From the comments, I guess the purpose of TIMEOUT_MILLIS is to set a 20 sec timeout of this network request. But volley library uses setRetryPolicy(TIMEOUT_MS, MAX_RETRIES, BACKOFF_MULT) to set timeout and retry policy. RequestFuture() only blocks and waits 20 sec for the result to be ready, and therefore cannot control the timeout of network request. So I think the expected behavior here is to add request.setRetryPolicy() to set the timeout value ?

Best,

Material design: ToggleButtons don't have the ripple effect

On the "Odd" question, there are toggle buttons for "Ring", "Lens or arc", etc. When running on Android 5.0 (API 21) these should have the ripple effect. A ToggleButton with the normal style would have the ripple effect, but ours doesn't because we have specified a different background for the checked state, by using a style, because the default style is so unsuitable:

    <style name="GalaxyZooToggleButtonStyle" parent="GalaxyZooButtonStyle">
        <item name="android:background">@drawable/question_answer_checkbox_background</item>
    </style>

https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/res/values/styles.xml#L77

whose background drawable is a :

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Strangely, we need to use android:drawable, not android:color even when specifying
    a color. -->
    <item android:state_checked="true"
        android:drawable="@color/color_accent" />
    <!-- Default State -->
    <item android:drawable="@android:color/transparent" />
</selector>

https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/res/drawable/question_answer_checkbox_background.xml

That style is specified in the ToggleButton's layout XML:
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/res/layout/question_answer_checkbox.xml

It works for the regular buttons, such as "Done", which just uses:
style="?android:attr/borderlessButtonStyle"
in it's layout xml:
https://github.com/murraycu/android-galaxyzoo/blob/master/app/src/main/res/layout/question_answer_button.xml
Incidentally, we don't use a style for that because there is no way to use an attribute (the borderlessButtonStyle) as a style parent.

Translation

Any plan to translate the app ?
I could help to translate it in French

Change Login menu item to "Log out" when the user is logged in.

The "Login" menu item doesn't change after the user is logged in. This seems to have made at least one person think that the login was not successful. (There is already a brief "Logged in" message after logging in and every time you open the app, to partly help with this.)

This (awkward anyway) branch tries to change it to "Log out" when we are logged in, but the menu of the current activity doesn't get updated yet:
https://github.com/murraycu/android-galaxyzoo/tree/show-log-out

Note also that there's no way to know when the login becomes invalid, for instance if the user changes their password on the website. That's a server bug that we can't do anything about in the client:
zooniverse/Galaxy-Zoo#184

Using a lot of Data

@chrislintott says he's heard reports about the app consuming quite a bit of data (over 1gb, he said).

I'm still waiting for him to send more details, but figured I'd give you a heads up.

Beta: Crash at startup: ava.lang.VerifyError: Rejecting class com.murrayc.galaxyzoo.app.aq because it failed compile-time verification

I just installed v1.59 and get a force close when starting the app. I did not have a previous version installed.
I am on CyanogenMod 13.0 / Android 6.0.1.

Here is the relevant information from logcat when the crash occurs:

08-25 19:27:06.811 D/AndroidRuntime(32133): Shutting down VM
08-25 19:27:06.814 E/AndroidRuntime(32133): FATAL EXCEPTION: main
08-25 19:27:06.814 E/AndroidRuntime(32133): Process: com.murrayc.galaxyzoo.app, PID: 32133
08-25 19:27:06.814 E/AndroidRuntime(32133): Theme: themes:{default=overlay:com.materialos.cm.theme, iconPack:org.twelf.cmtheme, fontPkg:org.mmk2410.cyngn.theme.fira, com.android.systemui=overlay:com.materialos.cm.theme, com.android.systemui.navbar=overlay:system}
08-25 19:27:06.814 E/AndroidRuntime(32133): java.lang.VerifyError: Rejecting class com.murrayc.galaxyzoo.app.aq because it failed compile-time verification (declaration of 'com.murrayc.galaxyzoo.app.aq' appears in /data/app/com.murrayc.galaxyzoo.app-1/base.apk)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at com.murrayc.galaxyzoo.app.ac.b()
08-25 19:27:06.814 E/AndroidRuntime(32133):     at com.murrayc.galaxyzoo.app.ac.k()
08-25 19:27:06.814 E/AndroidRuntime(32133):     at com.murrayc.galaxyzoo.app.ac.f()
08-25 19:27:06.814 E/AndroidRuntime(32133):     at com.murrayc.galaxyzoo.app.ac.m()
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.a.bw.j(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.a.bw.i(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.b.a(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.f.e(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.f.a(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.g.g(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.h.b(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.i.l(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.i.p(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.support.v4.d.s.handleMessage(Unknown)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.os.Handler.dispatchMessage(Handler.java:102)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.os.Looper.loop(Looper.java:148)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at android.app.ActivityThread.main(ActivityThread.java:5461)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at java.lang.reflect.Method.invoke(Native Method)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-25 19:27:06.814 E/AndroidRuntime(32133):     at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
08-25 19:27:06.816 W/ActivityManager(2705):   Force finishing activity com.murrayc.galaxyzoo.app/.ClassifyActivity
08-25 19:27:06.903 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:06.913 I/OpenGLRenderer(2705): Initialized EGL, version 1.4
08-25 19:27:06.963 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:06.989 I/art     (2705): Background partial concurrent mark sweep GC freed 78603(4MB) AllocSpace objects, 25(604KB) LOS objects, 33% free, 27MB/41MB, paused 2.510ms total 143.074ms
08-25 19:27:06.999 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:06.999 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:07.048 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:07.079 I/ActivityManager(2705): Process com.android.documentsui (pid 25558) has died
08-25 19:27:07.088 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:07.112 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:07.112 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:07.150 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:07.188 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:07.214 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:07.214 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:07.313 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:07.350 W/ActivityManager(2705): Activity pause timeout for ActivityRecord{98df40e u0 com.murrayc.galaxyzoo.app/.ClassifyActivity t10936 f}
08-25 19:27:07.351 E/QCOM PowerHAL(2705): Failed to acquire lock.
08-25 19:27:07.354 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:07.383 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:07.383 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:07.487 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:07.614 W/PackageSettings(2705): Skipping PackageSetting{39bc963 org.jtb.csdroid.donate/10113} due to missing metadata
08-25 19:27:07.623 W/PackageSettings(2705): Skipping PackageSetting{6431960 com.wolfram.android.alpha/10239} due to missing metadata
08-25 19:27:07.645 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:07.683 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:07.683 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:07.807 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:07.844 E/QCOM PowerHAL(2705): Failed to acquire lock.
08-25 19:27:07.852 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:07.855 E/QCOM PowerHAL(2705): Failed to acquire lock.
08-25 19:27:07.869 E/QCOM PowerHAL(2705): Failed to acquire lock.
08-25 19:27:07.884 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:07.884 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:07.956 E/QCOM PowerHAL(2705): Failed to acquire lock.
08-25 19:27:07.964 I/ActivityManager(2705): START u0 {act=com.android.systemui.recents.SHOW_RECENTS flg=0x10804000 cmp=com.android.systemui/.recents.RecentsActivity} from uid 10016 on display 0
08-25 19:27:07.988 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:08.087 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:08.139 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:08.139 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:08.185 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:08.248 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:08.284 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:08.284 I/android-galaxyzoo(32206): doRegularTasks() end
08-25 19:27:08.331 I/android-galaxyzoo(32206): doRegularTasks() start
08-25 19:27:08.354 I/android-galaxyzoo(32206): checkImagesStillExist(): start
08-25 19:27:08.372 I/android-galaxyzoo(32206): checkImagesStillExist(): end
08-25 19:27:08.372 I/android-galaxyzoo(32206): doRegularTasks() end

Crash with CONNECTIVITY_CHANGE: "Error receiving broadcast Intent"

A user reported this crash on Android 5.0 with version 1.45 after classifying 5 subjects. It looks like it was triggered by a change of network connectivity.

java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } in com.murrayc.galaxyzoo.app.g@2505d2ff
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:872)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.void checkStateLoss()(Unknown Source)
at android.support.v4.app.FragmentManagerImpl.void throwException(java.lang.RuntimeException)(Unknown Source)
                                              android.support.v4.app.FragmentTransaction beginTransaction()
                                              void putFragment(android.os.Bundle,java.lang.String,android.support.v4.app.Fragment)
                                              android.support.v4.app.Fragment getFragment(android.os.Bundle,java.lang.String)
                                              void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[])
                                              android.view.animation.Animation makeOpenCloseAnimation(android.content.Context,float,float,float,float)
                                              android.view.animation.Animation makeFadeAnimation(android.content.Context,float,float)
                                              android.view.animation.Animation loadAnimation(android.support.v4.app.Fragment,int,boolean,int)
                                              void performPendingDeferredStart(android.support.v4.app.Fragment)
                                              void moveToState(android.support.v4.app.Fragment,int,int,int,boolean)
                                              void moveToState(int,boolean)
                                              void moveToState(int,int,int,boolean)
                                              void addFragment(android.support.v4.app.Fragment,boolean)
                                              void removeFragment(android.support.v4.app.Fragment,int,int)
                                              android.support.v4.app.Fragment findFragmentById(int)
                                              android.support.v4.app.Fragment findFragmentByTag(java.lang.String)
                                              void enqueueAction(java.lang.Runnable,boolean)
                                              int allocBackStackIndex(android.support.v4.app.BackStackRecord)
                                              void setBackStackIndex(int,android.support.v4.app.BackStackRecord)
                                              boolean popBackStackState(android.os.Handler,java.lang.String,int,int)
                                              void restoreAllState(android.os.Parcelable,java.util.ArrayList)
                                              void attachActivity(android.support.v4.app.FragmentActivity,android.support.v4.app.FragmentContainer,android.support.v4.app.Fragment)
                                              void dispatchConfigurationChanged(android.content.res.Configuration)
                                              boolean dispatchCreateOptionsMenu(android.view.Menu,android.view.MenuInflater)
                                              boolean dispatchPrepareOptionsMenu(android.view.Menu)
                                              boolean dispatchOptionsItemSelected(android.view.MenuItem)
                                              android.view.View onCreateView(android.view.View,java.lang.String,android.content.Context,android.util.AttributeSet)
at android.support.v4.app.BackStackRecord.void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[])(Unknown Source)
                                          void dump(java.lang.String,java.io.PrintWriter,boolean)
                                          void addOp(android.support.v4.app.BackStackRecord$Op)
                                          android.support.v4.app.FragmentTransaction add(int,android.support.v4.app.Fragment,java.lang.String)
                                          void doAddOp(int,android.support.v4.app.Fragment,java.lang.String,int)
                                          android.support.v4.app.FragmentTransaction replace(int,android.support.v4.app.Fragment)
                                          android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment)
                                          void bumpBackStackNesting(int)
                                          int commit()
                                          int commitInternal(boolean)
                                          void setFirstOut(android.util.SparseArray,android.support.v4.app.Fragment)
                                          void calculateBackFragments(android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState popFromBackStack(boolean,android.support.v4.app.BackStackRecord$TransitionState,android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState beginTransition(android.util.SparseArray,android.util.SparseArray,boolean)
                                          java.lang.Object getEnterTransition(android.support.v4.app.Fragment,boolean)
                                          java.lang.Object getSharedElementTransition(android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean)
                                          java.lang.Object captureExitingViews(java.lang.Object,android.support.v4.app.Fragment,java.util.ArrayList,android.support.v4.util.ArrayMap,android.view.View)
                                          android.support.v4.util.ArrayMap remapSharedElements(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,boolean)
                                          boolean configureTransitions(int,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.util.SparseArray,android.util.SparseArray)
                                          void prepareSharedElementTransition(android.support.v4.app.BackStackRecord$TransitionState,android.view.View,java.lang.Object,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,java.util.ArrayList)
                                          void callSharedElementEnd(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void setEpicenterIn(android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          android.support.v4.util.ArrayMap mapSharedElementsIn(android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          android.support.v4.util.ArrayMap remapNames(java.util.ArrayList,java.util.ArrayList,android.support.v4.util.ArrayMap)
                                          void excludeHiddenFragmentsAfterEnter(android.view.View,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void excludeHiddenFragments(android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void setNameOverride(android.support.v4.util.ArrayMap,java.lang.String,java.lang.String)
                                          void setNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,java.util.ArrayList,java.util.ArrayList)
                                          void setBackNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.util.ArrayMap,boolean)
                                          android.support.v4.util.ArrayMap access$000(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          void access$100(android.support.v4.app.BackStackRecord,android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          void access$200(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void access$300(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
at android.support.v4.app.BackStackRecord.void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[])(Unknown Source)
                                          void dump(java.lang.String,java.io.PrintWriter,boolean)
                                          void addOp(android.support.v4.app.BackStackRecord$Op)
                                          android.support.v4.app.FragmentTransaction add(int,android.support.v4.app.Fragment,java.lang.String)
                                          void doAddOp(int,android.support.v4.app.Fragment,java.lang.String,int)
                                          android.support.v4.app.FragmentTransaction replace(int,android.support.v4.app.Fragment)
                                          android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment)
                                          void bumpBackStackNesting(int)
                                          int commit()
                                          int commitInternal(boolean)
                                          void setFirstOut(android.util.SparseArray,android.support.v4.app.Fragment)
                                          void calculateBackFragments(android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState popFromBackStack(boolean,android.support.v4.app.BackStackRecord$TransitionState,android.util.SparseArray,android.util.SparseArray)
                                          android.support.v4.app.BackStackRecord$TransitionState beginTransition(android.util.SparseArray,android.util.SparseArray,boolean)
                                          java.lang.Object getEnterTransition(android.support.v4.app.Fragment,boolean)
                                          java.lang.Object getSharedElementTransition(android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean)
                                          java.lang.Object captureExitingViews(java.lang.Object,android.support.v4.app.Fragment,java.util.ArrayList,android.support.v4.util.ArrayMap,android.view.View)
                                          android.support.v4.util.ArrayMap remapSharedElements(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,boolean)
                                          boolean configureTransitions(int,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.util.SparseArray,android.util.SparseArray)
                                          void prepareSharedElementTransition(android.support.v4.app.BackStackRecord$TransitionState,android.view.View,java.lang.Object,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,java.util.ArrayList)
                                          void callSharedElementEnd(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void setEpicenterIn(android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          android.support.v4.util.ArrayMap mapSharedElementsIn(android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          android.support.v4.util.ArrayMap remapNames(java.util.ArrayList,java.util.ArrayList,android.support.v4.util.ArrayMap)
                                          void excludeHiddenFragmentsAfterEnter(android.view.View,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void excludeHiddenFragments(android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
                                          void setNameOverride(android.support.v4.util.ArrayMap,java.lang.String,java.lang.String)
                                          void setNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,java.util.ArrayList,java.util.ArrayList)
                                          void setBackNameOverrides(android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.util.ArrayMap,boolean)
                                          android.support.v4.util.ArrayMap access$000(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,boolean,android.support.v4.app.Fragment)
                                          void access$100(android.support.v4.app.BackStackRecord,android.support.v4.util.ArrayMap,android.support.v4.app.BackStackRecord$TransitionState)
                                          void access$200(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,android.support.v4.app.Fragment,android.support.v4.app.Fragment,boolean,android.support.v4.util.ArrayMap)
                                          void access$300(android.support.v4.app.BackStackRecord,android.support.v4.app.BackStackRecord$TransitionState,int,java.lang.Object)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void showChildFragments(boolean)(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void showLoadingInProgress(boolean)(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyFragment.void onAttach(android.app.Activity)(Unknown Source)
                                              android.view.View onCreateView(android.view.LayoutInflater,android.view.ViewGroup,android.os.Bundle)
                                              void onCreateOptionsMenu(android.view.Menu,android.view.MenuInflater)
                                              android.support.v4.content.Loader onCreateLoader(int,android.os.Bundle)
                                              void onLoadFinished(android.support.v4.content.Loader,android.database.Cursor)
                                              void onLoaderReset(android.support.v4.content.Loader)
                                              void onLoadFinished(android.support.v4.content.Loader,java.lang.Object)
at android.support.v4.app.LoaderManagerImpl.android.support.v4.app.LoaderManagerImpl$LoaderInfo createLoader(int,android.os.Bundle,android.support.v4.app.LoaderManager$LoaderCallbacks)(Unknown Source)
                                            void doStop()
at android.support.v4.app.LoaderManagerImpl.android.support.v4.app.LoaderManagerImpl$LoaderInfo createAndInstallLoader(int,android.os.Bundle,android.support.v4.app.LoaderManager$LoaderCallbacks)(Unknown Source)
                                            void doRetain()
at android.support.v4.app.LoaderManagerImpl.android.support.v4.content.Loader restartLoader(int,android.os.Bundle,android.support.v4.app.LoaderManager$LoaderCallbacks)(Unknown Source)
                                            void doStart()
at com.murrayc.galaxyzoo.app.ClassifyFragment.void update()(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyActivity.void startNextClassification()(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyActivity.void access$500(com.murrayc.galaxyzoo.app.ClassifyActivity)(Unknown Source)
at com.murrayc.galaxyzoo.app.ClassifyActivity$5.void onReceive(android.content.Context,android.content.Intent)(Unknown Source)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:862)
... 8 more

Zoom

Feature suggestion:

Image zoom. The image doesn't need to translate, only zoom on on the central object.
On a small device, the central object might be only a few mm across!

Cannot download new subjects to classify -- again

Since late last year, Galaxy Zoo isn't working.

I log in, it thinks a bit, and says
"Cannot download new subjects to classify".
I am able to log in to the Zooniverse web site without problems.
The network is working fine on the phone. I'm on wireless right now.

This is Galaxy Zoo 1.42 (beta) app for my Android Huawei Y350 running Android 4.4.2
See the previous issue #38

Provide pure floss build flavor

Recent versions introduced Google's Firebase, which is -- unfortunately -- a non-free software component. Could you either remove it, replace it with free crashreporting (like ACRA) or provide a build flavor that does not require this?

No good comes from screen rotation

Suggestion: use the entire right square of the screen for the image,
and the rest for whatever buttons and banners. The image is what's important!

screenshot_galaxyzoo_y360-rot

Android Lollipop needs WRITE_EXTERNAL_STORAGE but it shouldn't.

Android Lollipop throws IOExceptions when reading or writing from the getExternalFilesCacheDir() directory unless we request WRITE_EXTERNAL_STORAGE permission (and READ_EXTERNAL_STORAGE, which is then implicitly requested). But that shouldn't be necessary since API 18:
http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE

This commit requests the permission, but it shouldn't be necessary:
75aa986

I asked this on StackExchange too:
http://stackoverflow.com/questions/27016647/why-do-i-need-the-write-external-storage-permission-with-getexternalcachedir-o?sgp=2

Share the image via the Share menu item

The app now has a Share menu item, but it just shares the URI of the discussion page.

This branch tries to share the image itself, but it isn't working.
https://github.com/murraycu/android-galaxyzoo/commits/share-image

With that code, the Share menu item does nothing. If we comment out the intent.setData() line then we can share to other apps, but they then fail with errors or crashes, presumably due to lack of permission, though we are granting them permission.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.