From 888c8cfcec2aa50870fa243c136e179551c4fad2 Mon Sep 17 00:00:00 2001 From: Matthew Bishop Date: Thu, 21 Nov 2013 22:55:41 -0700 Subject: [PATCH] Fix for crash in Android 4.4, also added saving the position of the story list --- AndroidManifest.xml | 14 +++---- .../billing/IMarketBillingService.aidl | 24 ++++++++++++ .../activity/SlideoutMenuActivity.java | 6 +-- .../hackernews/data/AppData.java | 38 +++++++++++++++++++ .../hackernews/data/UserPrefs.java | 11 +++--- .../hackernews/fragment/StoryFragment.java | 29 +++++++++++--- 6 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 out/production/HackerNews/com/android/vending/billing/IMarketBillingService.aidl create mode 100644 src/com/airlocksoftware/hackernews/data/AppData.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9b9e65f..a20a17e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,8 +2,8 @@ xmlns:tools="http://schemas.android.com/tools" package="com.airlocksoftware.hackernews" android:installLocation="auto" - android:versionCode="12" - android:versionName="2.0.6" > + android:versionCode="13" + android:versionName="2.1.0" > - + + + + + diff --git a/out/production/HackerNews/com/android/vending/billing/IMarketBillingService.aidl b/out/production/HackerNews/com/android/vending/billing/IMarketBillingService.aidl new file mode 100644 index 0000000..6884b41 --- /dev/null +++ b/out/production/HackerNews/com/android/vending/billing/IMarketBillingService.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * 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 com.android.vending.billing; + +import android.os.Bundle; + +interface IMarketBillingService { + /** Given the arguments in bundle form, returns a bundle for results. */ + Bundle sendBillingRequest(in Bundle bundle); +} diff --git a/src/com/airlocksoftware/hackernews/activity/SlideoutMenuActivity.java b/src/com/airlocksoftware/hackernews/activity/SlideoutMenuActivity.java index 7c0e7ef..f9d4ddb 100644 --- a/src/com/airlocksoftware/hackernews/activity/SlideoutMenuActivity.java +++ b/src/com/airlocksoftware/hackernews/activity/SlideoutMenuActivity.java @@ -13,7 +13,6 @@ import android.view.inputmethod.InputMethodManager; import android.widget.TextView; import android.widget.Toast; - import com.airlocksoftware.hackernews.R; import com.airlocksoftware.hackernews.data.UserPrefs; import com.airlocksoftware.hackernews.data.UserPrefs.Theme; @@ -25,7 +24,6 @@ import com.airlocksoftware.holo.checkable.CheckableViewManager.OnCheckedViewChangedListener; import com.airlocksoftware.holo.utils.Utils; import com.airlocksoftware.holo.utils.ViewUtils; -import com.bugsense.trace.BugSenseHandler; import com.slidingmenu.lib.SlidingMenu; import com.slidingmenu.lib.SlidingMenu.OnOpenListener; @@ -62,7 +60,9 @@ public void onCreate(Bundle savedState) { mUserPrefs = new UserPrefs(this); retrieveTheme(); setWindowBackground(); - BugSenseHandler.initAndStartSession(getApplicationContext(), getString(R.string.bugsense_api_key)); + + /* TODO I'm over the quota anyways -- going to move to Crashlytics in the next version. */ +// BugSenseHandler.initAndStartSession(getApplicationContext(), getString(R.string.bugsense_api_key)); // initialize ActionBarActivity layout after setting theme and window background super.initialize(); diff --git a/src/com/airlocksoftware/hackernews/data/AppData.java b/src/com/airlocksoftware/hackernews/data/AppData.java new file mode 100644 index 0000000..b4171ee --- /dev/null +++ b/src/com/airlocksoftware/hackernews/data/AppData.java @@ -0,0 +1,38 @@ +package com.airlocksoftware.hackernews.data; + +import android.content.Context; +import android.content.SharedPreferences; + +/** + * TODO + * + * @author matthewbbishop + */ +public class AppData { + + // State + private Context mContext; + private SharedPreferences mPrefs; + private SharedPreferences.Editor mEditor; + + // Constants + public static final String PREFS_NAME = AppData.class.getSimpleName() + ".data"; + public static final String STORY_LIST_POSITION = AppData.class.getSimpleName() + ".story_list_position"; + + public AppData(Context context) { + mContext = context; + mPrefs = mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + mEditor = mPrefs.edit(); + } + + public void saveStoryListPosition(int position) { + mEditor.putInt(STORY_LIST_POSITION, position); + mEditor.commit(); + } + + public int getStoryListPosition() { + int position = mPrefs.getInt(STORY_LIST_POSITION, 0); + return position; + } + +} diff --git a/src/com/airlocksoftware/hackernews/data/UserPrefs.java b/src/com/airlocksoftware/hackernews/data/UserPrefs.java index 186687b..9832480 100644 --- a/src/com/airlocksoftware/hackernews/data/UserPrefs.java +++ b/src/com/airlocksoftware/hackernews/data/UserPrefs.java @@ -1,13 +1,12 @@ package com.airlocksoftware.hackernews.data; -import java.text.SimpleDateFormat; -import java.util.Calendar; - -import org.apache.commons.lang3.StringUtils; - import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; +import org.apache.commons.lang3.StringUtils; + +import java.text.SimpleDateFormat; +import java.util.Calendar; /** Encapsulates methods for interacting with SharedPreferences that the user's preferences. **/ public class UserPrefs { @@ -159,7 +158,7 @@ public void saveOpenInBrowser(boolean enabled) { // } public enum Theme { - LIGHT, DARK; + LIGHT, DARK } public Theme getTheme() { diff --git a/src/com/airlocksoftware/hackernews/fragment/StoryFragment.java b/src/com/airlocksoftware/hackernews/fragment/StoryFragment.java index 605fb4c..b9412da 100644 --- a/src/com/airlocksoftware/hackernews/fragment/StoryFragment.java +++ b/src/com/airlocksoftware/hackernews/fragment/StoryFragment.java @@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.view.LayoutInflater; @@ -15,18 +16,14 @@ import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; - import com.airlocksoftware.hackernews.R; import com.airlocksoftware.hackernews.activity.MainActivity; import com.airlocksoftware.hackernews.adapter.StoryAdapter; +import com.airlocksoftware.hackernews.data.AppData; import com.airlocksoftware.hackernews.interfaces.SharePopupInterface; import com.airlocksoftware.hackernews.interfaces.TabletLayout; import com.airlocksoftware.hackernews.loader.StoryLoader; -import com.airlocksoftware.hackernews.model.Comment; -import com.airlocksoftware.hackernews.model.Page; -import com.airlocksoftware.hackernews.model.Request; -import com.airlocksoftware.hackernews.model.Result; -import com.airlocksoftware.hackernews.model.Story; +import com.airlocksoftware.hackernews.model.*; import com.airlocksoftware.hackernews.parser.StoryParser.StoryResponse; import com.airlocksoftware.hackernews.view.SharePopup; import com.airlocksoftware.holo.actionbar.ActionBarButton; @@ -45,6 +42,7 @@ public class StoryFragment extends Fragment implements ActionBarClient, LoaderMa private Request mRequest = Request.NEW; private Result mLastResult = Result.EMPTY; private boolean mIsLoading = false; + private boolean mShouldRestoreListState; // Activity interfaces TabletLayout mTabletLayout = null; @@ -150,9 +148,20 @@ public void onActivityCreated(Bundle savedInstanceState) { mAdapter.onRestoreInstanceState(savedInstanceState); } + mShouldRestoreListState = true; + refreshContentVisibility(); } + @Override + public void onPause() { + /* Save list state to shared prefs (since we kill the activity when we switch to the comments list) */ + FragmentActivity activity = getActivity(); + if(activity == null) return; + new AppData(activity).saveStoryListPosition(mList.getFirstVisiblePosition()); + super.onPause(); + } + @SuppressWarnings("deprecation") private void setupTabletBackgroundColors() { Resources res = getActivity().getResources(); @@ -207,10 +216,12 @@ private void findViews() { @Override public void onSaveInstanceState(Bundle outState) { + /* Save to bundle */ if (!mCallbacks.storyFragmentIsInLayout()) return; outState.putSerializable(PAGE, mPage); outState = mAdapter.onSaveInstanceState(outState); super.onSaveInstanceState(outState); + } // Loader interface @@ -264,6 +275,12 @@ public void onLoadFinished(Loader loader, StoryResponse response) showMoreLink(); checkForExpiredCache(response); refreshContentVisibility(); + + if(mShouldRestoreListState) { + mShouldRestoreListState = false; + int listPosition = new AppData(getActivity()).getStoryListPosition(); + mList.setSelectionFromTop(listPosition, 0); + } } private void checkForExpiredCache(StoryResponse response) {