android-ibc-forum

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 5d3dfff98cfc02be40a8c31a31b9ec2482b04032
parent 0fae5c063a68867e9e8ed5146013a80ad3d822d9
Author: Jan Dankert <devnull@localhost>
Date:   Fri, 20 Jan 2012 01:05:54 +0100

Ermitteln von ungelesenen, neuen und teilgenommenen Themen.

Diffstat:
AndroidManifest.xml | 10++++++++--
res/layout/main.xml | 29-----------------------------
res/layout/start.xml | 29+++++++++++++++++++++++++++++
res/values/ibc.xml | 17++++++++++++-----
res/values/strings.xml | 4++++
src/de/mtbnews/android/ForumActivity.java | 370++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
src/de/mtbnews/android/IBCActivity.java | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
src/de/mtbnews/android/MailActivity.java | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/de/mtbnews/android/MailboxActivity.java | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/de/mtbnews/android/MessageActivity.java | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/de/mtbnews/android/NewsDetailActivity.java | 56++++++++++++++++++++++++++++++++++++++++++++++++++++----
src/de/mtbnews/android/adapter/MapContentAdapter.java | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/de/mtbnews/android/adapter/RSSContentAdapter.java | 7+++++--
src/de/mtbnews/android/image/ImageGetterAsyncTask.java | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/de/mtbnews/android/image/URLDrawable.java | 22++++++++++++++++++++++
src/de/mtbnews/android/image/URLImageParser.java | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/de/mtbnews/android/util/AppData.java | 19+++++++++++++++++++
src/de/mtbnews/android/util/ServerAsyncTask.java | 150-------------------------------------------------------------------------------
18 files changed, 1159 insertions(+), 246 deletions(-)

diff --git a/AndroidManifest.xml b/AndroidManifest.xml @@ -13,10 +13,16 @@ <activity android:name="Configuration" android:label="@string/preferences"></activity> - <activity android:name="ForumActivity" android:label="@string/forum"></activity> - <activity android:name="NewsActivity" android:label="@string/news"></activity> <activity android:name="NewsDetailActivity" android:label="@string/news"></activity> <activity android:name="PhotoActivity" android:label="@string/photos"></activity> + + <activity android:name="ForumActivity" android:label="@string/forum"></activity> + <activity android:name="TopicActivity" android:label="@string/forum"></activity> + <activity android:name="PostActivity" android:label="@string/forum"></activity> + + <activity android:name="MailboxActivity" android:label="@string/news"></activity> + <activity android:name="MailActivity" android:label="@string/news"></activity> + <activity android:name="MessageActivity" android:label="@string/news"></activity> <service android:name=".service.UploadIntentService"></service> diff --git a/res/layout/main.xml b/res/layout/main.xml @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" android:layout_height="wrap_content"> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" android:layout_width="fill_parent" - android:layout_height="fill_parent"> - - <ImageView android:src="@drawable/ibc_logo" - android:layout_width="fill_parent" android:layout_height="wrap_content"> - </ImageView> - <TextView android:layout_width="fill_parent" android:id="@+id/hello" - android:layout_height="wrap_content" /> - - <Button android:id="@+id/forum" android:text="@string/forum" - android:layout_width="fill_parent" android:layout_height="wrap_content"></Button> - - <Button android:id="@+id/news" android:text="@string/news" - android:layout_width="fill_parent" android:layout_height="wrap_content" - style="@style/button"></Button> - - <Button android:id="@+id/photo" android:text="@string/photos" - android:layout_width="fill_parent" android:layout_height="wrap_content" - style="@style/button"></Button> - - </LinearLayout> - -</ScrollView>- \ No newline at end of file diff --git a/res/layout/start.xml b/res/layout/start.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <LinearLayout android:orientation="horizontal" + android:layout_width="fill_parent" android:layout_height="wrap_content"> + + <ImageView android:src="@drawable/ibc_logo" + android:layout_width="wrap_content" android:layout_height="wrap_content"> + </ImageView> + + <LinearLayout android:orientation="vertical" + android:layout_width="fill_parent" android:layout_height="fill_parent"> + + <Button android:id="@+id/forum" android:text="@string/forum" + android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> + <Button android:id="@+id/photo" android:text="@string/photos" + android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> + </LinearLayout> + + + </LinearLayout> + + <ListView android:id="@id/android:list" android:layout_width="fill_parent" + android:layout_height="wrap_content"> + </ListView> + +</LinearLayout> diff --git a/res/values/ibc.xml b/res/values/ibc.xml @@ -9,28 +9,35 @@ <item name="android:buttonStyle">@style/button</item> - <item name="android:windowBackground">@drawable/ibc_logo</item> + <item name="android:windowBackground">@drawable/ibc_logo</item> </style> <style name="button" parent="@android:style/Widget.Button"> - <!-- - <item name="android:layout_width">wrap_content</item> - <item name="android:layout_height">wrap_content</item> - --> + <!-- + <item name="android:layout_width">wrap_content</item> <item + name="android:layout_height">wrap_content</item> + --> + <item name="android:background">@drawable/border</item> <item name="android:textSize">20sp</item> <item name="android:textColor">#003399</item> <!-- <item name="android:layout_margin">0dip</item> + <item name="android:background">#E3E3E3</item> --> + </style> + + <style name="textbox"> <item name="android:background">#E3E3E3</item> </style> <style name="normalText"> + <item name="android:background">#E3E3E3</item> <item name="android:textSize">13sp</item> <item name="android:textColor">#000000</item> </style> <style name="titleText"> + <item name="android:background">#E3E3E3</item> <item name="android:textSize">20sp</item> <item name="android:textColor">#003399</item> </style> diff --git a/res/values/strings.xml b/res/values/strings.xml @@ -6,6 +6,10 @@ <string name="username">Benutzername</string> <string name="path">Pfad</string> + <string name="unread_topics">Ungelesen</string> + <string name="participated_topics">Meine Themen</string> + <string name="latest_topics">Neuste Themen</string> + <string name="mailbox">Nachrichten</string> <string name="hostname">Hostname</string> <string name="password">Kennwort</string> <string name="port">Port</string> diff --git a/src/de/mtbnews/android/ForumActivity.java b/src/de/mtbnews/android/ForumActivity.java @@ -4,16 +4,28 @@ package de.mtbnews.android; import java.io.IOException; -import java.lang.reflect.ReflectPermission; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.xmlrpc.android.XMLRPCClient; import org.xmlrpc.android.XMLRPCException; -import android.app.Activity; +import android.app.ListActivity; +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.AdapterView.OnItemClickListener; +import de.mtbnews.android.adapter.MapContentAdapter; +import de.mtbnews.android.util.AppData; import de.mtbnews.android.util.IBC; import de.mtbnews.android.util.ServerAsyncTask; @@ -21,32 +33,283 @@ import de.mtbnews.android.util.ServerAsyncTask; * @author dankert * */ -public class ForumActivity extends Activity +public class ForumActivity extends ListActivity { - public static final String ID = "id"; - public static final String CLIENT = "client"; - private String objectid; - - Map<String, String> data; - + private Object[] forumList; + @Override protected void onCreate(Bundle savedInstanceState) { - final SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(this); + if (AppData.client == null) + AppData.client = new XMLRPCClient(IBC.IBC_FORUM_CONNECTOR_URL); super.onCreate(savedInstanceState); setContentView(R.layout.listing); + if (getIntent().getBooleanExtra("latest", false)) + { + loadLatest(); + } + else if (getIntent().getBooleanExtra("participated", false)) + { + loadParticipated(); + } + else if (getIntent().getBooleanExtra("unread", false)) + { + loadUnread(); + } + else + { + loadForum(); + } + } + + private void loadUnread() + { + final SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(this); + final XMLRPCClient client = AppData.client; + + new ServerAsyncTask(this, R.string.waitingforcontent) + { + + + @Override + protected void callServer() throws IOException + { + + // add 2 to 4 + Object[] params = new Object[] { + prefs.getString("username", "").getBytes(), + prefs.getString("password", "").getBytes() }; + + try + { + Object sum = client.callEx("login", params); + + // Object l = client.call("get_inbox_stat"); + // System.out.println(l.toString() ); + Object l = client.call("get_unread_topic"); + + Object k = ((Map) l).get("topics"); + forumList = (Object[]) k; + + System.out.println(l.toString()); + + // Object i = client.call("get_box_info"); + // System.out.println(i.toString() ); + + } + catch (XMLRPCException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + + } + + protected void doOnSuccess() + { + List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); + for (Object o : forumList) + { + list.add((Map) o); + } + ListAdapter adapter = new MapContentAdapter(ForumActivity.this, + list, null, "topic_title", "short_content"); + // IBCActivity.this.setTitle(feed.getTitle()); + setListAdapter(adapter); + + } + + }.execute(); + final ListView list = getListView(); + + list.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + + final Intent intent = new Intent(ForumActivity.this, + TopicActivity.class); + intent.putExtra("topic_id", (String) ((Map)forumList[position]).get("topic_id")); + startActivity(intent); + } + }); + } + + private void loadLatest() + { + final SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(this); + final XMLRPCClient client = AppData.client; + + new ServerAsyncTask(this, R.string.waitingforcontent) + { + + + @Override + protected void callServer() throws IOException + { + + // add 2 to 4 + Object[] params = new Object[] { + prefs.getString("username", "").getBytes(), + prefs.getString("password", "").getBytes() }; + + try + { + Object sum = client.callEx("login", params); + + // Object l = client.call("get_inbox_stat"); + // System.out.println(l.toString() ); + Object l = client.call("get_latest_topic"); + + forumList = (Object[]) ((Map) l).get("topics"); + + System.out.println(l.toString()); + + // Object i = client.call("get_box_info"); + // System.out.println(i.toString() ); + + } + catch (XMLRPCException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + + } + + protected void doOnSuccess() + { + List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); + for (Object o : forumList) + { + list.add((Map) o); + } + ListAdapter adapter = new MapContentAdapter(ForumActivity.this, + list, null, "topic_title", "short_content"); + // IBCActivity.this.setTitle(feed.getTitle()); + setListAdapter(adapter); + + } + + }.execute(); + final ListView list = getListView(); + + list.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + + // final Intent intent = new Intent(ForumActivity.this, + // NewsDetailActivity.class); + // intent.putExtra("itemid", position); + // startActivity(intent); + } + }); + } + + private void loadParticipated() + { + final SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(this); + final XMLRPCClient client = AppData.client; + + new ServerAsyncTask(this, R.string.waitingforcontent) + { + + private Object[] forumList; + + @Override + protected void callServer() throws IOException + { + + // add 2 to 4 + Object[] params = new Object[] { + prefs.getString("username", "").getBytes(), + prefs.getString("password", "").getBytes() }; + + try + { + Object sum = client.callEx("login", params); + + // Object l = client.call("get_inbox_stat"); + // System.out.println(l.toString() ); + Object l = client.call("get_participated_topic"); + + this.forumList = (Object[]) ((Map) l).get("topics"); + + System.out.println(l.toString()); + + // Object i = client.call("get_box_info"); + // System.out.println(i.toString() ); + + } + catch (XMLRPCException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + + } + + protected void doOnSuccess() + { + List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); + for (Object o : forumList) + { + list.add((Map) o); + } + ListAdapter adapter = new MapContentAdapter(ForumActivity.this, + list, null, "topic_title", "short_content"); + // IBCActivity.this.setTitle(feed.getTitle()); + setListAdapter(adapter); + + } + + }.execute(); + final ListView list = getListView(); + + list.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + + // final Intent intent = new Intent(ForumActivity.this, + // NewsDetailActivity.class); + // intent.putExtra("itemid", position); + // startActivity(intent); + } + }); + } + + private void loadForum() + { + final SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(this); + final XMLRPCClient client = AppData.client; + new ServerAsyncTask(this, R.string.waitingforcontent) { + private Object[] forumList; + @Override protected void callServer() throws IOException { - XMLRPCClient client = new XMLRPCClient(IBC.IBC_FORUM_CONNECTOR_URL); // add 2 to 4 Object[] params = new Object[] { prefs.getString("username", "").getBytes(), @@ -55,15 +318,17 @@ public class ForumActivity extends Activity try { Object sum = client.callEx("login", params); - System.out.println(sum.getClass()); - System.out.println(sum); - - Object l = client.call("get_inbox_stat"); - System.out.println(l.toString() ); - - Object i = client.call("get_box_info"); - System.out.println(i.toString() ); - + + // Object l = client.call("get_inbox_stat"); + // System.out.println(l.toString() ); + Object l = client.call("get_forum"); + + this.forumList = (Object[]) l; + System.out.println(l.toString()); + + // Object i = client.call("get_box_info"); + // System.out.println(i.toString() ); + } catch (XMLRPCException e) { @@ -75,10 +340,73 @@ public class ForumActivity extends Activity protected void doOnSuccess() { + List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); + for (Object o : forumList) + { + list.add((Map) o); + } + ListAdapter adapter = new MapContentAdapter(ForumActivity.this, + list, null, "forum_name", "description"); + // IBCActivity.this.setTitle(feed.getTitle()); + setListAdapter(adapter); + } }.execute(); + final ListView list = getListView(); + + list.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + + // final Intent intent = new Intent(ForumActivity.this, + // NewsDetailActivity.class); + // intent.putExtra("itemid", position); + // startActivity(intent); + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + super.onCreateOptionsMenu(menu); + MenuInflater mi = new MenuInflater(getApplication()); + mi.inflate(R.menu.forum, menu); + + return true; + } + + public boolean onOptionsItemSelected(MenuItem item) + { + switch (item.getItemId()) + { + case R.id.menu_mailbox: + startActivity(new Intent(this, MailboxActivity.class)); + return true; + + case R.id.menu_participated_topics: + Intent intent = new Intent(this, ForumActivity.class); + intent.putExtra("participated", true); + startActivity(intent); + return true; + case R.id.menu_latest_topics: + Intent intent2 = new Intent(this, ForumActivity.class); + intent2.putExtra("latest", true); + startActivity(intent2); + return true; + case R.id.menu_unread_topics: + Intent intent3 = new Intent(this, ForumActivity.class); + intent3.putExtra("unread", true); + startActivity(intent3); + return true; + } + return false; } } diff --git a/src/de/mtbnews/android/IBCActivity.java b/src/de/mtbnews/android/IBCActivity.java @@ -18,11 +18,15 @@ */ package de.mtbnews.android; -import java.util.ArrayList; -import java.util.List; +import java.io.IOException; + +import org.apache.http.client.ClientProtocolException; +import org.mcsoxford.rss.RSSFeed; +import org.mcsoxford.rss.RSSReader; +import org.mcsoxford.rss.RSSReaderException; -import android.app.Activity; import android.app.AlertDialog; +import android.app.ListActivity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; @@ -32,27 +36,31 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; +import android.widget.AdapterView; import android.widget.Button; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.AdapterView.OnItemClickListener; +import de.mtbnews.android.adapter.RSSContentAdapter; +import de.mtbnews.android.util.AppData; +import de.mtbnews.android.util.IBC; +import de.mtbnews.android.util.ServerAsyncTask; /** * @author Jan Dankert */ -public class IBCActivity extends Activity +public class IBCActivity extends ListActivity { - private static final String PREFS_NAME = "OR_BLOG_PREFS"; - private List<String> serverList; - /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.main); + setContentView(R.layout.start); SharedPreferences globalPrefs = PreferenceManager .getDefaultSharedPreferences(this); - ArrayList<String> list = new ArrayList<String>(); if (globalPrefs.getString("username", "").equals("") ) { // Noch kein Benutzer konfiguriert. Hinweis anzeigen! @@ -73,30 +81,81 @@ public class IBCActivity extends Activity } }); - Button newsButton = (Button) findViewById(R.id.news); - newsButton.setOnClickListener( new OnClickListener() + + Button photoButton = (Button) findViewById(R.id.photo); + photoButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { - startActivity(new Intent(IBCActivity.this, NewsActivity.class)); + startActivity(new Intent(IBCActivity.this, PhotoActivity.class)); } }); + + reloadFeed(); + } + + + /** + * + */ + private void reloadFeed() + { + if ( AppData.newsFeed != null ) { + // Nicht nochmal laden. + // TODO: Reload-Funktion. + return; + } - Button photoButton = (Button) findViewById(R.id.photo); - photoButton.setOnClickListener( new OnClickListener() + new ServerAsyncTask(this, R.string.waitingforcontent) { - + + private RSSFeed feed; + @Override - public void onClick(View v) + protected void callServer() throws IOException { - startActivity(new Intent(IBCActivity.this, PhotoActivity.class)); + RSSReader reader = new RSSReader(); + try + { + feed = reader.load(IBC.IBC_NEWS_RSS_URL); + AppData.newsFeed = feed; + } + catch (RSSReaderException e) + { + throw new ClientProtocolException(e); + } } - }); + protected void doOnSuccess() + { + ListAdapter adapter = new RSSContentAdapter(IBCActivity.this, + feed); + IBCActivity.this.setTitle(feed.getTitle()); + setListAdapter(adapter); + } + }.execute(); + + final ListView list = getListView(); + + list.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + final Intent intent = new Intent(IBCActivity.this, + NewsDetailActivity.class); + intent.putExtra("itemid", position); + startActivity(intent); + } + }); } + + @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -114,22 +173,8 @@ public class IBCActivity extends Activity case R.id.menu_preferences: startActivity(new Intent(this, Configuration.class)); return true; + } return false; } - - @Override - protected void onStop() - { - super.onStop(); - - // Save user preferences. We need an Editor object to - // make changes. All objects are from android.context.Context - SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); - SharedPreferences.Editor editor = settings.edit(); - // editor.putBoolean("silentMode", mSilentMode); - - // Don't forget to commit your edits!!! - editor.commit(); - } } \ No newline at end of file diff --git a/src/de/mtbnews/android/MailActivity.java b/src/de/mtbnews/android/MailActivity.java @@ -0,0 +1,108 @@ +package de.mtbnews.android; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.mcsoxford.rss.RSSItem; +import org.xmlrpc.android.XMLRPCException; + +import android.app.ListActivity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.AdapterView.OnItemClickListener; +import de.mtbnews.android.adapter.MapContentAdapter; +import de.mtbnews.android.util.AppData; +import de.mtbnews.android.util.ServerAsyncTask; + +public class MailActivity extends ListActivity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + setContentView(R.layout.listing); + + super.onCreate(savedInstanceState); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.listing); + + new ServerAsyncTask(this, R.string.waitingforcontent) + { + + private Object[] forumList; + + @Override + protected void callServer() throws IOException + { + + try + { + Object l = AppData.client.call("get_box"); + + this.forumList = (Object[]) ((Map) l).get("list"); + + } + catch (XMLRPCException e) + { + throw new RuntimeException(e); + } + } + + protected void doOnSuccess() + { + List<Map<String, Object>> list1 = new ArrayList<Map<String, Object>>(); + for (Object o : forumList) + { + list1.add((Map) o); + } + ListAdapter adapter = new MapContentAdapter(MailActivity.this, + list1, null, "box_name", null); + // IBCActivity.this.setTitle(feed.getTitle()); + setListAdapter(adapter); + + } + + }.execute(); + final ListView list = getListView(); + + list.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + + // final Intent intent = new Intent(ForumActivity.this, + // NewsDetailActivity.class); + // intent.putExtra("itemid", position); + // startActivity(intent); + } + }); + + final ListView list2 = getListView(); + + list2.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + RSSItem item = (RSSItem) getListAdapter().getItem(position); + + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(item.getLink()); + startActivity(i); + } + }); + + } +} diff --git a/src/de/mtbnews/android/MailboxActivity.java b/src/de/mtbnews/android/MailboxActivity.java @@ -0,0 +1,116 @@ +package de.mtbnews.android; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.http.client.ClientProtocolException; +import org.mcsoxford.rss.RSSFeed; +import org.mcsoxford.rss.RSSItem; +import org.mcsoxford.rss.RSSReader; +import org.mcsoxford.rss.RSSReaderException; +import org.xmlrpc.android.XMLRPCException; + +import android.app.ListActivity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.AdapterView.OnItemClickListener; +import de.mtbnews.android.adapter.MapContentAdapter; +import de.mtbnews.android.adapter.RSSContentAdapter; +import de.mtbnews.android.util.AppData; +import de.mtbnews.android.util.IBC; +import de.mtbnews.android.util.ServerAsyncTask; + +public class MailboxActivity extends ListActivity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + setContentView(R.layout.listing); + + super.onCreate(savedInstanceState); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.listing); + + new ServerAsyncTask(this, R.string.waitingforcontent) + { + + private Object[] forumList; + + @Override + protected void callServer() throws IOException + { + + try + { + Object l = AppData.client.call("get_box_info"); + + this.forumList = (Object[]) ((Map) l).get("list"); + + } + catch (XMLRPCException e) + { + throw new RuntimeException(e); + } + } + + protected void doOnSuccess() + { + List<Map<String, Object>> list1 = new ArrayList<Map<String, Object>>(); + for (Object o : forumList) + { + list1.add((Map) o); + } + ListAdapter adapter = new MapContentAdapter(MailboxActivity.this, + list1, null, "box_name", null); + // IBCActivity.this.setTitle(feed.getTitle()); + setListAdapter(adapter); + + } + + }.execute(); + final ListView list = getListView(); + + list.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + + + // final Intent intent = new Intent(ForumActivity.this, + // NewsDetailActivity.class); + // intent.putExtra("itemid", position); + // startActivity(intent); + } + }); + + final ListView list2 = getListView(); + + list2.setOnItemClickListener(new OnItemClickListener() + { + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int position, long id) + { + RSSItem item = (RSSItem) getListAdapter().getItem(position); + + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(item.getLink()); + startActivity(i); + } + }); + + } +} diff --git a/src/de/mtbnews/android/MessageActivity.java b/src/de/mtbnews/android/MessageActivity.java @@ -0,0 +1,56 @@ +package de.mtbnews.android; + +import java.io.IOException; +import java.util.Map; + +import org.apache.http.client.ClientProtocolException; +import org.mcsoxford.rss.RSSFeed; +import org.mcsoxford.rss.RSSReader; +import org.mcsoxford.rss.RSSReaderException; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.ListAdapter; +import de.mtbnews.android.adapter.RSSContentAdapter; +import de.mtbnews.android.util.IBC; +import de.mtbnews.android.util.ServerAsyncTask; + +public class MessageActivity extends Activity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + setContentView(R.layout.listing); + + super.onCreate(savedInstanceState); + + new ServerAsyncTask(this, R.string.waitingforcontent) + { + + private RSSFeed feed; + + @Override + protected void callServer() throws IOException + { + RSSReader reader = new RSSReader(); + try + { + feed = reader.load(IBC.IBC_NEWS_RSS_URL); + } + catch (RSSReaderException e) + { + throw new ClientProtocolException(e); + } + } + + protected void doOnSuccess() + { + ListAdapter adapter = new RSSContentAdapter( + MessageActivity.this, feed); + MessageActivity.this.setTitle(feed.getTitle()); + // setListAdapter(adapter); + } + }.execute(); + + } +} diff --git a/src/de/mtbnews/android/NewsDetailActivity.java b/src/de/mtbnews/android/NewsDetailActivity.java @@ -1,11 +1,15 @@ package de.mtbnews.android; -import org.mcsoxford.rss.RSSItem; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; -import de.mtbnews.android.util.AppData; +import org.mcsoxford.rss.RSSItem; import android.app.Activity; import android.content.Intent; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.Html; import android.text.format.DateFormat; @@ -13,6 +17,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; +import de.mtbnews.android.util.AppData; public class NewsDetailActivity extends Activity { @@ -32,10 +37,11 @@ public class NewsDetailActivity extends Activity // TextView name = (TextView) findViewById(R.id.item_title); // name.setText(item.getTitle()); - TextView desc = (TextView) findViewById(R.id.item_description); + final TextView desc = (TextView) findViewById(R.id.item_description); // if (e.getContent() != null) - desc.setText(Html.fromHtml(item.getContent())); + final String html = item.getContent(); + desc.setText(Html.fromHtml(html, new ImageGetter(), null)); setTitle(item.getTitle()); Button button = (Button) findViewById(R.id.item_button); @@ -53,4 +59,46 @@ public class NewsDetailActivity extends Activity }); } + + protected class ImageGetter implements Html.ImageGetter + { + + public Drawable getDrawable(String source) + { + Drawable d = null; + String imageSource; +// if (!source.startsWith("http://www")) +// { +// imageSource = "http://www.minhembio.com" + source; +// } +// else +// { + imageSource = source; + // } + + try + { + URL myFileUrl = new URL(imageSource); + + HttpURLConnection conn = (HttpURLConnection) myFileUrl + .openConnection(); + conn.setDoInput(true); + conn.connect(); + InputStream is = conn.getInputStream(); + BitmapDrawable a = new BitmapDrawable(is); + d = a.getCurrent(); + d + .setBounds(0, 0, d.getIntrinsicWidth(), d + .getIntrinsicHeight()); + } + catch (Exception e) + { + throw new RuntimeException(e); + //d = null; + } + + return d; + } + }; + } diff --git a/src/de/mtbnews/android/adapter/MapContentAdapter.java b/src/de/mtbnews/android/adapter/MapContentAdapter.java @@ -0,0 +1,114 @@ +/** + * + */ +package de.mtbnews.android.adapter; + +import java.util.List; +import java.util.Map; + +import org.mcsoxford.rss.RSSItem; + +import android.content.Context; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; +import de.mtbnews.android.R; + +/** + * @author dankert + * + */ +public class MapContentAdapter extends BaseAdapter +{ + + /** Remember our context so we can use it when constructing views. */ + private Context mContext; + + /** + * Hold onto a copy of the entire Contact List. + */ + + private LayoutInflater inflator; + + private String dateKey; + private String titleKey; + private String descriptionKey; + + private List<Map<String, Object>> map; + + public MapContentAdapter(Context context, List<Map<String, Object>> map, + String dateKey, String titleKey, String descriptionKey) + { + mContext = context; + inflator = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + this.map = map; + this.dateKey = dateKey; + this.titleKey = titleKey; + this.descriptionKey = descriptionKey; + } + + public int getCount() + { + return map.size(); + } + + public Object getItem(int position) + { + return map.get(position); + } + + /** Use the array index as a unique id. */ + public long getItemId(int position) + { + return position; + + } + + /** + * @param convertView + * The old view to overwrite, if one is passed + * @returns a ContactEntryView that holds wraps around an ContactEntry + */ + public View getView(int position, View convertView, ViewGroup parent) + { + + Map<String, Object> e = map.get(position); + + final View view = inflator.inflate(R.layout.rss_item, null); + + if (dateKey != null) + { + TextView datum = (TextView) view.findViewById(R.id.item_date); + datum.setText(DateFormat.getDateFormat(parent.getContext()).format( + e.get(dateKey)) + + " " + + DateFormat.getTimeFormat(parent.getContext()).format( + e.get(dateKey))); + } + + if (titleKey != null) + { + + TextView name = (TextView) view.findViewById(R.id.item_title); + name.setText(new String((byte[]) e.get(titleKey))); + } + + if (descriptionKey != null) + { + TextView desc = (TextView) view.findViewById(R.id.item_description); + + if (e.get(descriptionKey) != null) + desc.setText(new String((byte[]) e.get(descriptionKey)) + + " ..."); + else + desc.setText(""); + } + + return view; + } + +} diff --git a/src/de/mtbnews/android/adapter/RSSContentAdapter.java b/src/de/mtbnews/android/adapter/RSSContentAdapter.java @@ -72,8 +72,11 @@ public class RSSContentAdapter extends BaseAdapter final View view = inflator.inflate(R.layout.rss_item, null); TextView datum = (TextView) view.findViewById(R.id.item_date); - datum.setText(DateFormat.getTimeFormat(parent.getContext()).format( - e.getPubDate())); + datum.setText(DateFormat.getDateFormat(parent.getContext()).format( + e.getPubDate()) + + " " + + DateFormat.getTimeFormat(parent.getContext()).format( + e.getPubDate())); TextView name = (TextView) view.findViewById(R.id.item_title); name.setText(e.getTitle()); diff --git a/src/de/mtbnews/android/image/ImageGetterAsyncTask.java b/src/de/mtbnews/android/image/ImageGetterAsyncTask.java @@ -0,0 +1,75 @@ +package de.mtbnews.android.image; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; + +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; + +public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> +{ + URLDrawable urlDrawable; + + public ImageGetterAsyncTask(URLDrawable d) + { + this.urlDrawable = d; + } + + @Override + protected Drawable doInBackground(String... params) + { + String source = params[0]; + return fetchDrawable(source); + } + + @Override + protected void onPostExecute(Drawable result) + { + // set the correct bound according to the result from HTTP call + urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0 + result + .getIntrinsicHeight()); + + // change the reference of the current drawable to the result + // from the HTTP call + urlDrawable.drawable = result; + + // redraw the image by invalidating the container + //URLImageParser.this.container.invalidate(); + } + + /*** + * Get the Drawable from URL + * + * @param urlString + * @return + */ + public Drawable fetchDrawable(String urlString) + { + try + { + InputStream is = fetch(urlString); + Drawable drawable = Drawable.createFromStream(is, "src"); + drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), + 0 + drawable.getIntrinsicHeight()); + return drawable; + } + catch (Exception e) + { + return null; + } + } + + private InputStream fetch(String urlString) throws MalformedURLException, + IOException + { + DefaultHttpClient httpClient = new DefaultHttpClient(); + HttpGet request = new HttpGet(urlString); + HttpResponse response = httpClient.execute(request); + return response.getEntity().getContent(); + } +} diff --git a/src/de/mtbnews/android/image/URLDrawable.java b/src/de/mtbnews/android/image/URLDrawable.java @@ -0,0 +1,22 @@ +package de.mtbnews.android.image; + +import android.graphics.Canvas; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; + +public class URLDrawable extends BitmapDrawable +{ + // the drawable that you need to set, you could set the initial drawing + // with the loading image if you need to + protected Drawable drawable; + + @Override + public void draw(Canvas canvas) + { + // override the draw to facilitate refresh function later + if (drawable != null) + { + drawable.draw(canvas); + } + } +} diff --git a/src/de/mtbnews/android/image/URLImageParser.java b/src/de/mtbnews/android/image/URLImageParser.java @@ -0,0 +1,112 @@ +package de.mtbnews.android.image; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.text.Html.ImageGetter; +import android.view.View; + +public class URLImageParser implements ImageGetter +{ + Context c; + View container; + + /*** + * Construct the URLImageParser which will execute AsyncTask and refresh the + * container + * + * @param t + * @param c + */ + public URLImageParser(View t, Context c) + { + this.c = c; + this.container = t; + } + + public Drawable getDrawable(String source) + { + URLDrawable urlDrawable = new URLDrawable(); + + // get the actual source + ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask(urlDrawable); + + asyncTask.execute(source); + + // return reference to URLDrawable where I will change with actual image + // from + // the src tag + return urlDrawable; + } + + public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> + { + URLDrawable urlDrawable; + + public ImageGetterAsyncTask(URLDrawable d) + { + this.urlDrawable = d; + } + + @Override + protected Drawable doInBackground(String... params) + { + String source = params[0]; + return fetchDrawable(source); + } + + @Override + protected void onPostExecute(Drawable result) + { + // set the correct bound according to the result from HTTP call + urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), + 0 + result.getIntrinsicHeight()); + + // change the reference of the current drawable to the result + // from the HTTP call + urlDrawable.drawable = result; + + // redraw the image by invalidating the container + URLImageParser.this.container.invalidate(); + } + + /*** + * Get the Drawable from URL + * + * @param urlString + * @return + */ + public Drawable fetchDrawable(String urlString) + { + try + { + InputStream is = fetch(urlString); + Drawable drawable = Drawable.createFromStream(is, "src"); + drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), + 0 + drawable.getIntrinsicHeight()); + return drawable; + } + catch (Exception e) + { + return null; + } + } + + private InputStream fetch(String urlString) + throws MalformedURLException, IOException + { + DefaultHttpClient httpClient = new DefaultHttpClient(); + HttpGet request = new HttpGet(urlString); + HttpResponse response = httpClient.execute(request); + return response.getEntity().getContent(); + } + } +} diff --git a/src/de/mtbnews/android/util/AppData.java b/src/de/mtbnews/android/util/AppData.java @@ -0,0 +1,19 @@ +package de.mtbnews.android.util; + +import org.mcsoxford.rss.RSSFeed; +import org.xmlrpc.android.XMLRPCClient; + +/** + * Speichert Anwendungsdaten. + * + * @author dankert + * + */ +public class AppData +{ + public static RSSFeed newsFeed; + + public static RSSFeed photoFeed; + + public static XMLRPCClient client; +} diff --git a/src/de/mtbnews/android/util/ServerAsyncTask.java b/src/de/mtbnews/android/util/ServerAsyncTask.java @@ -1,150 +0,0 @@ -/** - * - */ -package de.mtbnews.android.util; - -import java.io.IOException; - - -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.app.AlertDialog.Builder; -import android.content.Context; -import android.os.AsyncTask; -import android.util.Log; - -/** - * Ein asynchroner Task für den Zugriff auf einen Server. Der Aufruf - * des Servers muss in der zu überschreibenden Methode {@link #callServer()} - * durchgeführt werden.<br> - * <br> - * <br> - * Während der Serverabfrage wird ein {@link ProgressDialog} angezeigt. Falls - * die Abfrage nicht erfolgreich ist, wird automatisch ein {@link AlertDialog} - * mit einer Fehlermeldung angezeigt.<br> - * <br> - * <br> - * Durch überschreiben von {@link #doOnError(IOException)} kann selber auf einen - * Fehler reagiert werden. Durch Überschreiben von {@link #doOnSuccess()} kann - * eine Aktion nach erfolgreicher Serveranfrage ausgeführt werden. <br> - * - * @author dankert - * - */ -public abstract class ServerAsyncTask extends - AsyncTask<Void, Void, Void> -{ - private ProgressDialog progressDialog; - private Context context; - private AlertDialog alertDialog; - private IOException error; - - /** - * @param context - * Context des Aufrufers - * @param message - * Resource-Id für den Text im {@link ProgressDialog}. - */ - public ServerAsyncTask(Context context, int message) - { - this.context = context; - - this.progressDialog = new ProgressDialog(context); - // progressDialog.setTitle(R.string.loading); - progressDialog.setMessage(context.getResources().getString(message)); - } - - @Override - final protected void onPreExecute() - { - progressDialog.show(); - } - - /** - * {@inheritDoc} - * - * @see android.os.AsyncTask#onPostExecute(java.lang.Object) - */ - @Override - final protected void onPostExecute(Void result) - { - progressDialog.dismiss(); - - if (error != null) - { - doOnError(error); - } - else - { - doOnSuccess(); - } - } - - /** - * Wird aufgerufen, falls die Serveranfrage nicht durchgeführt werden - * konnte. Läuft im UI-Thread. - * - * @param error - * Exception, die aufgetreten ist. - */ - protected void doOnError(IOException error) - { - final Builder builder = new AlertDialog.Builder(this.context); - alertDialog = builder.setCancelable(true).create(); - final int causeRId = ExceptionUtils.getResourceStringId(error); - String msg = // this.context.getResources().getString(R.string.reason) - // + ":\n\n" + - error.getMessage(); - - Throwable t = error; - while (t.getCause() != null) - { - t = t.getCause(); - msg += ": " + t.getMessage(); - } - - alertDialog.setTitle(causeRId); - alertDialog.setIcon(android.R.drawable.ic_menu_close_clear_cancel); - alertDialog.setMessage(msg); - alertDialog.show(); - - } - - /** - * Wird aufgerufen, falls die Serveranfrage erfolgreich durchgeführt werden - * konnte. Läuft im UI-Thread. - */ - protected void doOnSuccess() - { - } - - /** - * Startet die Serveranfrage und fängt auftretene Fehler. - * - * @see android.os.AsyncTask#doInBackground(Params[]) - */ - @Override - final protected Void doInBackground(Void... params) - { - try - { - callServer(); - } - catch (IOException e) - { - Log.e(this.getClass().getName(), e.getMessage(), e); - error = e; - } - - return null; - } - - /** - * Ausführen der Serveranfrage. Auftretene {@link IOException} sollte - * weitergeworfen werden, da daraus ein {@link AlertDialog} erzeugt wird. - * - * @throws IOException - * Vom Server erzeugte Fehler - */ - protected abstract void callServer() throws IOException; -}