diff options
Diffstat (limited to 'core/src/main/java/de')
8 files changed, 200 insertions, 226 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java index d056917e1..42e4191f6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java @@ -44,12 +44,45 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr private boolean read; private String paymentLink; private FlattrStatus flattrStatus; + + /** + * Is true if the database contains any chapters that belong to this item. This attribute is only + * written once by DBReader on initialization. + * The FeedItem might still have a non-null chapters value. In this case, the list of chapters + * has not been saved in the database yet. + * */ + private final boolean hasChapters; + + /** + * The list of chapters of this item. This might be null even if there are chapters of this item + * in the database. The 'hasChapters' attribute should be used to check if this item has any chapters. + * */ private List<Chapter> chapters; private FeedImage image; public FeedItem() { this.read = true; this.flattrStatus = new FlattrStatus(); + this.hasChapters = false; + } + + /** + * This constructor is used by DBReader. + * */ + public FeedItem(long id, String title, String link, Date pubDate, String paymentLink, long feedId, + FlattrStatus flattrStatus, boolean hasChapters, FeedImage image, boolean read, + String itemIdentifier) { + this.id = id; + this.title = title; + this.link = link; + this.pubDate = pubDate; + this.paymentLink = paymentLink; + this.feedId = feedId; + this.flattrStatus = flattrStatus; + this.hasChapters = hasChapters; + this.image = image; + this.read = read; + this.itemIdentifier = itemIdentifier; } /** @@ -64,6 +97,22 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr this.read = read; this.feed = feed; this.flattrStatus = new FlattrStatus(); + this.hasChapters = false; + } + + /** + * This constructor should be used for creating test objects involving chapter marks. + */ + public FeedItem(long id, String title, String itemIdentifier, String link, Date pubDate, boolean read, Feed feed, boolean hasChapters) { + this.id = id; + this.title = title; + this.itemIdentifier = itemIdentifier; + this.link = link; + this.pubDate = (pubDate != null) ? (Date) pubDate.clone() : null; + this.read = read; + this.feed = feed; + this.flattrStatus = new FlattrStatus(); + this.hasChapters = hasChapters; } public void updateFromOther(FeedItem other) { @@ -331,4 +380,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr public String getHumanReadableIdentifier() { return title; } + + public boolean hasChapters() { + return hasChapters; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java index defcfd598..2434ee0cf 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java @@ -245,14 +245,19 @@ public class FeedMedia extends FeedFile implements Playable { @Override public void loadChapterMarks() { - if (getChapters() == null && !localFileAvailable()) { + if (item == null && itemID != 0) { + item = DBReader.getFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), itemID); + } + // check if chapters are stored in db and not loaded yet. + if (item != null && item.hasChapters() && item.getChapters() == null) { + DBReader.loadChaptersOfFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), item); + } else if (item != null && item.getChapters() == null && !localFileAvailable()) { ChapterUtils.loadChaptersFromStreamUrl(this); if (getChapters() != null && item != null) { DBWriter.setFeedItem(ClientConfig.applicationCallbacks.getApplicationInstance(), item); } } - } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java index 6c0b6df74..217e6fba5 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java @@ -4,8 +4,22 @@ import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.util.Log; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + import de.danoeh.antennapod.core.BuildConfig; -import de.danoeh.antennapod.core.feed.*; +import de.danoeh.antennapod.core.feed.Chapter; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedImage; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; +import de.danoeh.antennapod.core.feed.FeedPreferences; +import de.danoeh.antennapod.core.feed.ID3Chapter; +import de.danoeh.antennapod.core.feed.SimpleChapter; +import de.danoeh.antennapod.core.feed.VorbisCommentChapter; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.util.DownloadError; import de.danoeh.antennapod.core.util.comparator.DownloadStatusComparator; @@ -14,11 +28,6 @@ import de.danoeh.antennapod.core.util.comparator.PlaybackCompletionDateComparato import de.danoeh.antennapod.core.util.flattr.FlattrStatus; import de.danoeh.antennapod.core.util.flattr.FlattrThing; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - /** * Provides methods for reading data from the AntennaPod database. * In general, all database calls in DBReader-methods are executed on the caller's thread. @@ -203,75 +212,26 @@ public final class DBReader { if (itemlistCursor.moveToFirst()) { do { - FeedItem item = new FeedItem(); - - item.setId(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_ID)); - item.setTitle(itemlistCursor - .getString(PodDBAdapter.IDX_FI_SMALL_TITLE)); - item.setLink(itemlistCursor - .getString(PodDBAdapter.IDX_FI_SMALL_LINK)); - item.setPubDate(new Date(itemlistCursor - .getLong(PodDBAdapter.IDX_FI_SMALL_PUBDATE))); - item.setPaymentLink(itemlistCursor - .getString(PodDBAdapter.IDX_FI_SMALL_PAYMENT_LINK)); - item.setFeedId(itemlistCursor - .getLong(PodDBAdapter.IDX_FI_SMALL_FEED)); - itemIds.add(String.valueOf(item.getId())); - - item.setRead((itemlistCursor - .getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0)); - item.setItemIdentifier(itemlistCursor - .getString(PodDBAdapter.IDX_FI_SMALL_ITEM_IDENTIFIER)); - item.setFlattrStatus(new FlattrStatus(itemlistCursor - .getLong(PodDBAdapter.IDX_FI_SMALL_FLATTR_STATUS))); - long imageIndex = itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_IMAGE); + FeedImage image = null; if (imageIndex != 0) { - item.setImage(getFeedImage(adapter, imageIndex)); + image = getFeedImage(adapter, imageIndex); } - // extract chapters - boolean hasSimpleChapters = itemlistCursor - .getInt(PodDBAdapter.IDX_FI_SMALL_HAS_CHAPTERS) > 0; - if (hasSimpleChapters) { - Cursor chapterCursor = adapter - .getSimpleChaptersOfFeedItemCursor(item); - if (chapterCursor.moveToFirst()) { - item.setChapters(new ArrayList<Chapter>()); - do { - int chapterType = chapterCursor - .getInt(PodDBAdapter.KEY_CHAPTER_TYPE_INDEX); - Chapter chapter = null; - long start = chapterCursor - .getLong(PodDBAdapter.KEY_CHAPTER_START_INDEX); - String title = chapterCursor - .getString(PodDBAdapter.KEY_TITLE_INDEX); - String link = chapterCursor - .getString(PodDBAdapter.KEY_CHAPTER_LINK_INDEX); - - switch (chapterType) { - case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER: - chapter = new SimpleChapter(start, title, item, - link); - break; - case ID3Chapter.CHAPTERTYPE_ID3CHAPTER: - chapter = new ID3Chapter(start, title, item, - link); - break; - case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER: - chapter = new VorbisCommentChapter(start, - title, item, link); - break; - } - if (chapter != null) { - chapter.setId(chapterCursor - .getLong(PodDBAdapter.KEY_ID_INDEX)); - item.getChapters().add(chapter); - } - } while (chapterCursor.moveToNext()); - } - chapterCursor.close(); - } + FeedItem item = new FeedItem(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_ID), + itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_TITLE), + itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_LINK), + new Date(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_PUBDATE)), + itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_PAYMENT_LINK), + itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_FEED), + new FlattrStatus(itemlistCursor.getLong(PodDBAdapter.IDX_FI_SMALL_FLATTR_STATUS)), + itemlistCursor.getInt(PodDBAdapter.IDX_FI_SMALL_HAS_CHAPTERS) > 0, + image, + (itemlistCursor.getInt(PodDBAdapter.IDX_FI_SMALL_READ) > 0), + itemlistCursor.getString(PodDBAdapter.IDX_FI_SMALL_ITEM_IDENTIFIER)); + + itemIds.add(String.valueOf(item.getId())); + items.add(item); } while (itemlistCursor.moveToNext()); } @@ -367,6 +327,7 @@ public final class DBReader { return feed; } + private static FeedItem getMatchingItemForMedia(long itemId, List<FeedItem> items) { for (FeedItem item : items) { @@ -689,6 +650,9 @@ public final class DBReader { if (list.size() > 0) { item = list.get(0); loadFeedDataOfFeedItemlist(context, list); + if (item.hasChapters()) { + loadChaptersOfFeedItem(adapter, item); + } } } return item; @@ -696,12 +660,13 @@ public final class DBReader { } /** - * Loads a specific FeedItem from the database. + * Loads a specific FeedItem from the database. This method should not be used for loading more + * than one FeedItem because this method might query the database several times for each item. * * @param context A context that is used for opening a database connection. * @param itemId The ID of the FeedItem - * @return The FeedItem or null if the FeedItem could not be found. All FeedComponent-attributes of the FeedItem will - * also be loaded from the database. + * @return The FeedItem or null if the FeedItem could not be found. All FeedComponent-attributes + * as well as chapter marks of the FeedItem will also be loaded from the database. */ public static FeedItem getFeedItem(final Context context, final long itemId) { if (BuildConfig.DEBUG) @@ -737,6 +702,63 @@ public final class DBReader { } /** + * Loads the list of chapters that belongs to this FeedItem if available. This method overwrites + * any chapters that this FeedItem has. If no chapters were found in the database, the chapters + * reference of the FeedItem will be set to null. + * + * @param context A context that is used for opening a database connection. + * @param item The FeedItem + */ + public static void loadChaptersOfFeedItem(final Context context, final FeedItem item) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + loadChaptersOfFeedItem(adapter, item); + adapter.close(); + } + + static void loadChaptersOfFeedItem(PodDBAdapter adapter, FeedItem item) { + Cursor chapterCursor = adapter + .getSimpleChaptersOfFeedItemCursor(item); + if (chapterCursor.moveToFirst()) { + item.setChapters(new ArrayList<Chapter>()); + do { + int chapterType = chapterCursor + .getInt(PodDBAdapter.KEY_CHAPTER_TYPE_INDEX); + Chapter chapter = null; + long start = chapterCursor + .getLong(PodDBAdapter.KEY_CHAPTER_START_INDEX); + String title = chapterCursor + .getString(PodDBAdapter.KEY_TITLE_INDEX); + String link = chapterCursor + .getString(PodDBAdapter.KEY_CHAPTER_LINK_INDEX); + + switch (chapterType) { + case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER: + chapter = new SimpleChapter(start, title, item, + link); + break; + case ID3Chapter.CHAPTERTYPE_ID3CHAPTER: + chapter = new ID3Chapter(start, title, item, + link); + break; + case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER: + chapter = new VorbisCommentChapter(start, + title, item, link); + break; + } + if (chapter != null) { + chapter.setId(chapterCursor + .getLong(PodDBAdapter.KEY_ID_INDEX)); + item.getChapters().add(chapter); + } + } while (chapterCursor.moveToNext()); + } else { + item.setChapters(null); + } + chapterCursor.close(); + } + + /** * Returns the number of downloaded episodes. * * @param context A context that is used for opening a database connection. @@ -788,7 +810,7 @@ public final class DBReader { static FeedImage getFeedImage(PodDBAdapter adapter, final long id) { Cursor cursor = adapter.getImageCursor(id); if ((cursor.getCount() == 0) || !cursor.moveToFirst()) { - throw new SQLException("No FeedImage found at index: " + id); + return null; } FeedImage image = new FeedImage(id, cursor.getString(cursor .getColumnIndex(PodDBAdapter.KEY_TITLE)), diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index 148d886ae..f5ee9e28c 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -90,7 +90,7 @@ public class DownloadRequester { return true; } - private void download(Context context, FeedFile item, File dest, + private void download(Context context, FeedFile item, FeedFile container, File dest, boolean overwriteIfExists, String username, String password, boolean deleteOnFailure, Bundle arguments) { if (!isDownloadingFile(item)) { if (!isFilenameAvailable(dest.toString()) || (deleteOnFailure && dest.exists())) { @@ -129,7 +129,8 @@ public class DownloadRequester { if (BuildConfig.DEBUG) Log.d(TAG, "Requesting download of url " + item.getDownload_url()); - item.setDownload_url(URLChecker.prepareURL(item.getDownload_url())); + String baseUrl = (container != null) ? container.getDownload_url() : null; + item.setDownload_url(URLChecker.prepareURL(item.getDownload_url(), baseUrl)); DownloadRequest request = new DownloadRequest(dest.toString(), URLChecker.prepareURL(item.getDownload_url()), item.getHumanReadableIdentifier(), @@ -171,7 +172,7 @@ public class DownloadRequester { args.putInt(REQUEST_ARG_PAGE_NR, feed.getPageNr()); args.putBoolean(REQUEST_ARG_LOAD_ALL_PAGES, loadAllPages); - download(context, feed, new File(getFeedfilePath(context), + download(context, feed, null, new File(getFeedfilePath(context), getFeedfileName(feed)), true, username, password, true, args); } } @@ -183,7 +184,8 @@ public class DownloadRequester { public synchronized void downloadImage(Context context, FeedImage image) throws DownloadRequestException { if (feedFileValid(image)) { - download(context, image, new File(getImagefilePath(context), + FeedFile container = (image.getOwner() instanceof FeedFile) ? (FeedFile) image.getOwner() : null; + download(context, image, container, new File(getImagefilePath(context), getImagefileName(image)), false, null, null, false, null); } } @@ -209,7 +211,7 @@ public class DownloadRequester { dest = new File(getMediafilePath(context, feedmedia), getMediafilename(feedmedia)); } - download(context, feedmedia, + download(context, feedmedia, feed, dest, false, username, password, false, null); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 79124521f..ce41147e1 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -693,7 +693,7 @@ public class PodDBAdapter { } values.put(KEY_FEED, item.getFeed().getId()); values.put(KEY_READ, item.isRead()); - values.put(KEY_HAS_CHAPTERS, item.getChapters() != null); + values.put(KEY_HAS_CHAPTERS, item.getChapters() != null || item.hasChapters()); values.put(KEY_ITEM_IDENTIFIER, item.getItemIdentifier()); values.put(KEY_FLATTR_STATUS, item.getFlattrStatus().toLong()); if (item.hasItemImage()) { @@ -848,7 +848,7 @@ public class PodDBAdapter { if (item.getMedia() != null) { removeFeedMedia(item.getMedia()); } - if (item.getChapters() != null) { + if (item.hasChapters() || item.getChapters() != null) { removeChaptersOfItem(item); } if (item.hasItemImage()) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java index 72e0f053b..1ac389f08 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/util/SyndDateUtils.java @@ -7,13 +7,16 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; +import de.danoeh.antennapod.core.BuildConfig; + /** * Parses several date formats. */ public class SyndDateUtils { private static final String TAG = "DateUtils"; - private static final String[] RFC822DATES = {"dd MMM yy HH:mm:ss Z",}; + private static final String[] RFC822DATES = {"dd MMM yy HH:mm:ss Z", + "dd MMM yy HH:mm Z"}; /** * RFC 3339 date format for UTC dates. @@ -51,17 +54,18 @@ public class SyndDateUtils { date = date.substring(date.indexOf(",") + 1).trim(); } SimpleDateFormat format = RFC822Formatter.get(); - for (int i = 0; i < RFC822DATES.length; i++) { + + for (String RFC822DATE : RFC822DATES) { try { - format.applyPattern(RFC822DATES[i]); + format.applyPattern(RFC822DATE); result = format.parse(date); break; } catch (ParseException e) { - e.printStackTrace(); + if (BuildConfig.DEBUG) Log.d(TAG, "ParserException", e); } } if (result == null) { - Log.e(TAG, "Unable to parse feed date correctly"); + Log.e(TAG, "Unable to parse feed date correctly:" + date); } return result; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java index 4bd18c8bc..4300556d2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/URLChecker.java @@ -1,5 +1,6 @@ package de.danoeh.antennapod.core.util; +import android.net.Uri; import android.util.Log; import org.apache.commons.lang3.StringUtils; @@ -51,4 +52,28 @@ public final class URLChecker { return url; } } + + /** + * Checks if URL is valid and modifies it if necessary. + * This method also handles protocol relative URLs. + * + * @param url The url which is going to be prepared + * @param base The url against which the (possibly relative) url is applied. If this is null, + * the result of prepareURL(url) is returned instead. + * @return The prepared url + */ + public static String prepareURL(String url, String base) { + if (base == null) { + return prepareURL(url); + } + url = StringUtils.trim(url); + base = prepareURL(base); + Uri urlUri = Uri.parse(url); + Uri baseUri = Uri.parse(base); + if (urlUri.isRelative() && baseUri.isAbsolute()) { + return urlUri.buildUpon().scheme(baseUri.getScheme()).build().toString(); + } else { + return prepareURL(url); + } + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/UndoBarController.java b/core/src/main/java/de/danoeh/antennapod/core/util/UndoBarController.java deleted file mode 100644 index 5843c5f8f..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/util/UndoBarController.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2012 Roman Nurik - * - * 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 de.danoeh.antennapod.core.util; - -import android.os.Bundle; -import android.os.Handler; -import android.os.Parcelable; -import android.text.TextUtils; -import android.view.View; -import android.widget.TextView; -import com.nineoldandroids.animation.Animator; -import com.nineoldandroids.animation.AnimatorListenerAdapter; -import com.nineoldandroids.view.ViewHelper; -import com.nineoldandroids.view.ViewPropertyAnimator; -import de.danoeh.antennapod.core.R; - -import static com.nineoldandroids.view.ViewPropertyAnimator.animate; - -public class UndoBarController { - private View mBarView; - private TextView mMessageView; - private ViewPropertyAnimator mBarAnimator; - private Handler mHideHandler = new Handler(); - - private UndoListener mUndoListener; - - // State objects - private Parcelable mUndoToken; - private CharSequence mUndoMessage; - - public interface UndoListener { - void onUndo(Parcelable token); - } - - public UndoBarController(View undoBarView, UndoListener undoListener) { - mBarView = undoBarView; - mBarAnimator = animate(mBarView); - mUndoListener = undoListener; - - mMessageView = (TextView) mBarView.findViewById(R.id.undobar_message); - mBarView.findViewById(R.id.undobar_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - hideUndoBar(false); - mUndoListener.onUndo(mUndoToken); - } - }); - - hideUndoBar(true); - } - - public void showUndoBar(boolean immediate, CharSequence message, Parcelable undoToken) { - mUndoToken = undoToken; - mUndoMessage = message; - mMessageView.setText(mUndoMessage); - - mHideHandler.removeCallbacks(mHideRunnable); - mHideHandler.postDelayed(mHideRunnable, - mBarView.getResources().getInteger(R.integer.undobar_hide_delay)); - - mBarView.setVisibility(View.VISIBLE); - if (immediate) { - ViewHelper.setAlpha(mBarView, 1); - } else { - mBarAnimator.cancel(); - mBarAnimator - .alpha(1) - .setDuration( - mBarView.getResources() - .getInteger(android.R.integer.config_shortAnimTime)) - .setListener(null); - } - } - - public void hideUndoBar(boolean immediate) { - mHideHandler.removeCallbacks(mHideRunnable); - if (immediate) { - mBarView.setVisibility(View.GONE); - ViewHelper.setAlpha(mBarView, 0); - mUndoMessage = null; - mUndoToken = null; - - } else { - mBarAnimator.cancel(); - mBarAnimator - .alpha(0) - .setDuration(mBarView.getResources() - .getInteger(android.R.integer.config_shortAnimTime)) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mBarView.setVisibility(View.GONE); - mUndoMessage = null; - mUndoToken = null; - } - }); - } - } - - public void onSaveInstanceState(Bundle outState) { - outState.putCharSequence("undo_message", mUndoMessage); - outState.putParcelable("undo_token", mUndoToken); - } - - public void onRestoreInstanceState(Bundle savedInstanceState) { - if (savedInstanceState != null) { - mUndoMessage = savedInstanceState.getCharSequence("undo_message"); - mUndoToken = savedInstanceState.getParcelable("undo_token"); - - if (mUndoToken != null || !TextUtils.isEmpty(mUndoMessage)) { - showUndoBar(true, mUndoMessage, mUndoToken); - } - } - } - - private Runnable mHideRunnable = new Runnable() { - @Override - public void run() { - hideUndoBar(false); - } - }; -} |