diff options
author | Daniel Oeh <daniel@daniel-pc.(none)> | 2011-12-23 19:22:06 +0100 |
---|---|---|
committer | Daniel Oeh <daniel@daniel-pc.(none)> | 2011-12-23 19:22:06 +0100 |
commit | c9283f09dced6f156e13675ef4c13ebeb20cb9e5 (patch) | |
tree | 833961a4fd03b94086223dba9f658cb2841cbe77 /src | |
download | AntennaPod-c9283f09dced6f156e13675ef4c13ebeb20cb9e5.zip |
Initial Commit
Diffstat (limited to 'src')
-rw-r--r-- | src/de/podfetcher/PodcastApp.java | 25 | ||||
-rw-r--r-- | src/de/podfetcher/PodfetcherActivity.java | 41 | ||||
-rw-r--r-- | src/de/podfetcher/feed/Feed.java | 45 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedCategory.java | 12 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedComponent.java | 16 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedFile.java | 7 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedHandler.java | 41 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedImage.java | 26 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedItem.java | 33 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedManager.java | 116 | ||||
-rw-r--r-- | src/de/podfetcher/feed/FeedMedia.java | 33 | ||||
-rw-r--r-- | src/de/podfetcher/feed/RSSHandler.java | 116 | ||||
-rw-r--r-- | src/de/podfetcher/gui/AddFeedActivity.java | 15 | ||||
-rw-r--r-- | src/de/podfetcher/gui/FeedlistAdapter.java | 57 | ||||
-rw-r--r-- | src/de/podfetcher/storage/DownloadReceiver.java | 27 | ||||
-rw-r--r-- | src/de/podfetcher/storage/DownloadRequester.java | 131 | ||||
-rw-r--r-- | src/de/podfetcher/storage/PodDBAdapter.java | 295 |
17 files changed, 1036 insertions, 0 deletions
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 + + } + + } +} |