summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Oeh <daniel@daniel-pc.(none)>2011-12-23 19:22:06 +0100
committerDaniel Oeh <daniel@daniel-pc.(none)>2011-12-23 19:22:06 +0100
commitc9283f09dced6f156e13675ef4c13ebeb20cb9e5 (patch)
tree833961a4fd03b94086223dba9f658cb2841cbe77
downloadAntennaPod-c9283f09dced6f156e13675ef4c13ebeb20cb9e5.zip
Initial Commit
-rw-r--r--.gitignore19
-rw-r--r--AndroidManifest.xml27
-rw-r--r--build.xml85
-rw-r--r--proguard.cfg40
-rw-r--r--project.properties11
-rw-r--r--res/drawable-hdpi/ic_launcher.pngbin0 -> 4147 bytes
-rw-r--r--res/drawable-ldpi/ic_launcher.pngbin0 -> 1723 bytes
-rw-r--r--res/drawable-mdpi/ic_launcher.pngbin0 -> 2574 bytes
-rw-r--r--res/layout/feedlist_item.xml34
-rw-r--r--res/layout/main.xml16
-rw-r--r--res/values/strings.xml7
-rw-r--r--src/de/podfetcher/PodcastApp.java25
-rw-r--r--src/de/podfetcher/PodfetcherActivity.java41
-rw-r--r--src/de/podfetcher/feed/Feed.java45
-rw-r--r--src/de/podfetcher/feed/FeedCategory.java12
-rw-r--r--src/de/podfetcher/feed/FeedComponent.java16
-rw-r--r--src/de/podfetcher/feed/FeedFile.java7
-rw-r--r--src/de/podfetcher/feed/FeedHandler.java41
-rw-r--r--src/de/podfetcher/feed/FeedImage.java26
-rw-r--r--src/de/podfetcher/feed/FeedItem.java33
-rw-r--r--src/de/podfetcher/feed/FeedManager.java116
-rw-r--r--src/de/podfetcher/feed/FeedMedia.java33
-rw-r--r--src/de/podfetcher/feed/RSSHandler.java116
-rw-r--r--src/de/podfetcher/gui/AddFeedActivity.java15
-rw-r--r--src/de/podfetcher/gui/FeedlistAdapter.java57
-rw-r--r--src/de/podfetcher/storage/DownloadReceiver.java27
-rw-r--r--src/de/podfetcher/storage/DownloadRequester.java131
-rw-r--r--src/de/podfetcher/storage/PodDBAdapter.java295
28 files changed, 1275 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..d0fa551e5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+# built application files
+*.apk
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Backup files
+*~
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 000000000..2de7577b8
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="de.podfetcher"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <!-- <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS" /> -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <uses-sdk android:minSdkVersion="10" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <activity
+ android:label="@string/app_name"
+ android:name=".PodfetcherActivity" >
+ <intent-filter >
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/build.xml b/build.xml
new file mode 100644
index 000000000..d392d5e74
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Podfetcher" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
+ unless="sdk.dir"
+ />
+
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+ in between standard targets -->
+<!--
+ <target name="-pre-build">
+ </target>
+ <target name="-pre-compile">
+ </target>
+
+ /* This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir} */
+ <target name="-post-compile">
+ </target>
+-->
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/proguard.cfg b/proguard.cfg
new file mode 100644
index 000000000..b1cdf17b5
--- /dev/null
+++ b/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
diff --git a/project.properties b/project.properties
new file mode 100644
index 000000000..f049142c1
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-10
diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 000000000..8074c4c57
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-ldpi/ic_launcher.png b/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 000000000..1095584ec
--- /dev/null
+++ b/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 000000000..a07c69fa5
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/res/layout/feedlist_item.xml b/res/layout/feedlist_item.xml
new file mode 100644
index 000000000..f204d1807
--- /dev/null
+++ b/res/layout/feedlist_item.xml
@@ -0,0 +1,34 @@
+<?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/imgvFeedimage"
+ android:layout_height="fill_parent"
+ android:layout_width="50dip"
+ android:padding="10dip"
+ android:cropToPadding="true"
+ android:layout_alignParentLeft="true"
+ />
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="fill_parent"
+ android:layout_width="wrap_content"
+ android:layout_alignParentRight="true">
+ <TextView
+ android:id="@+id/txtvFeedname"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ <TextView
+ android:id="@+id/txtvNewEpisodes"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+
+ />
+
+
+ </LinearLayout>
+
+
+
+</RelativeLayout> \ No newline at end of file
diff --git a/res/layout/main.xml b/res/layout/main.xml
new file mode 100644
index 000000000..45ed9b9b5
--- /dev/null
+++ b/res/layout/main.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+ <EditText
+ android:id="@+id/textedit"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <Button
+ android:id="@+id/testbutton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Test2" />
+
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 000000000..fcd5d2837
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="hello">Hello World, PodfetcherActivity!</string>
+ <string name="app_name">Podfetcher</string>
+
+</resources> \ No newline at end of file
diff --git a/src/de/podfetcher/PodcastApp.java b/src/de/podfetcher/PodcastApp.java
new file mode 100644
index 000000000..59c68f6b8
--- /dev/null
+++ b/src/de/podfetcher/PodcastApp.java
@@ -0,0 +1,25 @@
+package de.podfetcher;
+
+import de.podfetcher.feed.FeedManager;
+import android.app.Application;
+
+public class PodcastApp extends Application {
+
+ private static PodcastApp singleton;
+
+ public static PodcastApp getInstance() {
+ return singleton;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ singleton = this;
+
+ FeedManager manager = FeedManager.getInstance();
+ manager.loadDBData(getApplicationContext());
+ }
+
+
+
+}
diff --git a/src/de/podfetcher/PodfetcherActivity.java b/src/de/podfetcher/PodfetcherActivity.java
new file mode 100644
index 000000000..9cb4f9cfc
--- /dev/null
+++ b/src/de/podfetcher/PodfetcherActivity.java
@@ -0,0 +1,41 @@
+package de.podfetcher;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.xml.sax.SAXException;
+
+import de.podfetcher.feed.*;
+import de.podfetcher.storage.DownloadRequester;
+import android.app.Activity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.os.Bundle;
+
+public class PodfetcherActivity extends Activity {
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ final DownloadRequester requester = DownloadRequester.getInstance();
+ final FeedHandler handler = new FeedHandler();
+ final FeedManager manager = FeedManager.getInstance();
+
+ final Button button = (Button)findViewById(R.id.testbutton);
+ final EditText edittext = (EditText)findViewById(R.id.textedit);
+
+
+
+ button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ final String s = edittext.getText().toString();
+ manager.addFeed(v.getContext(), s);
+ edittext.setText("Receiving...");
+
+ }
+ });
+
+ }
+}
diff --git a/src/de/podfetcher/feed/Feed.java b/src/de/podfetcher/feed/Feed.java
new file mode 100644
index 000000000..823c8f198
--- /dev/null
+++ b/src/de/podfetcher/feed/Feed.java
@@ -0,0 +1,45 @@
+package de.podfetcher.feed;
+
+import java.util.ArrayList;
+
+
+
+
+/**
+ * Data Object for a whole feed
+ * @author daniel
+ *
+ */
+public class Feed extends FeedFile{
+ public String title;
+ public String link;
+ public String description;
+ public FeedImage image;
+ public FeedCategory category;
+ public ArrayList<FeedItem> items;
+
+
+ public Feed() {
+ items = new ArrayList<FeedItem>();
+ }
+
+ public Feed(String url) {
+ this.download_url = url;
+ }
+
+ public Feed(String title, String link, String description, String download_url,
+ FeedCategory category) {
+ super();
+ this.title = title;
+ this.link = link;
+ this.description = description;
+ this.download_url = download_url;
+ this.category = category;
+ items = new ArrayList<FeedItem>();
+ }
+
+
+
+
+
+}
diff --git a/src/de/podfetcher/feed/FeedCategory.java b/src/de/podfetcher/feed/FeedCategory.java
new file mode 100644
index 000000000..d5fd028ab
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedCategory.java
@@ -0,0 +1,12 @@
+package de.podfetcher.feed;
+
+public class FeedCategory extends FeedComponent{
+ public String name;
+
+ public FeedCategory(String name) {
+ super();
+ this.name = name;
+ }
+
+
+}
diff --git a/src/de/podfetcher/feed/FeedComponent.java b/src/de/podfetcher/feed/FeedComponent.java
new file mode 100644
index 000000000..4c787c55a
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedComponent.java
@@ -0,0 +1,16 @@
+package de.podfetcher.feed;
+
+/**
+ * Represents every possible component of a feed
+ * @author daniel
+ *
+ */
+public class FeedComponent {
+
+ public long id;
+
+ public FeedComponent() {
+ super();
+ }
+
+} \ No newline at end of file
diff --git a/src/de/podfetcher/feed/FeedFile.java b/src/de/podfetcher/feed/FeedFile.java
new file mode 100644
index 000000000..8335166b0
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedFile.java
@@ -0,0 +1,7 @@
+package de.podfetcher.feed;
+
+public abstract class FeedFile extends FeedComponent {
+ public String file_url;
+ public String download_url;
+
+}
diff --git a/src/de/podfetcher/feed/FeedHandler.java b/src/de/podfetcher/feed/FeedHandler.java
new file mode 100644
index 000000000..304799c7a
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedHandler.java
@@ -0,0 +1,41 @@
+package de.podfetcher.feed;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+
+public class FeedHandler {
+ public final static String CHANNEL = "channel";
+ public final static String ITEM = "item";
+ public final static String TITLE = "title";
+ public final static String LINK = "link";
+ public final static String DESCR = "description";
+ public final static String PUBDATE = "pubDate";
+ public final static String ENCLOSURE = "enclosure";
+ public final static String IMAGE = "image";
+ public final static String URL = "url";
+
+ public final static String ENC_URL = "url";
+ public final static String ENC_LEN = "length";
+ public final static String ENC_TYPE = "type";
+
+ public Feed parseFeed(String file) throws ParserConfigurationException, SAXException {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ SAXParser saxParser = factory.newSAXParser();
+ RSSHandler handler = new RSSHandler();
+ try {
+ saxParser.parse(new File(file), handler);
+ } catch (SAXException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return handler.feed;
+ }
+}
diff --git a/src/de/podfetcher/feed/FeedImage.java b/src/de/podfetcher/feed/FeedImage.java
new file mode 100644
index 000000000..f62f13267
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedImage.java
@@ -0,0 +1,26 @@
+package de.podfetcher.feed;
+
+public class FeedImage extends FeedFile {
+ public String title;
+
+ public FeedImage(String download_url, String title) {
+ super();
+ this.download_url = download_url;
+ this.title = title;
+ }
+
+ public FeedImage(long id, String title, String file_url, String download_url) {
+ this.id = id;
+ this.title = title;
+ this.file_url = file_url;
+ this.download_url = download_url;
+ }
+
+ public FeedImage() {
+
+ }
+
+
+
+
+}
diff --git a/src/de/podfetcher/feed/FeedItem.java b/src/de/podfetcher/feed/FeedItem.java
new file mode 100644
index 000000000..09bd8f3e1
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedItem.java
@@ -0,0 +1,33 @@
+package de.podfetcher.feed;
+
+
+/**
+ * Data Object for a XML message
+ * @author daniel
+ *
+ */
+public class FeedItem extends FeedComponent{
+ public String title;
+ public String description;
+ public String link;
+ public String pubDate;
+ public FeedMedia media;
+ public Feed feed;
+ public boolean read;
+
+ public FeedItem() {
+ this.read = false;
+ }
+
+ public FeedItem(String title, String description, String link,
+ String pubDate, FeedMedia media, Feed feed) {
+ super();
+ this.title = title;
+ this.description = description;
+ this.link = link;
+ this.pubDate = pubDate;
+ this.media = media;
+ this.feed = feed;
+ this.read = false;
+ }
+}
diff --git a/src/de/podfetcher/feed/FeedManager.java b/src/de/podfetcher/feed/FeedManager.java
new file mode 100644
index 000000000..fde532694
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedManager.java
@@ -0,0 +1,116 @@
+package de.podfetcher.feed;
+
+import java.util.ArrayList;
+
+
+import de.podfetcher.storage.*;
+import android.content.Context;
+import android.database.Cursor;
+
+
+/**
+ * Singleton class
+ * Manages all feeds, categories and feeditems
+ *
+ *
+ * */
+public class FeedManager {
+
+ private static FeedManager singleton;
+
+ public ArrayList<Feed> feeds;
+ public ArrayList<FeedCategory> categories;
+
+ Cursor feedlistCursor;
+
+
+ private FeedManager() {
+ feeds = new ArrayList<Feed>();
+ categories = new ArrayList<FeedCategory>();
+
+ }
+
+ public static FeedManager getInstance(){
+ if(singleton == null) {
+ singleton = new FeedManager();
+ }
+ return singleton;
+ }
+
+ /** Add and Download a new Feed */
+ public void addFeed(Context context, String url) {
+ // TODO Check if URL is correct
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ Feed feed = new Feed(url);
+ feed.id = adapter.setFeed(feed);
+
+ DownloadRequester req = DownloadRequester.getInstance();
+ req.downloadFeed(context, feed);
+
+ }
+
+ /** Reads the database */
+ public void loadDBData(Context context) {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ feedlistCursor = adapter.getAllFeedsCursor();
+ updateArrays(context);
+ }
+
+
+ public void updateArrays(Context context) {
+ feedlistCursor.requery();
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ feeds.clear();
+ categories.clear();
+ extractFeedlistFromCursor(context);
+ }
+
+ private void extractFeedlistFromCursor(Context context) {
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ if(feedlistCursor.moveToFirst()) {
+ do {
+ Feed feed = new Feed();
+
+ feed.id = feedlistCursor.getLong(feedlistCursor.getColumnIndex(PodDBAdapter.KEY_ID));
+ feed.title = feedlistCursor.getString(feedlistCursor.getColumnIndex(PodDBAdapter.KEY_TITLE));
+ feed.link = feedlistCursor.getString(feedlistCursor.getColumnIndex(PodDBAdapter.KEY_LINK));
+ feed.description = feedlistCursor.getString(feedlistCursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION));
+ feed.image = adapter.getFeedImage(feed);
+ feed.file_url = feedlistCursor.getString(feedlistCursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL));
+ feed.download_url = feedlistCursor.getString(feedlistCursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL));
+
+ // Get FeedItem-Object
+ Cursor itemlistCursor = adapter.getAllItemsOfFeedCursor(feed);
+ feed.items = extractFeedItemsFromCursor(context, itemlistCursor);
+
+ feeds.add(feed);
+ }while(feedlistCursor.moveToNext());
+ }
+ }
+
+ private ArrayList<FeedItem> extractFeedItemsFromCursor(Context context, Cursor itemlistCursor) {
+ ArrayList<FeedItem> items = new ArrayList<FeedItem>();
+ PodDBAdapter adapter = new PodDBAdapter(context);
+
+ if(itemlistCursor.moveToFirst()) {
+ do {
+ FeedItem item = new FeedItem();
+
+ item.id = itemlistCursor.getLong(itemlistCursor.getColumnIndex(PodDBAdapter.KEY_ID));
+ item.title = itemlistCursor.getString(itemlistCursor.getColumnIndex(PodDBAdapter.KEY_TITLE));
+ item.link = itemlistCursor.getString(itemlistCursor.getColumnIndex(PodDBAdapter.KEY_LINK));
+ item.description = itemlistCursor.getString(itemlistCursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION));
+ item.pubDate = itemlistCursor.getString(itemlistCursor.getColumnIndex(PodDBAdapter.KEY_PUBDATE));
+ item.media = adapter.getFeedMedia(itemlistCursor.getLong(itemlistCursor.getColumnIndex(PodDBAdapter.KEY_MEDIA)));
+ item.read = (itemlistCursor.getInt(itemlistCursor.getColumnIndex(PodDBAdapter.KEY_READ)) > 0) ? true : false;
+
+ items.add(item);
+ } while(itemlistCursor.moveToNext());
+ }
+ return items;
+ }
+
+
+
+
+}
diff --git a/src/de/podfetcher/feed/FeedMedia.java b/src/de/podfetcher/feed/FeedMedia.java
new file mode 100644
index 000000000..e5945785d
--- /dev/null
+++ b/src/de/podfetcher/feed/FeedMedia.java
@@ -0,0 +1,33 @@
+package de.podfetcher.feed;
+
+public class FeedMedia extends FeedFile{
+ public long length;
+ public long position;
+ public long size; // File size in Byte
+ public String mime_type;
+
+ public FeedItem item; // TODO remove
+
+ public FeedMedia(FeedItem i, String download_url, long size, String mime_type) {
+ this.item = i;
+ this.download_url = download_url;
+ this.size = size;
+ this.mime_type = mime_type;
+ }
+
+ public FeedMedia(long id, long length, long position, long size, String mime_type,
+ String file_url, String download_url) {
+ super();
+ this.id = id;
+ this.length = length;
+ this.position = position;
+ this.size = size;
+ this.mime_type = mime_type;
+ this.file_url = file_url;
+ this.download_url = download_url;
+ }
+
+
+
+
+}
diff --git a/src/de/podfetcher/feed/RSSHandler.java b/src/de/podfetcher/feed/RSSHandler.java
new file mode 100644
index 000000000..1176107b9
--- /dev/null
+++ b/src/de/podfetcher/feed/RSSHandler.java
@@ -0,0 +1,116 @@
+package de.podfetcher.feed;
+
+import java.util.ArrayList;
+import de.podfetcher.feed.FeedHandler;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * SAX-Parser for reading RSS-Feeds
+ *
+ * @author daniel
+ *
+ */
+public class RSSHandler extends DefaultHandler {
+ public ArrayList<FeedItem> items;
+ public FeedItem currentItem;
+ public StringBuilder strBuilder;
+ public Feed feed;
+ public String active_root_element; // channel or item or image
+ public String active_sub_element; // Not channel or item
+
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ if (active_sub_element != null) {
+ strBuilder.append(ch, start, length);
+ }
+ }
+
+ @Override
+ public void endDocument() throws SAXException {
+ feed.items = items;
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if (qName.equalsIgnoreCase(FeedHandler.ITEM)) {
+ currentItem.feed = feed;
+ items.add(currentItem);
+ } else if (qName.equalsIgnoreCase(FeedHandler.TITLE)) {
+ if (active_root_element.equalsIgnoreCase(FeedHandler.CHANNEL)) {
+ feed.title = strBuilder.toString();
+ } else if(active_root_element.equalsIgnoreCase(FeedHandler.TITLE)) {
+ currentItem.title = strBuilder.toString();
+ } else if(active_root_element.equalsIgnoreCase(FeedHandler.IMAGE)) {
+ feed.image.title = strBuilder.toString();
+ }
+ } else if (qName.equalsIgnoreCase(FeedHandler.DESCR)) {
+ if (active_root_element.equalsIgnoreCase(FeedHandler.CHANNEL)) {
+ feed.description = strBuilder.toString();
+ } else {
+ currentItem.description = strBuilder.toString();
+ }
+ } else if (qName.equalsIgnoreCase(FeedHandler.LINK)) {
+ if (active_root_element.equalsIgnoreCase(FeedHandler.CHANNEL)) {
+ feed.link = strBuilder.toString();
+ } else if(active_root_element.equalsIgnoreCase(FeedHandler.TITLE)){
+ currentItem.link = strBuilder.toString();
+ }
+ } else if (qName.equalsIgnoreCase(FeedHandler.PUBDATE)) {
+ if (active_root_element.equalsIgnoreCase(FeedHandler.ITEM)) {
+ currentItem.pubDate = strBuilder.toString();
+ }
+ } else if (qName.equalsIgnoreCase(FeedHandler.URL)) {
+ if(active_root_element.equalsIgnoreCase(FeedHandler.IMAGE)) {
+ feed.image.download_url = strBuilder.toString();
+ }
+ } else if(qName.equalsIgnoreCase(FeedHandler.IMAGE)) {
+ active_root_element = FeedHandler.CHANNEL;
+ }
+ active_sub_element = null;
+ strBuilder = new StringBuilder();
+ }
+
+ @Override
+ public void startDocument() throws SAXException {
+ items = new ArrayList<FeedItem>();
+ strBuilder = new StringBuilder();
+
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+ if (qName.equalsIgnoreCase(FeedHandler.CHANNEL)) {
+ feed = new Feed();
+ active_root_element = qName;
+ } else if (qName.equalsIgnoreCase(FeedHandler.ITEM)) {
+ currentItem = new FeedItem();
+ active_root_element = qName;
+ } else if (qName.equalsIgnoreCase(FeedHandler.TITLE)) {
+ active_sub_element = qName;
+ } else if (qName.equalsIgnoreCase(FeedHandler.DESCR)) {
+ active_sub_element = qName;
+ } else if (qName.equalsIgnoreCase(FeedHandler.LINK)) {
+ active_sub_element = qName;
+ } else if (qName.equalsIgnoreCase(FeedHandler.PUBDATE)) {
+ active_sub_element = qName;
+ } else if (qName.equalsIgnoreCase(FeedHandler.ENCLOSURE)) {
+ currentItem.media = new FeedMedia(currentItem,
+ attributes.getValue(FeedHandler.ENC_URL),
+ Long.parseLong(attributes.getValue(FeedHandler.ENC_LEN)),
+ attributes.getValue(FeedHandler.ENC_TYPE));
+ } else if(qName.equalsIgnoreCase(FeedHandler.IMAGE)) {
+ feed.image = new FeedImage();
+ active_root_element = qName;
+ } else if(qName.equalsIgnoreCase(FeedHandler.URL)) {
+ active_sub_element = qName;
+ }
+
+ }
+
+}
diff --git a/src/de/podfetcher/gui/AddFeedActivity.java b/src/de/podfetcher/gui/AddFeedActivity.java
new file mode 100644
index 000000000..a15d64658
--- /dev/null
+++ b/src/de/podfetcher/gui/AddFeedActivity.java
@@ -0,0 +1,15 @@
+package de.podfetcher.gui;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class AddFeedActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ }
+
+
+}
diff --git a/src/de/podfetcher/gui/FeedlistAdapter.java b/src/de/podfetcher/gui/FeedlistAdapter.java
new file mode 100644
index 000000000..ac46874e5
--- /dev/null
+++ b/src/de/podfetcher/gui/FeedlistAdapter.java
@@ -0,0 +1,57 @@
+package de.podfetcher.gui;
+
+import java.io.File;
+import java.util.List;
+
+import de.podfetcher.R;
+import de.podfetcher.feed.Feed;
+import android.content.Context;
+import android.net.Uri;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+
+public class FeedlistAdapter extends ArrayAdapter<Feed> {
+
+ int resource;
+
+ public FeedlistAdapter(Context context, int resource,
+ int textViewResourceId, List<Feed> objects) {
+ super(context, resource, textViewResourceId, objects);
+ this.resource = resource;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LinearLayout feedlistView;
+
+
+ Feed feed = getItem(position);
+ // Inflate Layout
+ if (convertView == null) {
+ feedlistView = new LinearLayout(getContext());
+ String inflater = Context.LAYOUT_INFLATER_SERVICE;
+ LayoutInflater vi = (LayoutInflater)getContext().getSystemService(inflater);
+ vi.inflate(resource, feedlistView, true);
+ } else {
+ feedlistView = (LinearLayout) convertView;
+ }
+
+ ImageView imageView = (ImageView)feedlistView.findViewById(R.id.imgvFeedimage);
+ TextView txtvFeedname = (TextView)feedlistView.findViewById(R.id.txtvFeedname);
+ TextView txtvNewEpisodes = (TextView)feedlistView.findViewById(R.id.txtvNewEpisodes);
+
+ imageView.setImageURI(Uri.fromFile(new File(feed.file_url))); // TODO select default picture when no image downloaded
+ txtvFeedname.setText(feed.title);
+ // TODO find new Episodes txtvNewEpisodes.setText(feed)
+ return feedlistView;
+ }
+
+
+
+}
diff --git a/src/de/podfetcher/storage/DownloadReceiver.java b/src/de/podfetcher/storage/DownloadReceiver.java
new file mode 100644
index 000000000..1d06b51f7
--- /dev/null
+++ b/src/de/podfetcher/storage/DownloadReceiver.java
@@ -0,0 +1,27 @@
+package de.podfetcher.storage;
+
+import de.podfetcher.PodcastApp;
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class DownloadReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
+ DownloadRequester requester = DownloadRequester.getInstance();
+ Intent item_intent = requester.getItemIntent(id);
+ String action = item_intent.getAction();
+ if(action.equals(DownloadRequester.ACTION_FEED_DOWNLOAD_COMPLETED)) {
+ requester.removeFeedByID(item_intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
+ } else if(action.equals(DownloadRequester.ACTION_MEDIA_DOWNLOAD_COMPLETED)) {
+ requester.removeMediaByID(item_intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
+ } else if(action.equals(DownloadRequester.ACTION_IMAGE_DOWNLOAD_COMPLETED)) {
+ requester.removeImageByID(item_intent.getLongExtra(DownloadRequester.EXTRA_ITEM_ID, -1));
+ }
+ PodcastApp.getInstance().getApplicationContext().sendBroadcast(item_intent);
+ }
+
+}
diff --git a/src/de/podfetcher/storage/DownloadRequester.java b/src/de/podfetcher/storage/DownloadRequester.java
new file mode 100644
index 000000000..6161e7ac3
--- /dev/null
+++ b/src/de/podfetcher/storage/DownloadRequester.java
@@ -0,0 +1,131 @@
+package de.podfetcher.storage;
+
+import java.util.ArrayList;
+import java.io.File;
+
+import de.podfetcher.feed.Feed;
+import de.podfetcher.feed.FeedImage;
+import de.podfetcher.feed.FeedMedia;
+
+import android.app.DownloadManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+
+public class DownloadRequester {
+ public static String EXTRA_DOWNLOAD_ID = "extra.de.podfetcher.storage.download_id";
+ public static String EXTRA_ITEM_ID = "extra.de.podfetcher.storage.item_id";
+
+ public static String ACTION_FEED_DOWNLOAD_COMPLETED = "action.de.podfetcher.storage.feed_download_completed";
+ public static String ACTION_MEDIA_DOWNLOAD_COMPLETED = "action.de.podfetcher.storage.media_download_completed";
+ public static String ACTION_IMAGE_DOWNLOAD_COMPLETED = "action.de.podfetcher.storage.image_download_completed";
+
+ private static boolean STORE_ON_SD = true;
+ public static String IMAGE_DOWNLOADPATH = "images";
+ public static String FEED_DOWNLOADPATH = "cache";
+ public static String MEDIA_DOWNLOADPATH = "media";
+
+
+ private static DownloadRequester downloader;
+
+ public ArrayList<Intent> feeds;
+ public ArrayList<Intent> images;
+ public ArrayList<Intent> media;
+
+ private DownloadRequester(){
+ feeds = new ArrayList<Intent>();
+ images = new ArrayList<Intent>();
+ media = new ArrayList<Intent>();
+
+ }
+
+ public static DownloadRequester getInstance() {
+ if(downloader == null) {
+ downloader = new DownloadRequester();
+ }
+ return downloader;
+ }
+
+ private void download(Context context, ArrayList<Intent> type, String str_uri, File dest, boolean visibleInUI, String action, long id) {
+ DownloadManager.Request request = new DownloadManager.Request(Uri.parse(str_uri));
+ //request.allowScanningByMediaScanner();
+
+ request.setDestinationUri(Uri.fromFile(dest));
+ request.setVisibleInDownloadsUi(visibleInUI);
+ // TODO Set Allowed Network Types
+ DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
+ Intent i = new Intent(action);
+ i.putExtra(EXTRA_DOWNLOAD_ID, manager.enqueue(request));
+ i.putExtra(EXTRA_ITEM_ID, id);
+ type.add(i);
+
+ }
+ public void downloadFeed(Context context, Feed feed) {
+ download(context, feeds, feed.download_url,
+ new File(context.getExternalFilesDir(FEED_DOWNLOADPATH), "feed-" + feed.id),
+ true, ACTION_FEED_DOWNLOAD_COMPLETED, feed.id);
+ }
+
+ public void downloadImage(Context context, FeedImage image) {
+ download(context, images, image.download_url,
+ new File(context.getExternalFilesDir(IMAGE_DOWNLOADPATH), "image-" + image.id),
+ true, ACTION_IMAGE_DOWNLOAD_COMPLETED, image.id);
+ }
+
+ public void downloadMedia(Context context, FeedMedia feedmedia) {
+ download(context, media, feedmedia.download_url,
+ new File(context.getExternalFilesDir(MEDIA_DOWNLOADPATH), "media-" + feedmedia.id),
+ true, ACTION_MEDIA_DOWNLOAD_COMPLETED, feedmedia.id);
+ }
+
+ public void removeFeedByID(long id) {
+ int len = feeds.size();
+ for(int x = 0; x < len; x++) {
+ if(feeds.get(x).getLongExtra(EXTRA_ITEM_ID, -1) == id) {
+ feeds.remove(x);
+ break;
+ }
+ }
+ }
+
+ public void removeMediaByID(long id) {
+ int len = media.size();
+ for(int x = 0; x < len; x++) {
+ if(media.get(x).getLongExtra(EXTRA_ITEM_ID, -1) == id) {
+ media.remove(x);
+ break;
+ }
+ }
+ }
+
+ public void removeImageByID(long id) {
+ int len = images.size();
+ for(int x = 0; x < len; x++) {
+ if(images.get(x).getLongExtra(EXTRA_ITEM_ID, -1) == id) {
+ images.remove(x);
+ break;
+ }
+ }
+ }
+
+ /* Returns the stored intent by looking for the right download id */
+ public Intent getItemIntent(long id) {
+ for(Intent i : feeds) {
+ if(i.getLongExtra(EXTRA_DOWNLOAD_ID, -1) == id) {
+ return i;
+ }
+ }
+ for(Intent i : media) {
+ if(i.getLongExtra(EXTRA_DOWNLOAD_ID, -1) == id) {
+ return i;
+ }
+ }
+ for(Intent i : images) {
+ if(i.getLongExtra(EXTRA_DOWNLOAD_ID, -1) == id) {
+ return i;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/de/podfetcher/storage/PodDBAdapter.java b/src/de/podfetcher/storage/PodDBAdapter.java
new file mode 100644
index 000000000..e9df7607e
--- /dev/null
+++ b/src/de/podfetcher/storage/PodDBAdapter.java
@@ -0,0 +1,295 @@
+package de.podfetcher.storage;
+
+import de.podfetcher.feed.Feed;
+import de.podfetcher.feed.FeedCategory;
+import de.podfetcher.feed.FeedImage;
+import de.podfetcher.feed.FeedItem;
+import de.podfetcher.feed.FeedMedia;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+/**
+ * Implements methods for accessing the database
+ * */
+public class PodDBAdapter {
+
+ private static final int DATABASE_VERSION = 1;
+ private static final String DATABASE_NAME = "Podfetcher.db";
+
+ // Key-constants
+ public static final String KEY_ID = "id";
+ public static final String KEY_TITLE = "title";
+ public static final String KEY_NAME = "name";
+ public static final String KEY_LINK = "link";
+ public static final String KEY_DESCRIPTION = "description";
+ public static final String KEY_FILE_URL = "file_url";
+ public static final String KEY_DOWNLOAD_URL = "download_url";
+ public static final String KEY_PUBDATE = "pubDate";
+ public static final String KEY_READ = "read";
+ public static final String KEY_LENGTH = "length";
+ public static final String KEY_POSITION = "position";
+ public static final String KEY_SIZE = "filesize";
+ public static final String KEY_MIME_TYPE = "mime_type";
+ public static final String KEY_IMAGE = "image";
+ public static final String KEY_CATEGORY = "category";
+ public static final String KEY_FEED = "feed";
+ public static final String KEY_MEDIA = "media";
+
+ // Table names
+ public static final String TABLE_NAME_FEEDS = "Feeds";
+ public static final String TABLE_NAME_FEED_ITEMS = "FeedItems";
+ public static final String TABLE_NAME_FEED_CATEGORIES = "FeedCategories";
+ public static final String TABLE_NAME_FEED_IMAGES = "FeedImages";
+ public static final String TABLE_NAME_FEED_MEDIA = "FeedMedia";
+
+ // SQL Statements for creating new tables
+ private static final String TABLE_PRIMARY_KEY = KEY_ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT ,";
+ private static final String CREATE_TABLE_FEEDS = "CREATE TABLE "
+ + TABLE_NAME_FEEDS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE
+ + " TEXT," + KEY_LINK + " TEXT," + KEY_DESCRIPTION
+ + " TEXT," + KEY_IMAGE + " INTEGER," + KEY_CATEGORY
+ + " INTEGER," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL
+ + " TEXT)";
+
+ private static final String CREATE_TABLE_FEED_ITEMS = "CREATE TABLE "
+ + TABLE_NAME_FEED_ITEMS + " (" + TABLE_PRIMARY_KEY + KEY_TITLE
+ + " TEXT," + KEY_LINK + " TEXT," + KEY_DESCRIPTION
+ + " TEXT," + KEY_PUBDATE + " TEXT," + KEY_MEDIA
+ + " INTEGER," + KEY_FEED + " INTEGER," + KEY_READ
+ + " INTEGER)";
+
+ private static final String CREATE_TABLE_FEED_CATEGORIES = "CREATE TABLE "
+ + TABLE_NAME_FEED_CATEGORIES + " (" + TABLE_PRIMARY_KEY + KEY_NAME
+ + " TEXT)";
+
+ private static final String CREATE_TABLE_FEED_IMAGES = "CREATE TABLE "
+ + TABLE_NAME_FEED_IMAGES + " (" + TABLE_PRIMARY_KEY + KEY_TITLE
+ + " TEXT," + KEY_FILE_URL + " TEXT,"
+ + KEY_DOWNLOAD_URL + " TEXT)";
+
+ private static final String CREATE_TABLE_FEED_MEDIA = "CREATE TABLE "
+ + TABLE_NAME_FEED_MEDIA + " (" + TABLE_PRIMARY_KEY + KEY_LENGTH
+ + " INTEGER," + KEY_POSITION + " INTEGER,"
+ + KEY_SIZE + " INTEGER," + KEY_MIME_TYPE + " TEXT,"
+ + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT)";
+
+ private SQLiteDatabase db;
+ private final Context context;
+ private PodDBHelper helper;
+
+ public PodDBAdapter(Context c) {
+ this.context = c;
+ helper = new PodDBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ public PodDBAdapter open() {
+ try {
+ db = helper.getWritableDatabase();
+ } catch (SQLException ex) {
+ db = helper.getReadableDatabase();
+ }
+ return this;
+ }
+
+ public void close() {
+ db.close();
+ }
+
+ /** Inserts or updates a feed entry
+ * @return the id of the entry
+ * */
+ public long setFeed(Feed feed) {
+ open();
+ ContentValues values = new ContentValues();
+ values.put(KEY_TITLE, feed.title);
+ values.put(KEY_LINK, feed.link);
+ values.put(KEY_DESCRIPTION, feed.description);
+ if (feed.image != null) {
+ if (feed.image.id == 0) {
+ setImage(feed.image);
+ }
+ values.put(KEY_IMAGE, feed.image.id);
+ }
+ if(feed.category != null) {
+ if(feed.category.id == 0) {
+ setCategory(feed.category);
+ }
+ values.put(KEY_CATEGORY, feed.category.id);
+ }
+ if(feed.file_url != null) {
+ values.put(KEY_FILE_URL, feed.file_url);
+ }
+ values.put(KEY_DOWNLOAD_URL, feed.download_url);
+
+ if(feed.id == 0) {
+ // Create new entry
+ feed.id = db.insert(TABLE_NAME_FEEDS, null, values);
+ } else {
+ db.update(TABLE_NAME_FEEDS, values, KEY_ID+"=?", new String[]{String.valueOf(feed.id)});
+ }
+ close();
+ return feed.id;
+ }
+
+ /** Inserts or updates a category entry
+ * @return the id of the entry
+ * */
+ public long setCategory(FeedCategory category) {
+ ContentValues values = new ContentValues();
+ values.put(KEY_NAME, category.name);
+ if(category.id == 0) {
+ category.id = db.insert(TABLE_NAME_FEED_CATEGORIES, null, values);
+ } else {
+ db.update(TABLE_NAME_FEED_CATEGORIES, values, KEY_ID+"=?", new String[]{String.valueOf(category.id)});
+
+ }
+ return category.id;
+ }
+
+ /**
+ * Inserts or updates an image entry
+ * @return the id of the entry
+ * */
+ public long setImage(FeedImage image) {
+ ContentValues values = new ContentValues();
+ values.put(KEY_TITLE, image.title);
+ values.put(KEY_DOWNLOAD_URL, image.download_url);
+ if(image.file_url != null) {
+ values.put(KEY_FILE_URL, image.file_url);
+ }
+ if(image.id == 0) {
+ image.id = db.insert(TABLE_NAME_FEED_IMAGES, null, values);
+ } else {
+ db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID+"=?", new String[]{String.valueOf(image.id)});
+ }
+ return image.id;
+ }
+
+ /**
+ * Inserts or updates an image entry
+ * @return the id of the entry
+ */
+ public long setMedia(FeedMedia media) {
+ ContentValues values = new ContentValues();
+ values.put(KEY_LENGTH, media.length);
+ values.put(KEY_POSITION, media.position);
+ values.put(KEY_SIZE, media.size);
+ values.put(KEY_MIME_TYPE, media.mime_type);
+ values.put(KEY_DOWNLOAD_URL, media.download_url);
+ if(media.file_url != null) {
+ values.put(KEY_FILE_URL, media.file_url);
+ }
+ if(media.id == 0) {
+ media.id = db.insert(TABLE_NAME_FEED_MEDIA, null, values);
+ } else {
+ db.update(TABLE_NAME_FEED_MEDIA, values, KEY_ID+"=?", new String[]{String.valueOf(media.id)});
+ }
+ return media.id;
+ }
+
+ /**
+ * Inserts or updates a feeditem entry
+ * @return the id of the entry
+ */
+ public long setFeedItem(FeedItem item) {
+ ContentValues values = new ContentValues();
+ values.put(KEY_TITLE, item.title);
+ values.put(KEY_LINK, item.link);
+ values.put(KEY_DESCRIPTION, item.description);
+ values.put(KEY_PUBDATE, item.pubDate);
+ if(item.media != null) {
+ if(item.media.id == 0) {
+ setMedia(item.media);
+ }
+ values.put(KEY_MEDIA, item.media.id);
+ }
+ if(item.feed.id == 0) {
+ setFeed(item.feed);
+ }
+ values.put(KEY_FEED, item.feed.id);
+ values.put(KEY_READ, (item.read) ? 1 : 0);
+ return item.id;
+ }
+
+ public Cursor getAllCategoriesCursor() {
+ return db.query(TABLE_NAME_FEED_CATEGORIES, null, null, null, null, null, null);
+ }
+
+ public Cursor getAllFeedsCursor() {
+ return db.query(TABLE_NAME_FEEDS, null, null, null, null, null, null);
+ }
+
+ public Cursor getAllItemsOfFeedCursor(Feed feed) {
+ return db.query(TABLE_NAME_FEED_ITEMS, null, KEY_FEED+"=?", new String[]{String.valueOf(feed.id)}, null, null, null);
+ }
+
+ public Cursor getFeedMediaOfItemCursor(FeedItem item) {
+ return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID+"=?", new String[]{String.valueOf(item.media.id)}, null, null, null);
+ }
+
+ public Cursor getImageOfFeedCursor(Feed feed) {
+ return db.query(TABLE_NAME_FEED_IMAGES, null, KEY_ID+"=?", new String[]{String.valueOf(feed.image.id)}, null, null, null);
+ }
+
+ public FeedMedia getFeedMedia(long row_index) throws SQLException{
+ Cursor cursor = db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID+"=?", new String[]{String.valueOf(row_index)}, null, null, null);
+
+ if((cursor.getCount() == 0) || !cursor.moveToFirst()) {
+ throw new SQLException("No FeedMedia found at index: "+ row_index);
+ }
+
+ return new FeedMedia(row_index,
+ cursor.getLong(cursor.getColumnIndex(KEY_LENGTH)),
+ cursor.getLong(cursor.getColumnIndex(KEY_POSITION)),
+ cursor.getLong(cursor.getColumnIndex(KEY_SIZE)),
+ cursor.getString(cursor.getColumnIndex(KEY_MIME_TYPE)),
+ cursor.getString(cursor.getColumnIndex(KEY_FILE_URL)),
+ cursor.getString(cursor.getColumnIndex(KEY_DOWNLOAD_URL)));
+
+ }
+
+ public FeedImage getFeedImage(Feed feed) throws SQLException {
+ Cursor cursor = this.getImageOfFeedCursor(feed);
+ if((cursor.getCount() == 0) || !cursor.moveToFirst()) {
+ throw new SQLException("No FeedImage found at index: "+ feed.image.id);
+ }
+
+ return new FeedImage(feed.image.id, cursor.getString(cursor.getColumnIndex(KEY_TITLE)),
+ cursor.getString(cursor.getColumnIndex(KEY_FILE_URL)),
+ cursor.getString(cursor.getColumnIndex(KEY_DOWNLOAD_URL)));
+ }
+
+ private static class PodDBHelper extends SQLiteOpenHelper {
+
+ public PodDBHelper(Context context, String name, CursorFactory factory,
+ int version) {
+ super(context, name, factory, version);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(CREATE_TABLE_FEEDS);
+ db.execSQL(CREATE_TABLE_FEED_ITEMS);
+ db.execSQL(CREATE_TABLE_FEED_CATEGORIES);
+ db.execSQL(CREATE_TABLE_FEED_IMAGES);
+ db.execSQL(CREATE_TABLE_FEED_MEDIA);
+
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
+ + newVersion + ".");
+ // TODO delete Database
+
+ }
+
+ }
+}