summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml300
-rw-r--r--res/layout/gpodnet_main.xml21
-rw-r--r--res/layout/gpodnet_podcast_listitem.xml6
-rw-r--r--res/layout/gpodnet_search.xml12
-rw-r--r--res/layout/gpodnet_tag_activity.xml12
-rw-r--r--res/layout/itemdescription_listitem.xml27
-rw-r--r--res/layout/onlinefeedview_header.xml39
-rw-r--r--res/values/colors.xml1
-rw-r--r--res/values/strings.xml5
-rw-r--r--res/xml/gpodnet_searchable.xml5
-rw-r--r--src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java46
-rw-r--r--src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java422
-rw-r--r--src/de/danoeh/antennapod/activity/gpoddernet/GpodnetActivity.java44
-rw-r--r--src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java58
-rw-r--r--src/de/danoeh/antennapod/activity/gpoddernet/GpodnetSearchActivity.java50
-rw-r--r--src/de/danoeh/antennapod/activity/gpoddernet/GpodnetTagActivity.java51
-rw-r--r--src/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java55
-rw-r--r--src/de/danoeh/antennapod/asynctask/ImageDiskCache.java13
-rw-r--r--src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java17
-rw-r--r--src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java5
-rw-r--r--src/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java48
-rw-r--r--src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java96
22 files changed, 971 insertions, 362 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0d041079c..36ff8eef7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,345 +1,387 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="de.danoeh.antennapod"
- android:versionCode="31"
- android:versionName="0.9.7.4" >
+ package="de.danoeh.antennapod"
+ android:versionCode="31"
+ android:versionName="0.9.7.4">
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk
android:minSdkVersion="10"
- android:targetSdkVersion="18" />
+ android:targetSdkVersion="18"/>
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
- android:xlargeScreens="true" />
+ android:xlargeScreens="true"/>
<uses-feature
android:name="android.hardware.screen.portrait"
- android:required="false" />
+ android:required="false"/>
<uses-feature
android:name="android.hardware.touchscreen"
- android:required="false" />
+ android:required="false"/>
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name="de.danoeh.antennapod.PodcastApp"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:logo="@drawable/ic_launcher"
- android:theme="@style/Theme.AntennaPod.Light" >
+ android:theme="@style/Theme.AntennaPod.Light">
<activity
android:name=".activity.MainActivity"
android:configChanges="keyboardHidden|orientation"
- android:label="@string/app_name" >
+ android:label="@string/app_name">
<meta-data
android:name="android.app.default_searchable"
- android:value="de.danoeh.antennapod.activity.SearchActivity" />
+ android:value="de.danoeh.antennapod.activity.SearchActivity"/>
<meta-data
android:name="android.app.searchable"
- android:resource="@xml/searchable" />
+ android:resource="@xml/searchable"/>
+
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="de.danoeh.antennapod.activity.AddFeedActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/add_new_feed_label"
- android:windowSoftInputMode="adjustResize" >
+ android:windowSoftInputMode="adjustResize">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+
+ <data android:scheme="http"/>
+ <data android:scheme="https"/>
+ <data android:host="*"/>
+ <data android:pathPattern=".*\\.xml"/>
+ <data android:pathPattern=".*\\.rss"/>
+ </intent-filter>
+
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+
+ <data android:scheme="http"/>
+ <data android:scheme="https"/>
+ <data android:host="feeds.feedburner.com"/>
+ <data android:host="feedproxy.google.com"/>
+ <data android:host="feeds2.feedburner.com"/>
+ <data android:host="feedsproxy.google.com"/>
+ </intent-filter>
+
<intent-filter>
- <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
- <data android:scheme="http"/>
- <data android:scheme="https"/>
- <data android:host="*"/>
- <data android:pathPattern=".*\\.xml"/>
- <data android:pathPattern=".*\\.rss"/>
- </intent-filter>
-
- <intent-filter>
- <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
- <data android:scheme="http"/>
- <data android:scheme="https"/>
- <data android:host="feeds.feedburner.com"/>
- <data android:host="feedproxy.google.com"/>
- <data android:host="feeds2.feedburner.com"/>
- <data android:host="feedsproxy.google.com"/>
- </intent-filter>
-
- <intent-filter>
- <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT"/>
- <category android:name="android.intent.category.BROWSABLE"/>
- <data android:scheme="http"/>
- <data android:scheme="https"/>
- <data android:mimeType="text/xml"/>
- <data android:mimeType="application/rss+xml"/>
- <data android:mimeType="application/atom+xml"/>
- <data android:mimeType="application/xml"/>
- </intent-filter>
+ <action android:name="android.intent.action.VIEW"/>
+
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+
+ <data android:scheme="http"/>
+ <data android:scheme="https"/>
+ <data android:mimeType="text/xml"/>
+ <data android:mimeType="application/rss+xml"/>
+ <data android:mimeType="application/atom+xml"/>
+ <data android:mimeType="application/xml"/>
+ </intent-filter>
<intent-filter>
- <action android:name="android.intent.action.SEND" />
+ <action android:name="android.intent.action.SEND"/>
- <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.DEFAULT"/>
- <data android:mimeType="text/plain" />
+ <data android:mimeType="text/plain"/>
</intent-filter>
</activity>
<activity
android:name="de.danoeh.antennapod.activity.FeedItemlistActivity"
- android:configChanges="orientation|screenSize" >
+ android:configChanges="orientation|screenSize">
<meta-data
android:name="android.app.default_searchable"
- android:value="de.danoeh.antennapod.activity.SearchActivity" />
+ android:value="de.danoeh.antennapod.activity.SearchActivity"/>
<meta-data
android:name="android.app.searchable"
- android:resource="@xml/searchable" />
+ android:resource="@xml/searchable"/>
</activity>
<activity
android:name="de.danoeh.antennapod.activity.ItemviewActivity"
- android:configChanges="keyboard|orientation" />
+ android:configChanges="keyboard|orientation"/>
<activity
android:name="de.danoeh.antennapod.activity.DownloadActivity"
- android:label="@string/downloads_label" />
+ android:label="@string/downloads_label"/>
<activity
android:name=".activity.AudioplayerActivity"
- android:launchMode="singleTop" >
+ android:launchMode="singleTop">
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
- <data android:scheme="file" />
- <data android:mimeType="audio/*" />
+ <data android:scheme="file"/>
+ <data android:mimeType="audio/*"/>
</intent-filter>
</activity>
<service
android:name=".service.download.DownloadService"
- android:enabled="true" />
+ android:enabled="true"/>
<service
android:name="de.danoeh.antennapod.service.PlaybackService"
- android:enabled="true" >
+ android:enabled="true">
</service>
<activity
android:name=".activity.PreferenceActivity"
android:configChanges="keyboardHidden|orientation"
- android:label="@string/settings_label" >
+ android:label="@string/settings_label">
</activity>
<activity
android:name=".activity.DownloadLogActivity"
- android:label="@string/download_log_label" >
+ android:label="@string/download_log_label">
</activity>
<receiver
android:name=".receiver.MediaButtonReceiver"
- android:exported="true" >
+ android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MEDIA_BUTTON" />
+ <action android:name="android.intent.action.MEDIA_BUTTON"/>
</intent-filter>
<intent-filter>
- <action android:name="de.danoeh.antennapod.NOTIFY_BUTTON_RECEIVER" />
+ <action android:name="de.danoeh.antennapod.NOTIFY_BUTTON_RECEIVER"/>
</intent-filter>
</receiver>
- <activity android:name=".activity.FeedInfoActivity" >
+ <activity android:name=".activity.FeedInfoActivity">
</activity>
<service
android:name=".service.PlayerWidgetService"
android:enabled="true"
- android:exported="false" >
+ android:exported="false">
</service>
- <receiver android:name=".receiver.PlayerWidget" >
+ <receiver android:name=".receiver.PlayerWidget">
<intent-filter>
- <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<intent-filter>
- <action android:name="de.danoeh.antennapod.FORCE_WIDGET_UPDATE" />
+ <action android:name="de.danoeh.antennapod.FORCE_WIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
- android:resource="@xml/player_widget_info" />
+ android:resource="@xml/player_widget_info"/>
<intent-filter>
- <action android:name="de.danoeh.antennapod.STOP_WIDGET_UPDATE" />
+ <action android:name="de.danoeh.antennapod.STOP_WIDGET_UPDATE"/>
</intent-filter>
</receiver>
- <receiver android:name=".receiver.FeedUpdateReceiver" >
+ <receiver android:name=".receiver.FeedUpdateReceiver">
<intent-filter>
- <action android:name="de.danoeh.antennapod.feedupdatereceiver.refreshFeeds" />
+ <action android:name="de.danoeh.antennapod.feedupdatereceiver.refreshFeeds"/>
</intent-filter>
</receiver>
- <activity android:name=".activity.StorageErrorActivity" >
+ <activity android:name=".activity.StorageErrorActivity">
</activity>
<activity
android:name=".activity.FlattrAuthActivity"
- android:label="@string/flattr_auth_label" >
+ android:label="@string/flattr_auth_label">
<intent-filter>
- <action android:name=".activities.FlattrAuthActivity" />
+ <action android:name=".activities.FlattrAuthActivity"/>
- <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="de.danoeh.antennapod"
- android:scheme="flattr4j" />
+ android:scheme="flattr4j"/>
</intent-filter>
</activity>
<activity
android:name=".activity.AboutActivity"
- android:label="@string/about_pref" >
+ android:label="@string/about_pref">
</activity>
<activity
android:name=".activity.OpmlImportFromPathActivity"
android:configChanges="keyboardHidden|orientation"
- android:label="@string/opml_import_label" >
+ android:label="@string/opml_import_label">
</activity>
<activity
android:name=".activity.OpmlImportFromIntentActivity"
android:configChanges="keyboardHidden|orientation"
- android:label="@string/opml_import_label" >
+ android:label="@string/opml_import_label">
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="*"
android:mimeType="*/*"
android:pathPattern=".*\\.opml"
- android:scheme="file" />
+ android:scheme="file"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="*"
android:pathPattern=".*\\.opml"
android:scheme="file"
- android:mimeType="text/x-opml" />
+ android:mimeType="text/x-opml"/>
</intent-filter>
</activity>
<activity
android:name=".activity.OpmlFeedChooserActivity"
- android:label="@string/opml_import_label" >
+ android:label="@string/opml_import_label">
</activity>
<activity
android:name=".activity.SearchActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/search_results_label"
- android:launchMode="singleTop" >
+ android:launchMode="singleTop">
<intent-filter>
- <action android:name="android.intent.action.SEARCH" />
+ <action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<meta-data
android:name="android.app.searchable"
- android:resource="@xml/searchable" />
+ android:resource="@xml/searchable"/>
</activity>
<activity
android:name=".activity.MiroGuideMainActivity"
- android:label="@string/miro_guide_label" >
+ android:label="@string/miro_guide_label">
<meta-data
android:name="android.app.default_searchable"
- android:value="de.danoeh.antennapod.activity.MiroGuideSearchActivity" />
+ android:value="de.danoeh.antennapod.activity.MiroGuideSearchActivity"/>
<meta-data
android:name="android.app.searchable"
- android:resource="@xml/miroguide_searchable" />
+ android:resource="@xml/miroguide_searchable"/>
</activity>
<activity
android:name=".activity.MiroGuideSearchActivity"
android:configChanges="keyboardHidden|orientation"
- android:launchMode="singleTop" >
+ android:launchMode="singleTop">
<intent-filter>
- <action android:name="android.intent.action.SEARCH" />
+ <action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<meta-data
android:name="android.app.searchable"
- android:resource="@xml/miroguide_searchable" />
+ android:resource="@xml/miroguide_searchable"/>
</activity>
<activity
android:name=".activity.MiroGuideCategoryActivity"
- android:configChanges="keyboardHidden|orientation" >
+ android:configChanges="keyboardHidden|orientation">
</activity>
<activity
android:name=".activity.MiroGuideChannelViewActivity"
android:configChanges="keyboard|orientation"
- android:label="@string/miro_guide_label" >
+ android:label="@string/miro_guide_label">
</activity>
<activity
android:name=".activity.VideoplayerActivity"
android:configChanges="keyboardHidden|orientation"
- android:screenOrientation="landscape" >
+ android:screenOrientation="landscape">
<intent-filter>
- <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.VIEW"/>
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
- <data android:scheme="file" />
- <data android:mimeType="video/*" />
+ <data android:scheme="file"/>
+ <data android:mimeType="video/*"/>
</intent-filter>
</activity>
<activity
android:name=".activity.PlaybackHistoryActivity"
- android:label="@string/playback_history_label" />
+ android:label="@string/playback_history_label"/>
<activity
android:name=".activity.DirectoryChooserActivity"
- android:label="@string/choose_data_directory" />
+ android:label="@string/choose_data_directory"/>
<activity
android:name=".activity.OrganizeQueueActivity"
android:configChanges="orientation"
- android:label="@string/organize_queue_label" >
+ android:label="@string/organize_queue_label">
</activity>
<activity
android:name=".activity.gpoddernet.GpodnetMainActivity"
android:configChanges="orientation"
- android:label="@string/gpodnet_main_label"/>
+ android:label="@string/gpodnet_main_label">
+
+ <meta-data
+ android:name="android.app.default_searchable"
+ android:value="de.danoeh.antennapod.activity.gpoddernet.GpodnetSearchActivity"/>
+ <meta-data
+ android:name="android.app.searchable"
+ android:resource="@xml/gpodnet_searchable"/>
+ </activity>
+ <activity
+ android:name=".activity.gpoddernet.GpodnetTagActivity"
+ android:configChanges="orientation">
+ <meta-data
+ android:name="android.app.default_searchable"
+ android:value="de.danoeh.antennapod.activity.gpoddernet.GpodnetSearchActivity"/>
+ <meta-data
+ android:name="android.app.searchable"
+ android:resource="@xml/gpodnet_searchable"/>
+ </activity>
+
+ <activity
+ android:name=".activity.gpoddernet.GpodnetSearchActivity"
+ android:configChanges="orientation"
+ android:label="@string/search_label"
+ android:launchMode="singleTop">
+ <intent-filter>
+ <action android:name="android.intent.action.SEARCH"/>
+ </intent-filter>
+ <meta-data
+ android:name="android.app.searchable"
+ android:resource="@xml/gpodnet_searchable"/>
+ </activity>
+
+ <activity
+ android:name=".activity.DefaultOnlineFeedViewActivity"
+ android:configChanges="orientation"/>
- <receiver android:name=".receiver.ConnectivityActionReceiver" >
+ <receiver android:name=".receiver.ConnectivityActionReceiver">
<intent-filter>
- <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+ <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
- <receiver android:name=".receiver.AlarmUpdateReceiver" >
+ <receiver android:name=".receiver.AlarmUpdateReceiver">
<intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.PACKAGE_REPLACED" />
+ <action android:name="android.intent.action.PACKAGE_REPLACED"/>
<data
android:path="de.danoeh.antennapod"
- android:scheme="package" />
+ android:scheme="package"/>
</intent-filter>
</receiver>
</application>
diff --git a/res/layout/gpodnet_main.xml b/res/layout/gpodnet_main.xml
index 7e382a641..1017a6a65 100644
--- a/res/layout/gpodnet_main.xml
+++ b/res/layout/gpodnet_main.xml
@@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+ android:id="@+id/main_view"
android:layout_width="match_parent"
- android:layout_height="match_parent">
- <FrameLayout
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/viewpager"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/toplist_fragment"/>
+ android:layout_height="0px"
+ android:layout_weight="1">
+ <android.support.v4.view.PagerTabStrip
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top" />
+ </android.support.v4.view.ViewPager>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/res/layout/gpodnet_podcast_listitem.xml b/res/layout/gpodnet_podcast_listitem.xml
index 596eee136..f6ddb3bd8 100644
--- a/res/layout/gpodnet_podcast_listitem.xml
+++ b/res/layout/gpodnet_podcast_listitem.xml
@@ -5,8 +5,8 @@
android:layout_height="match_parent">
<ImageView
android:id="@+id/imgvCover"
- android:layout_width="@dimen/thumbnail_length"
- android:layout_height="@dimen/thumbnail_length"
+ android:layout_width="@dimen/thumbnail_length_itemlist"
+ android:layout_height="@dimen/thumbnail_length_itemlist"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="4dip"
@@ -16,7 +16,7 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="@dimen/thumbnail_length"
+ android:layout_height="@dimen/thumbnail_length_itemlist"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/imgvCover"
android:layout_marginRight="8dp"
diff --git a/res/layout/gpodnet_search.xml b/res/layout/gpodnet_search.xml
new file mode 100644
index 000000000..deb9cffd6
--- /dev/null
+++ b/res/layout/gpodnet_search.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <FrameLayout
+ android:id="@+id/searchListFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/gpodnet_tag_activity.xml b/res/layout/gpodnet_tag_activity.xml
new file mode 100644
index 000000000..01feb216f
--- /dev/null
+++ b/res/layout/gpodnet_tag_activity.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <FrameLayout
+ android:id="@+id/taglistFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/itemdescription_listitem.xml b/res/layout/itemdescription_listitem.xml
new file mode 100644
index 000000000..d6a3f6a16
--- /dev/null
+++ b/res/layout/itemdescription_listitem.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/txtvTitle"
+ android:layout_margin="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:lines="1"
+ android:ellipsize="end"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="@dimen/text_size_small"/>
+
+ <TextView
+ android:id="@+id/txtvDescription"
+ android:layout_margin="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:lines="3"
+ android:ellipsize="end"
+ android:textColor="?android:attr/textColorTertiary"
+ android:textSize="@dimen/text_size_micro"/>
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/onlinefeedview_header.xml b/res/layout/onlinefeedview_header.xml
new file mode 100644
index 000000000..59b7a9b24
--- /dev/null
+++ b/res/layout/onlinefeedview_header.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:id="@+id/imgvCover"
+ android:layout_width="@dimen/thumbnail_length_itemlist"
+ android:layout_height="@dimen/thumbnail_length_itemlist"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_margin="4dp"/>
+
+ <TextView
+ android:id="@+id/txtvTitle"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:ellipsize="end"
+ android:gravity="center_vertical"
+ android:layout_alignTop="@id/imgvCover"
+ android:layout_alignBottom="@id/imgvCover"
+ android:layout_toRightOf="@id/imgvCover"
+ android:layout_alignParentRight="true"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="@dimen/text_size_large"
+ android:layout_margin="4dp"/>
+
+ <TextView
+ android:id="@+id/txtvDescription"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/imgvCover"
+ android:maxLines="3"
+ android:ellipsize="end"
+ android:textColor="?android:attr/textColorTertiary"
+ android:textSize="@dimen/text_size_micro"
+ android:layout_margin="4dp"/>
+</RelativeLayout> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 5cf84ec4a..a666f8967 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -28,6 +28,7 @@
<color name="status_playing">#E0EE5F52</color>
<color name="overlay_dark">#262C31</color>
<color name="overlay_light">#DDDDDD</color>
+ <color name="default_image_color">#858585</color>
<!-- Use Gingerbread-orange -->
<color name="selection_background_color_dark">#FEBB20</color>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 78a92e249..2709f6c4c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -238,6 +238,11 @@
<string name="add_feed_label">Add feed</string>
<string name="miro_feed_added">Feed is being added</string>
+ <!-- gpodder.net -->
+ <string name="gpodnet_taglist_header">CATEGORIES</string>
+ <string name="gpodnet_toplist_header">TOP PODCASTS</string>
+ <string name="gpodnet_search_hint">Search gpodder.net</string>
+
<!-- Directory chooser -->
<string name="selected_folder_label">Selected folder:</string>
<string name="create_folder_label">Create folder</string>
diff --git a/res/xml/gpodnet_searchable.xml b/res/xml/gpodnet_searchable.xml
new file mode 100644
index 000000000..d2c14d7f7
--- /dev/null
+++ b/res/xml/gpodnet_searchable.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<searchable xmlns:android="http://schemas.android.com/apk/res/android" android:hint="@string/gpodnet_search_hint" android:label="@string/app_name" android:icon="@drawable/ic_launcher">
+
+
+</searchable> \ No newline at end of file
diff --git a/src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java b/src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
new file mode 100644
index 000000000..c72c777c1
--- /dev/null
+++ b/src/de/danoeh/antennapod/activity/DefaultOnlineFeedViewActivity.java
@@ -0,0 +1,46 @@
+package de.danoeh.antennapod.activity;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.adapter.FeedItemlistDescriptionAdapter;
+import de.danoeh.antennapod.asynctask.ImageDiskCache;
+import de.danoeh.antennapod.feed.Feed;
+
+/**
+ * Created by daniel on 24.08.13.
+ */
+public class DefaultOnlineFeedViewActivity extends OnlineFeedViewActivity {
+
+ @Override
+ protected void showFeedInformation(Feed feed) {
+ super.showFeedInformation(feed);
+ setContentView(R.layout.listview_activity);
+
+ ListView listView = (ListView) findViewById(R.id.listview);
+ LayoutInflater inflater = (LayoutInflater)
+ getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View header = inflater.inflate(R.layout.onlinefeedview_header, null);
+ listView.addHeaderView(header);
+
+ listView.setAdapter(new FeedItemlistDescriptionAdapter(this, 0, feed.getItems()));
+
+ ImageView cover = (ImageView) header.findViewById(R.id.imgvCover);
+ TextView title = (TextView) header.findViewById(R.id.txtvTitle);
+ TextView description = (TextView) header.findViewById(R.id.txtvDescription);
+
+ if (feed.getImage() != null) {
+ ImageDiskCache.getDefaultInstance().loadThumbnailBitmap(feed.getImage().getDownload_url(), cover, (int) getResources().getDimension(
+ R.dimen.thumbnail_length));
+ }
+ title.setText(feed.getTitle());
+ description.setText(feed.getDescription());
+
+
+ }
+}
+
diff --git a/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
index fbac7057d..ff2e4987e 100644
--- a/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/src/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -1,23 +1,15 @@
package de.danoeh.antennapod.activity;
-import java.io.File;
-import java.io.IOException;
-import java.util.Date;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import android.support.v7.app.ActionBarActivity;
-import org.xml.sax.SAXException;
-
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
-
+import android.widget.RelativeLayout;
import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.feed.Feed;
@@ -25,7 +17,6 @@ import de.danoeh.antennapod.preferences.UserPreferences;
import de.danoeh.antennapod.service.download.DownloadRequest;
import de.danoeh.antennapod.service.download.DownloadStatus;
import de.danoeh.antennapod.service.download.Downloader;
-import de.danoeh.antennapod.service.download.DownloaderCallback;
import de.danoeh.antennapod.service.download.HttpDownloader;
import de.danoeh.antennapod.syndication.handler.FeedHandler;
import de.danoeh.antennapod.syndication.handler.UnsupportedFeedtypeException;
@@ -33,207 +24,230 @@ import de.danoeh.antennapod.util.DownloadError;
import de.danoeh.antennapod.util.FileNameGenerator;
import de.danoeh.antennapod.util.StorageUtils;
import de.danoeh.antennapod.util.URLChecker;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
/**
* Downloads a feed from a feed URL and parses it. Subclasses can display the
* feed object that was parsed. This activity MUST be started with a given URL
* or an Exception will be thrown.
- *
+ * <p/>
* If the feed cannot be downloaded or parsed, an error dialog will be displayed
* and the activity will finish as soon as the error dialog is closed.
*/
public abstract class OnlineFeedViewActivity extends ActionBarActivity {
- private static final String TAG = "OnlineFeedViewActivity";
- private static final String ARG_FEEDURL = "arg.feedurl";
-
- public static final int RESULT_ERROR = 2;
-
- private Feed feed;
- private Downloader downloader;
-
- @Override
- protected void onCreate(Bundle arg0) {
- setTheme(UserPreferences.getTheme());
- super.onCreate(arg0);
- StorageUtils.checkStorageAvailability(this);
- final String feedUrl = getIntent().getStringExtra(ARG_FEEDURL);
- if (feedUrl == null) {
- throw new IllegalArgumentException(
- "Activity must be started with feedurl argument!");
- }
- if (AppConfig.DEBUG)
- Log.d(TAG, "Activity was started with url " + feedUrl);
- setLoadingLayout();
- startFeedDownload(feedUrl);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- if (downloader != null && !downloader.isFinished()) {
- downloader.cancel();
- }
- }
-
- private DownloaderCallback downloaderCallback = new DownloaderCallback() {
- @Override
- public void onDownloadCompleted(final Downloader downloader) {
- runOnUiThread(new Runnable() {
-
- @Override
- public void run() {
- DownloadStatus status = downloader.getResult();
- if (status != null) {
- if (!status.isCancelled()) {
- if (status.isSuccessful()) {
- parseFeed();
- } else {
- String errorMsg = status.getReason().getErrorString(
- OnlineFeedViewActivity.this);
- if (errorMsg != null
- && status.getReasonDetailed() != null) {
- errorMsg += " ("
- + status.getReasonDetailed() + ")";
- }
- showErrorDialog(errorMsg);
- }
- }
- } else {
- Log.wtf(TAG,
- "DownloadStatus returned by Downloader was null");
- finish();
- }
- }
- });
-
- }
- };
-
- private void startFeedDownload(String url) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Starting feed download");
- url = URLChecker.prepareURL(url);
- feed = new Feed(url, new Date());
- String fileUrl = new File(getExternalCacheDir(),
- FileNameGenerator.generateFileName(feed.getDownload_url()))
- .toString();
- feed.setFile_url(fileUrl);
- DownloadRequest request = new DownloadRequest(feed.getFile_url(),
- feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED);
- /* TODO update
- HttpDownloader httpDownloader = new HttpDownloader(downloaderCallback,
- request);
- httpDownloader.start();
- */
- }
-
- /** Displays a progress indicator. */
- private void setLoadingLayout() {
- LinearLayout ll = new LinearLayout(this);
- LinearLayout.LayoutParams llLayoutParams = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT,
- LinearLayout.LayoutParams.MATCH_PARENT);
-
- ProgressBar pb = new ProgressBar(this);
- pb.setIndeterminate(true);
- LinearLayout.LayoutParams pbLayoutParams = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.WRAP_CONTENT,
- LinearLayout.LayoutParams.WRAP_CONTENT);
- pbLayoutParams.gravity = Gravity.CENTER;
- ll.addView(pb, pbLayoutParams);
- addContentView(ll, llLayoutParams);
- }
-
- private void parseFeed() {
- if (feed == null || feed.getFile_url() == null) {
- throw new IllegalStateException(
- "feed must be non-null and downloaded when parseFeed is called");
- }
-
- if (AppConfig.DEBUG)
- Log.d(TAG, "Parsing feed");
-
- Thread thread = new Thread() {
-
- @Override
- public void run() {
- String reasonDetailed = "";
- boolean successful = false;
- FeedHandler handler = new FeedHandler();
- try {
- handler.parseFeed(feed);
- successful = true;
- } catch (SAXException e) {
- e.printStackTrace();
- reasonDetailed = e.getMessage();
- } catch (IOException e) {
- e.printStackTrace();
- reasonDetailed = e.getMessage();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- reasonDetailed = e.getMessage();
- } catch (UnsupportedFeedtypeException e) {
- e.printStackTrace();
- reasonDetailed = e.getMessage();
- } finally {
- boolean rc = new File(feed.getFile_url()).delete();
- if (AppConfig.DEBUG)
- Log.d(TAG, "Deleted feed source file. Result: " + rc);
- }
-
- if (successful) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- showFeedInformation();
- }
- });
- } else {
- final String errorMsg =
- DownloadError.ERROR_PARSER_EXCEPTION.getErrorString(
- OnlineFeedViewActivity.this)
- + " (" + reasonDetailed + ")";
- runOnUiThread(new Runnable() {
-
- @Override
- public void run() {
- showErrorDialog(errorMsg);
- }
- });
- }
- }
- };
- thread.start();
- }
-
- /** Called when feed parsed successfully */
- protected void showFeedInformation() {
-
- }
-
- private void showErrorDialog(String errorMsg) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.error_label);
- if (errorMsg != null) {
- builder.setMessage(getString(R.string.error_msg_prefix) + errorMsg);
- } else {
- builder.setMessage(R.string.error_msg_prefix);
- }
- builder.setNeutralButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
- builder.setOnCancelListener(new OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- setResult(RESULT_ERROR);
- finish();
- }
- });
- }
+ private static final String TAG = "OnlineFeedViewActivity";
+ public static final String ARG_FEEDURL = "arg.feedurl";
+
+ /** Optional argument: specify a title for the actionbar. */
+ public static final String ARG_TITLE = "title";
+
+ public static final int RESULT_ERROR = 2;
+
+ private Feed feed;
+ private Downloader downloader;
+
+ @Override
+ protected void onCreate(Bundle arg0) {
+ setTheme(UserPreferences.getTheme());
+ super.onCreate(arg0);
+
+ if (getIntent() != null && getIntent().hasExtra(ARG_TITLE)) {
+ getSupportActionBar().setTitle(getIntent().getStringExtra(ARG_TITLE));
+ }
+
+ StorageUtils.checkStorageAvailability(this);
+ final String feedUrl = getIntent().getStringExtra(ARG_FEEDURL);
+ if (feedUrl == null) {
+ throw new IllegalArgumentException(
+ "Activity must be started with feedurl argument!");
+ }
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Activity was started with url " + feedUrl);
+ setLoadingLayout();
+ startFeedDownload(feedUrl);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ if (downloader != null && !downloader.isFinished()) {
+ downloader.cancel();
+ }
+ }
+
+
+ private void onDownloadCompleted(final Downloader downloader) {
+ runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ if (AppConfig.DEBUG) Log.d(TAG, "Download was completed");
+ DownloadStatus status = downloader.getResult();
+ if (status != null) {
+ if (!status.isCancelled()) {
+ if (status.isSuccessful()) {
+ parseFeed();
+ } else {
+ String errorMsg = status.getReason().getErrorString(
+ OnlineFeedViewActivity.this);
+ if (errorMsg != null
+ && status.getReasonDetailed() != null) {
+ errorMsg += " ("
+ + status.getReasonDetailed() + ")";
+ }
+ showErrorDialog(errorMsg);
+ }
+ }
+ } else {
+ Log.wtf(TAG,
+ "DownloadStatus returned by Downloader was null");
+ finish();
+ }
+ }
+ });
+
+ }
+
+ private void startFeedDownload(String url) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Starting feed download");
+ url = URLChecker.prepareURL(url);
+ feed = new Feed(url, new Date());
+ String fileUrl = new File(getExternalCacheDir(),
+ FileNameGenerator.generateFileName(feed.getDownload_url()))
+ .toString();
+ feed.setFile_url(fileUrl);
+ final DownloadRequest request = new DownloadRequest(feed.getFile_url(),
+ feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED);
+ downloader = new HttpDownloader(
+ request);
+ new Thread() {
+ @Override
+ public void run() {
+ downloader.call();
+ onDownloadCompleted(downloader);
+ }
+ }.start();
+
+
+ }
+
+ /**
+ * Displays a progress indicator.
+ */
+ private void setLoadingLayout() {
+ RelativeLayout rl = new RelativeLayout(this);
+ RelativeLayout.LayoutParams rlLayoutParams = new RelativeLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT);
+
+ ProgressBar pb = new ProgressBar(this);
+ pb.setIndeterminate(true);
+ RelativeLayout.LayoutParams pbLayoutParams = new RelativeLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT);
+ pbLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
+ rl.addView(pb, pbLayoutParams);
+ addContentView(rl, rlLayoutParams);
+ }
+
+ private void parseFeed() {
+ if (feed == null || feed.getFile_url() == null) {
+ throw new IllegalStateException(
+ "feed must be non-null and downloaded when parseFeed is called");
+ }
+
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Parsing feed");
+
+ Thread thread = new Thread() {
+
+ @Override
+ public void run() {
+ String reasonDetailed = "";
+ boolean successful = false;
+ FeedHandler handler = new FeedHandler();
+ try {
+ handler.parseFeed(feed);
+ successful = true;
+ } catch (SAXException e) {
+ e.printStackTrace();
+ reasonDetailed = e.getMessage();
+ } catch (IOException e) {
+ e.printStackTrace();
+ reasonDetailed = e.getMessage();
+ } catch (ParserConfigurationException e) {
+ e.printStackTrace();
+ reasonDetailed = e.getMessage();
+ } catch (UnsupportedFeedtypeException e) {
+ e.printStackTrace();
+ reasonDetailed = e.getMessage();
+ } finally {
+ boolean rc = new File(feed.getFile_url()).delete();
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Deleted feed source file. Result: " + rc);
+ }
+
+ if (successful) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ showFeedInformation(feed);
+ }
+ });
+ } else {
+ final String errorMsg =
+ DownloadError.ERROR_PARSER_EXCEPTION.getErrorString(
+ OnlineFeedViewActivity.this)
+ + " (" + reasonDetailed + ")";
+ runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ showErrorDialog(errorMsg);
+ }
+ });
+ }
+ }
+ };
+ thread.start();
+ }
+
+ /**
+ * Called when feed parsed successfully
+ */
+ protected void showFeedInformation(Feed feed) {
+
+ }
+
+ private void showErrorDialog(String errorMsg) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.error_label);
+ if (errorMsg != null) {
+ builder.setMessage(getString(R.string.error_msg_prefix) + errorMsg);
+ } else {
+ builder.setMessage(R.string.error_msg_prefix);
+ }
+ builder.setNeutralButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+ builder.setOnCancelListener(new OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ setResult(RESULT_ERROR);
+ finish();
+ }
+ });
+ }
}
diff --git a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetActivity.java b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetActivity.java
new file mode 100644
index 000000000..08b37ae60
--- /dev/null
+++ b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetActivity.java
@@ -0,0 +1,44 @@
+package de.danoeh.antennapod.activity.gpoddernet;
+
+import android.app.SearchManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.SearchView;
+import android.view.Menu;
+import android.view.MenuItem;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.preferences.UserPreferences;
+
+/**
+ * Created by daniel on 23.08.13.
+ */
+public class GpodnetActivity extends ActionBarActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ setTheme(UserPreferences.getTheme());
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuItemCompat.setShowAsAction(menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label)
+ .setIcon(
+ obtainStyledAttributes(
+ new int[]{R.attr.action_search})
+ .getDrawable(0)),
+ MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ MenuItemCompat.setActionView(menu.findItem(R.id.search_item), new SearchView(this));
+
+ SearchManager searchManager =
+ (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+ SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.search_item));
+ searchView.setIconifiedByDefault(true);
+ searchView.setSearchableInfo(
+ searchManager.getSearchableInfo(getComponentName()));
+
+ return true;
+ }
+}
diff --git a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java
index 316ea2e88..d85ae4202 100644
--- a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java
+++ b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetMainActivity.java
@@ -1,25 +1,67 @@
package de.danoeh.antennapod.activity.gpoddernet;
import android.os.Bundle;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.ActionBarActivity;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+import android.support.v4.view.ViewPager;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.fragment.gpodnet.PodcastTopListFragment;
+import de.danoeh.antennapod.fragment.gpodnet.TagListFragment;
/**
* Created by daniel on 22.08.13.
*/
-public class GpodnetMainActivity extends ActionBarActivity {
+public class GpodnetMainActivity extends GpodnetActivity {
+ private static final String TAG = "GPodnetMainActivity";
+
+ private static final int POS_TAGS = 0;
+ private static final int POS_TOPLIST = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gpodnet_main);
- FragmentTransaction transaction = getSupportFragmentManager()
- .beginTransaction();
- PodcastTopListFragment topListFragment = new PodcastTopListFragment();
- transaction.replace(R.id.toplist_fragment, topListFragment);
- transaction.commit();
+ ViewPager viewpager = (ViewPager) findViewById(R.id.viewpager);
+ viewpager.setAdapter(new PagerAdapter(getSupportFragmentManager()));
+ }
+
+ private class PagerAdapter extends FragmentStatePagerAdapter {
+
+ private static final int NUM_PAGES = 2;
+
+ public PagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ @Override
+ public Fragment getItem(int i) {
+ switch (i) {
+ case POS_TAGS:
+ return new TagListFragment();
+ case POS_TOPLIST:
+ return new PodcastTopListFragment();
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ switch (position) {
+ case POS_TAGS:
+ return getString(R.string.gpodnet_taglist_header);
+ case POS_TOPLIST:
+ return getString(R.string.gpodnet_toplist_header);
+ default:
+ return super.getPageTitle(position);
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return NUM_PAGES;
+ }
}
}
diff --git a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetSearchActivity.java b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetSearchActivity.java
new file mode 100644
index 000000000..e0e3f822a
--- /dev/null
+++ b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetSearchActivity.java
@@ -0,0 +1,50 @@
+package de.danoeh.antennapod.activity.gpoddernet;
+
+import android.app.SearchManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.fragment.gpodnet.SearchListFragment;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Created by daniel on 23.08.13.
+ */
+public class GpodnetSearchActivity extends GpodnetActivity {
+
+ private SearchListFragment searchFragment;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.gpodnet_search);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Intent intent = getIntent();
+ if (StringUtils.equals(intent.getAction(), Intent.ACTION_SEARCH)) {
+ handleSearchRequest(intent.getStringExtra(SearchManager.QUERY));
+ }
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ setIntent(intent);
+ }
+
+ private void handleSearchRequest(String query) {
+ getSupportActionBar().setSubtitle(getString(R.string.search_term_label) + query);
+ if (searchFragment == null) {
+ FragmentTransaction transaction = getSupportFragmentManager()
+ .beginTransaction();
+ searchFragment = SearchListFragment.newInstance(query);
+ transaction.replace(R.id.searchListFragment, searchFragment);
+ transaction.commit();
+ } else {
+ searchFragment.changeQuery(query);
+ }
+ }
+}
diff --git a/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetTagActivity.java b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetTagActivity.java
new file mode 100644
index 000000000..aabd03685
--- /dev/null
+++ b/src/de/danoeh/antennapod/activity/gpoddernet/GpodnetTagActivity.java
@@ -0,0 +1,51 @@
+package de.danoeh.antennapod.activity.gpoddernet;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.fragment.gpodnet.PodcastListFragment;
+import de.danoeh.antennapod.fragment.gpodnet.SearchListFragment;
+import de.danoeh.antennapod.gpoddernet.GpodnetService;
+import de.danoeh.antennapod.gpoddernet.GpodnetServiceException;
+import de.danoeh.antennapod.gpoddernet.model.GpodnetPodcast;
+import de.danoeh.antennapod.gpoddernet.model.GpodnetTag;
+
+import java.util.List;
+
+/**
+ * Created by daniel on 23.08.13.
+ */
+public class GpodnetTagActivity extends GpodnetActivity{
+
+ private static final int PODCAST_COUNT = 50;
+ public static final String ARG_TAGNAME = "tagname";
+
+ private GpodnetTag tag;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.gpodnet_tag_activity);
+
+ if (!getIntent().hasExtra(ARG_TAGNAME)) {
+ throw new IllegalArgumentException("No tagname argument");
+ }
+ tag = new GpodnetTag(getIntent().getStringExtra(ARG_TAGNAME));
+ getSupportActionBar().setTitle(tag.getName());
+
+ FragmentTransaction transaction = getSupportFragmentManager()
+ .beginTransaction();
+ Fragment taglistFragment = new TaglistFragment();
+ transaction.replace(R.id.taglistFragment, taglistFragment);
+ transaction.commit();
+ }
+
+ private class TaglistFragment extends PodcastListFragment {
+
+ @Override
+ protected List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException {
+ return service.getPodcastsForTag(tag, PODCAST_COUNT);
+ }
+ }
+}
diff --git a/src/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/src/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
new file mode 100644
index 000000000..5fb204b26
--- /dev/null
+++ b/src/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java
@@ -0,0 +1,55 @@
+package de.danoeh.antennapod.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.feed.FeedItem;
+
+import java.util.List;
+
+/**
+ * Created by daniel on 24.08.13.
+ */
+public class FeedItemlistDescriptionAdapter extends ArrayAdapter<FeedItem> {
+
+ public FeedItemlistDescriptionAdapter(Context context, int resource, List<FeedItem> objects) {
+ super(context, resource, objects);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ Holder holder;
+
+ FeedItem item = getItem(position);
+
+ // Inflate layout
+ if (convertView == null) {
+ holder = new Holder();
+ LayoutInflater inflater = (LayoutInflater) getContext()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ convertView = inflater.inflate(R.layout.itemdescription_listitem, null);
+ holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
+ holder.description = (TextView) convertView.findViewById(R.id.txtvDescription);
+
+ convertView.setTag(holder);
+ } else {
+ holder = (Holder) convertView.getTag();
+ }
+
+ holder.title.setText(item.getTitle());
+ if (item.getDescription() != null) {
+ holder.description.setText(item.getDescription());
+ }
+
+ return convertView;
+ }
+
+ static class Holder {
+ TextView title;
+ TextView description;
+ }
+}
diff --git a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java
index e0675982f..0179260cc 100644
--- a/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java
+++ b/src/de/danoeh/antennapod/asynctask/ImageDiskCache.java
@@ -49,11 +49,16 @@ public class ImageDiskCache {
if (path == null) {
throw new NullPointerException();
}
+ if (cacheSingletons.containsKey(path)) {
+ return cacheSingletons.get(path);
+ }
+
ImageDiskCache cache = cacheSingletons.get(path);
if (cache == null) {
cache = new ImageDiskCache(path, maxCacheSize);
cacheSingletons.put(new File(path).getAbsolutePath(), cache);
}
+ cacheSingletons.put(path, cache);
return cache;
}
@@ -75,7 +80,7 @@ public class ImageDiskCache {
}
executor = Executors.newFixedThreadPool(Runtime.getRuntime()
- .availableProcessors());
+ .availableProcessors() * 2);
}
private synchronized void initCacheFolder() {
@@ -189,10 +194,11 @@ public class ImageDiskCache {
}
}
target.setTag(R.id.image_disk_cache_key, url);
+ target.setImageResource(R.color.default_image_color);
executor.submit(new ImageDownloader(url) {
@Override
protected void onImageLoaded(DiskCacheObject diskCacheObject) {
- if (target.getTag(R.id.image_disk_cache_key) == url) {
+ if (target.getTag(R.id.image_disk_cache_key).equals(url)) {
il.loadThumbnailBitmap(diskCacheObject.loadImage(), target, length);
}
}
@@ -215,10 +221,11 @@ public class ImageDiskCache {
}
}
target.setTag(R.id.image_disk_cache_key, url);
+ target.setImageResource(R.color.default_image_color);
executor.submit(new ImageDownloader(url) {
@Override
protected void onImageLoaded(DiskCacheObject diskCacheObject) {
- if (target.getTag(R.id.image_disk_cache_key) == url) {
+ if (target.getTag(R.id.image_disk_cache_key).equals(url)) {
il.loadCoverBitmap(diskCacheObject.loadImage(), target, length);
}
}
diff --git a/src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
index ba74d9d03..32e11e0ce 100644
--- a/src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
+++ b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastListFragment.java
@@ -1,9 +1,11 @@
package de.danoeh.antennapod.fragment.gpodnet;
import android.content.Context;
+import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -11,7 +13,10 @@ import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.TextView;
+import de.danoeh.antennapod.AppConfig;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.DefaultOnlineFeedViewActivity;
+import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
import de.danoeh.antennapod.adapter.gpodnet.PodcastListAdapter;
import de.danoeh.antennapod.gpoddernet.GpodnetService;
import de.danoeh.antennapod.gpoddernet.GpodnetServiceException;
@@ -49,11 +54,17 @@ public abstract class PodcastListFragment extends Fragment {
return root;
}
- protected abstract void onPodcastSelected(GpodnetPodcast selection);
+ protected void onPodcastSelected(GpodnetPodcast selection) {
+ if (AppConfig.DEBUG) Log.d(TAG, "Selected podcast: " + selection.toString());
+ Intent intent = new Intent(getActivity(), DefaultOnlineFeedViewActivity.class);
+ intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, selection.getUrl());
+ intent.putExtra(DefaultOnlineFeedViewActivity.ARG_TITLE, getString(R.string.gpodnet_main_label));
+ startActivity(intent);
+ }
protected abstract List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException;
- private void loadData() {
+ protected final void loadData() {
AsyncTask<Void, Void, List<GpodnetPodcast>> loaderTask = new AsyncTask<Void, Void, List<GpodnetPodcast>>() {
volatile Exception exception = null;
@@ -95,7 +106,7 @@ public abstract class PodcastListFragment extends Fragment {
@Override
protected void onPreExecute() {
super.onPreExecute();
- // gridView.setVisibility(View.GONE);
+ gridView.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}
};
diff --git a/src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java
index 4e7e42aa3..7007d0b9a 100644
--- a/src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java
+++ b/src/de/danoeh/antennapod/fragment/gpodnet/PodcastTopListFragment.java
@@ -16,11 +16,6 @@ public class PodcastTopListFragment extends PodcastListFragment {
private static final int PODCAST_COUNT = 50;
@Override
- protected void onPodcastSelected(GpodnetPodcast selection) {
- if (AppConfig.DEBUG) Log.d(TAG, "Selected: " + selection.getTitle());
- }
-
- @Override
protected List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException {
return service.getPodcastToplist(PODCAST_COUNT);
}
diff --git a/src/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java b/src/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
new file mode 100644
index 000000000..322d13097
--- /dev/null
+++ b/src/de/danoeh/antennapod/fragment/gpodnet/SearchListFragment.java
@@ -0,0 +1,48 @@
+package de.danoeh.antennapod.fragment.gpodnet;
+
+import android.os.Bundle;
+import de.danoeh.antennapod.gpoddernet.GpodnetService;
+import de.danoeh.antennapod.gpoddernet.GpodnetServiceException;
+import de.danoeh.antennapod.gpoddernet.model.GpodnetPodcast;
+
+import java.util.List;
+
+/**
+ * Created by daniel on 23.08.13.
+ */
+public class SearchListFragment extends PodcastListFragment {
+ private static final String ARG_QUERY = "query";
+
+ private String query;
+
+ public static SearchListFragment newInstance(String query) {
+ SearchListFragment fragment = new SearchListFragment();
+ Bundle args = new Bundle();
+ args.putString(ARG_QUERY, query);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null && getArguments().containsKey(ARG_QUERY)) {
+ this.query = getArguments().getString(ARG_QUERY);
+ } else {
+ this.query = "";
+ }
+ }
+
+ @Override
+ protected List<GpodnetPodcast> loadPodcastData(GpodnetService service) throws GpodnetServiceException {
+ return service.searchPodcasts(query, 0);
+ }
+
+ public void changeQuery(String query) {
+ if (query == null) {
+ throw new NullPointerException();
+ }
+ this.query = query;
+ loadData();
+ }
+}
diff --git a/src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java b/src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
new file mode 100644
index 000000000..3d63f2e58
--- /dev/null
+++ b/src/de/danoeh/antennapod/fragment/gpodnet/TagListFragment.java
@@ -0,0 +1,96 @@
+package de.danoeh.antennapod.fragment.gpodnet;
+
+import android.R;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+import de.danoeh.antennapod.activity.gpoddernet.GpodnetTagActivity;
+import de.danoeh.antennapod.gpoddernet.GpodnetService;
+import de.danoeh.antennapod.gpoddernet.GpodnetServiceException;
+import de.danoeh.antennapod.gpoddernet.model.GpodnetTag;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TagListFragment extends ListFragment {
+ private static final String TAG = "TagListFragment";
+ private static final int COUNT = 50;
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ setRetainInstance(true);
+
+ getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ String selectedTag = (String) getListAdapter().getItem(position);
+ Intent intent = new Intent(getActivity(), GpodnetTagActivity.class);
+ intent.putExtra(GpodnetTagActivity.ARG_TAGNAME, selectedTag);
+ startActivity(intent);
+ }
+ });
+
+ loadData();
+ }
+
+ private void loadData() {
+ AsyncTask<Void, Void, List<GpodnetTag>> task = new AsyncTask<Void, Void, List<GpodnetTag>>() {
+ private Exception exception;
+
+ @Override
+ protected List<GpodnetTag> doInBackground(Void... params) {
+ GpodnetService service = new GpodnetService();
+ try {
+ return service.getTopTags(COUNT);
+ } catch (GpodnetServiceException e) {
+ e.printStackTrace();
+ exception = e;
+ return null;
+ } finally {
+ service.shutdown();
+ }
+ }
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ setListShown(false);
+ }
+
+ @Override
+ protected void onPostExecute(List<GpodnetTag> gpodnetTags) {
+ super.onPostExecute(gpodnetTags);
+ final Context context = getActivity();
+ if (context != null) {
+ if (gpodnetTags != null) {
+ List<String> tagNames = new ArrayList<String>();
+ for (GpodnetTag tag : gpodnetTags) {
+ tagNames.add(tag.getName());
+ }
+ setListAdapter(new ArrayAdapter<String>(context, R.layout.simple_list_item_1, tagNames));
+ setListShown(true);
+ } else if (exception != null) {
+ TextView txtvError = new TextView(getActivity());
+ txtvError.setText(exception.getMessage());
+ getListView().setEmptyView(txtvError);
+ } else {
+ setListShown(true);
+ }
+ }
+ }
+ };
+ if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
+ task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ } else {
+ task.execute();
+ }
+ }
+}
+