Commits

Ed Crewe  committed 1d2f2dc

add in extra java

  • Participants
  • Parent commits 2f5b84e

Comments (0)

Files changed (7)

File android/placeUvote/src/com/placeuvote/android/AboutActivity.java

+/**
+ * Sparse rss
+ * 
+ * Copyright (c) 2010 Stefan Handschuh
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+package com.placeuvote.android;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class AboutActivity extends Activity {
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.about);
+	}
+
+}

File android/placeUvote/src/com/placeuvote/android/ApplicationPreferencesActivity.java

+/**
+ * Sparse rss
+ * 
+ * Copyright (c) 2010 Stefan Handschuh
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+package com.placeuvote.android;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.Preference.OnPreferenceChangeListener;
+import com.placeuvote.android.rss.RefreshService;
+import com.placeuvote.android.rss.Strings;
+
+public class ApplicationPreferencesActivity extends PreferenceActivity {
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		addPreferencesFromResource(R.layout.preferences);
+		
+		Preference enablePreference = (Preference) findPreference(Strings.SETTINGS_REFRESHENABLED);
+
+		enablePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+			public boolean onPreferenceChange(Preference preference, Object newValue) {
+				if (Boolean.TRUE.equals(newValue)) {
+					new Thread() {
+						public void run() {
+							startService(new Intent(ApplicationPreferencesActivity.this, RefreshService.class));
+						}
+					}.start();
+				} else {
+					stopService(new Intent(ApplicationPreferencesActivity.this, RefreshService.class));
+				}
+				return true;
+			}
+		});
+		
+		Preference showTabsPreference = (Preference) findPreference(Strings.SETTINGS_SHOWTABS);
+		
+		showTabsPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+			public boolean onPreferenceChange(Preference preference, Object newValue) {
+				if (MainTabActivity.INSTANCE != null ) {
+					MainTabActivity.INSTANCE.setTabWidgetVisible(Boolean.TRUE.equals(newValue));
+					
+				}
+				return true;
+			}
+		});
+		
+	}
+}

File android/placeUvote/src/com/placeuvote/android/EntriesListActivity.java

+/**
+ * Sparse rss
+ * 
+ * Copyright (c) 2010 Stefan Handschuh
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+package com.placeuvote.android;
+
+import android.app.ListActivity;
+import android.content.ContentUris;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.ListView;
+import com.placeuvote.android.rss.FeedData;
+import com.placeuvote.android.rss.Strings;
+
+public class EntriesListActivity extends ListActivity {
+	public static final String EXTRA_SHOWREAD = "show_read";
+	
+	public static final String EXTRA_SHOWFEEDINFO = "show_feedinfo";
+
+	private Uri uri;
+	
+	private EntriesListAdapter entriesListAdapter;
+	
+	private byte[] iconBytes;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		
+		iconBytes = getIntent().getByteArrayExtra(FeedData.FeedColumns.ICON);
+
+		if (iconBytes != null && iconBytes.length > 0) { // we cannot insert the icon here because it would be overwritten, but we have to reserve the icon here
+			if (!requestWindowFeature(Window.FEATURE_LEFT_ICON)) {
+				iconBytes = null;
+			}
+		}
+        
+		setContentView(R.layout.entries);
+		uri = getIntent().getData();
+		entriesListAdapter = new EntriesListAdapter(this, uri, getIntent().getBooleanExtra(EXTRA_SHOWFEEDINFO, false));
+        setListAdapter(entriesListAdapter);
+        
+        String title = getIntent().getStringExtra(FeedData.FeedColumns.NAME);
+        
+        if (title != null) {
+        	setTitle(title);
+        }
+        if (iconBytes != null && iconBytes.length > 0) {
+        	setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length)));
+        }
+        PollMain.notificationManager.cancel(0);
+	}
+
+	@Override
+	protected void onListItemClick(ListView listView, View view, int position, long id) {
+		startActivity(new Intent(Intent.ACTION_VIEW, ContentUris.withAppendedId(uri, id)).putExtra(EXTRA_SHOWREAD, entriesListAdapter.isShowRead()).putExtra(FeedData.FeedColumns.ICON, iconBytes));
+	}
+	
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		menu.add(0, 0, Menu.NONE, R.string.contextmenu_markasread).setIcon(android.R.drawable.ic_menu_revert);
+		menu.add(1, 1, Menu.NONE, R.string.contextmenu_hideread).setCheckable(true).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
+		return true;
+	}
+	
+	@Override
+	public boolean onPrepareOptionsMenu(Menu menu) {
+		menu.setGroupVisible(0, entriesListAdapter.getCount() > 0);
+		return super.onPrepareOptionsMenu(menu);
+	}
+
+	public boolean onMenuItemSelected(int featureId, MenuItem item) {
+		if (item.getItemId() == 0) {
+			new Thread() { // the update process takes some time
+				public void run() {
+					getContentResolver().update(uri, PollMain.getReadContentValues(), null, null);
+				}
+			}.start();
+		} else {
+			if (item.isChecked()) {
+				item.setChecked(false).setTitle(R.string.contextmenu_hideread).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
+				entriesListAdapter.showRead(true);
+			} else {
+				item.setChecked(true).setTitle(R.string.contextmenu_showread).setIcon(android.R.drawable.ic_menu_view);
+				entriesListAdapter.showRead(false);
+			}
+		}
+		return true;
+	}
+	
+}

File android/placeUvote/src/com/placeuvote/android/EntriesListAdapter.java

+/**
+ * Sparse rss
+ * 
+ * Copyright (c) 2010 Stefan Handschuh
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+package com.placeuvote.android;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.BitmapFactory;
+import android.graphics.Typeface;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+import android.widget.ResourceCursorAdapter;
+import android.widget.TextView;
+import com.placeuvote.android.rss.FeedData;
+import com.placeuvote.android.rss.Strings;
+
+public class EntriesListAdapter extends ResourceCursorAdapter {
+	public static DateFormat DATEFORMAT = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+	
+	private int titleColumnPosition;
+	
+	private int dateColumn;
+	
+	private int readDateColumn;
+	
+	private int favoriteColumn;
+	
+	private int idColumn;
+	
+	private int feedIconColumn;
+	
+	private int feedNameColumn;
+	
+	private static final String SQLREAD = "length(readdate) ASC, ";
+	
+	public static final String READDATEISNULL = "readdate is null";
+	
+	private boolean showRead;
+	
+	private Activity context;
+	
+	private Uri uri;
+	
+	private boolean showFeedInfo;
+	
+	public EntriesListAdapter(Activity context, Uri uri, boolean showFeedInfo) {
+		super(context, R.layout.listitem, createManagedCursor(context, uri, true));
+		showRead = true;
+		this.context = context;
+		this.uri = uri;
+		titleColumnPosition = getCursor().getColumnIndex(FeedData.EntryColumns.TITLE);
+		dateColumn = getCursor().getColumnIndex(FeedData.EntryColumns.DATE);
+		readDateColumn = getCursor().getColumnIndex(FeedData.EntryColumns.READDATE);
+		favoriteColumn = getCursor().getColumnIndex(FeedData.EntryColumns.FAVORITE);
+		idColumn = getCursor().getColumnIndex(FeedData.EntryColumns._ID);
+		this.showFeedInfo = showFeedInfo;
+		if (showFeedInfo) {
+			feedIconColumn = getCursor().getColumnIndex(FeedData.FeedColumns.ICON);
+			feedNameColumn = getCursor().getColumnIndex(FeedData.FeedColumns.NAME);
+		}
+	}
+
+	@Override
+	public void bindView(View view, final Context context, Cursor cursor) {
+		TextView textView = (TextView) view.findViewById(android.R.id.text1);
+		
+		textView.setText(cursor.getString(titleColumnPosition));
+		
+		TextView dateTextView = (TextView) view.findViewById(android.R.id.text2);
+		
+		ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
+		 
+		final boolean favorite = cursor.getInt(favoriteColumn) == 1;
+		
+		final String id = cursor.getString(idColumn);
+		
+		imageView.setImageResource(favorite ? android.R.drawable.star_on : android.R.drawable.star_off);
+		imageView.setOnClickListener(new OnClickListener() {
+			public void onClick(View view) {
+				ContentValues values = new ContentValues();
+				
+				values.put(FeedData.EntryColumns.FAVORITE, favorite ? 0 : 1);
+				view.getContext().getContentResolver().update(uri, values, new StringBuilder(FeedData.EntryColumns._ID).append(Strings.DB_ARG).toString(), new String[] {id});
+				context.getContentResolver().notifyChange(FeedData.EntryColumns.FAVORITES_CONTENT_URI, null);
+			}
+		});
+		if (cursor.isNull(readDateColumn)) {
+			textView.setTypeface(Typeface.DEFAULT_BOLD);
+			textView.setEnabled(true);
+			dateTextView.setEnabled(true);
+		} else {
+			textView.setTypeface(Typeface.DEFAULT);
+			textView.setEnabled(false);
+			dateTextView.setEnabled(false);
+		}
+		if (showFeedInfo) {
+			byte[] iconBytes = cursor.getBlob(feedIconColumn);
+			
+			if (iconBytes != null && iconBytes.length > 0) {
+				dateTextView.setText(" "+DATEFORMAT.format(new Date(cursor.getLong(dateColumn)))+", "+cursor.getString(feedNameColumn)); // bad style
+				dateTextView.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length)), null, null,  null);
+			} else {
+				dateTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+				dateTextView.setText(DATEFORMAT.format(new Date(cursor.getLong(dateColumn)))+", "+cursor.getString(feedNameColumn));
+			}
+			
+		} else {
+			textView.setText(cursor.getString(titleColumnPosition));
+			dateTextView.setText(DateFormat.getDateTimeInstance().format(new Date(cursor.getLong(dateColumn))));
+		}
+	}
+
+	public void showRead(boolean showRead) {
+		if (showRead != this.showRead) {
+			changeCursor(createManagedCursor(context, uri, showRead));
+			this.showRead = showRead;
+		}
+	}
+	
+	public boolean isShowRead() {
+		return showRead;
+	}
+	
+	private static Cursor createManagedCursor(Activity context, Uri uri, boolean showRead) {
+		return context.managedQuery(uri, null, showRead ? null : READDATEISNULL, null, new StringBuilder(PreferenceManager.getDefaultSharedPreferences(context).getBoolean(Strings.SETTINGS_PRIORITIZE, false) ? SQLREAD : Strings.EMPTY).append(FeedData.EntryColumns.DATE).append(Strings.DB_DESC).toString());
+	}
+}

File android/placeUvote/src/com/placeuvote/android/MainTabActivity.java

+package com.placeuvote.android;
+
+import android.app.TabActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.widget.TabHost;
+import com.placeuvote.android.rss.FeedData;
+import com.placeuvote.android.rss.Strings;
+
+
+public class MainTabActivity extends TabActivity {
+	private boolean tabsAdded;
+	
+	private static final String TAG_NORMAL = "normal";
+	
+	private static final String TAG_ALL = "all";
+	
+	private static final String TAG_FAVORITE = "favorite";
+	
+	public static MainTabActivity INSTANCE;
+	
+	public void onCreate(Bundle savedInstanceState) {
+	    super.onCreate(savedInstanceState);
+	    INSTANCE = this;
+	    setContentView(R.layout.tabs);
+
+	    TabHost tabHost = getTabHost();  
+
+	    tabHost.addTab(tabHost.newTabSpec(TAG_NORMAL).setIndicator(getString(R.string.overview)).setContent(new Intent().setClass(this, PollMain.class)));
+	    
+	    if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Strings.SETTINGS_SHOWTABS, false)) {
+	    	tabHost.addTab(tabHost.newTabSpec(TAG_ALL).setIndicator(getString(R.string.all)).setContent(new Intent(Intent.ACTION_VIEW, FeedData.EntryColumns.CONTENT_URI).putExtra(EntriesListActivity.EXTRA_SHOWFEEDINFO, true)));
+		    tabHost.addTab(tabHost.newTabSpec(TAG_FAVORITE).setIndicator(getString(R.string.favorites), getResources().getDrawable(android.R.drawable.star_big_on)).setContent(new Intent(Intent.ACTION_VIEW, FeedData.EntryColumns.FAVORITES_CONTENT_URI).putExtra(EntriesListActivity.EXTRA_SHOWFEEDINFO, true)));
+		    tabsAdded = true;
+		    getTabWidget().setVisibility(View.VISIBLE);
+	    }
+	}
+
+	public void setTabWidgetVisible(boolean visible) {
+		if (visible) {
+			if (!tabsAdded) {
+				TabHost tabHost = getTabHost();
+				
+				tabHost.addTab(tabHost.newTabSpec(TAG_ALL).setIndicator(getString(R.string.all)).setContent(new Intent(Intent.ACTION_VIEW, FeedData.EntryColumns.CONTENT_URI).putExtra(EntriesListActivity.EXTRA_SHOWFEEDINFO, true)));
+			    tabHost.addTab(tabHost.newTabSpec(TAG_FAVORITE).setIndicator(getString(R.string.favorites), getResources().getDrawable(android.R.drawable.star_big_on)).setContent(new Intent(Intent.ACTION_VIEW, FeedData.EntryColumns.FAVORITES_CONTENT_URI).putExtra(EntriesListActivity.EXTRA_SHOWFEEDINFO, true)));
+				tabsAdded = true;
+			}
+			getTabWidget().setVisibility(View.VISIBLE);
+		} else {
+			getTabWidget().setVisibility(View.GONE);
+		}
+		
+	}
+
+}

File android/placeUvote/src/com/placeuvote/android/PollMain.java

+package com.placeuvote.android;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.app.NotificationManager;
+import android.app.AlertDialog.Builder;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.Environment;
+import android.preference.PreferenceManager;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnClickListener;
+import android.view.View.OnCreateContextMenuListener;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.placeuvote.android.rss.FeedData;
+import com.placeuvote.android.rss.FeedDataContentProvider;
+import com.placeuvote.android.rss.RefreshService;
+import com.placeuvote.android.rss.Strings;
+
+public class PollMain extends ListActivity {	
+	
+	private static final int MENU_REFRESH_ID = 2;
+	
+	private static final int CONTEXTMENU_EDIT_ID = 3;
+	
+	private static final int CONTEXTMENU_REFRESH_ID = 4;
+	
+	private static final int CONTEXTMENU_DELETE_ID = 5;
+	
+	private static final int CONTEXTMENU_MARKASREAD_ID = 6;
+	
+	private static final int MENU_SETTINGS_ID = 7;
+	
+	private static final int MENU_ALLREAD = 8;
+	
+	private static final int MENU_ABOUT_ID = 9;
+	
+	private static final int MENU_IMPORT_ID = 10;
+	
+	private static final int MENU_EXPORT_ID = 11;
+	
+	private static final int ACTIVITY_APPLICATIONPREFERENCES_ID = 1;
+	
+	
+	static NotificationManager notificationManager; // package scope
+	
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        this.AddFeeds();
+        if (notificationManager == null) {
+        	notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+        }
+        setContentView(R.layout.main);
+        setListAdapter(new PollMainList(this));
+        getListView().setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
+			public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+				menu.setHeaderTitle(((TextView) ((AdapterView.AdapterContextMenuInfo) menuInfo).targetView.findViewById(android.R.id.text1)).getText());
+				menu.add(0, CONTEXTMENU_EDIT_ID, Menu.NONE, R.string.contextmenu_edit);
+				menu.add(0, CONTEXTMENU_REFRESH_ID, Menu.NONE, R.string.contextmenu_refresh);
+				menu.add(0, CONTEXTMENU_DELETE_ID, Menu.NONE, R.string.contextmenu_delete);
+				menu.add(0, CONTEXTMENU_MARKASREAD_ID, Menu.NONE, R.string.contextmenu_markasread);
+			}
+        });
+        if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Strings.SETTINGS_REFRESHENABLED, false)) {
+        	startService(new Intent(this, RefreshService.class)); // starts the service independent to this activity
+        } 
+        if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Strings.SETTINGS_REFRESHONPENENABLED, false)) {
+        	sendBroadcast(new Intent(Strings.ACTION_REFRESHFEEDS));
+        }
+        
+        if (!FeedDataContentProvider.USE_SDCARD) {
+        	Button button = (Button) findViewById(R.id.reload_button);
+        	
+        	button.setOnClickListener(new OnClickListener() {
+    			public void onClick(View view) {
+    				android.os.Process.killProcess(android.os.Process.myPid());
+    			}
+            });
+        	button.setVisibility(View.VISIBLE);
+        }
+     }
+
+	public void AddFeeds() {
+		String id = "1";
+		String url = "http://www.placeuvote.com/polls.rss";
+		String name = "Public polls";	
+		Cursor cursor = getContentResolver().query(FeedData.FeedColumns.CONTENT_URI, new String[] {FeedData.FeedColumns._ID}, new StringBuilder(FeedData.FeedColumns.URL).append(Strings.DB_ARG).toString(), new String[] {url}, null);
+	
+		if (cursor.moveToFirst()) {
+			return;
+		} else {
+			ContentValues values = new ContentValues();
+			
+			if (!url.startsWith(Strings.HTTP) && !url.startsWith(Strings.HTTPS)) {
+				url = Strings.HTTP+url;
+			}
+			values.put(FeedData.FeedColumns.URL, url);
+			values.put(FeedData.FeedColumns.ERROR, (String) null);
+	
+			if (name.trim().length() > 0) {
+				values.put(FeedData.FeedColumns.NAME, name);
+			}
+			getContentResolver().insert(FeedData.FeedColumns.CONTENT_URI, values);
+		}
+		cursor.close();
+	}
+    
+	@Override
+	protected void onResume() {
+		super.onResume();
+		notificationManager.cancel(0);
+	}
+
+	@Override
+	public boolean onCreateOptionsMenu(Menu menu) {
+		menu.add(0, MENU_REFRESH_ID, Menu.NONE, R.string.menu_refresh).setIcon(android.R.drawable.ic_menu_rotate);
+		menu.add(0, MENU_SETTINGS_ID, Menu.NONE, R.string.menu_settings).setIcon(android.R.drawable.ic_menu_preferences);
+		menu.add(0, MENU_ALLREAD, Menu.NONE, R.string.menu_allread).setIcon(android.R.drawable.ic_menu_revert);
+		menu.add(0, MENU_ABOUT_ID, Menu.NONE, R.string.menu_about).setIcon(android.R.drawable.ic_menu_info_details);
+		
+		return true;
+	}
+
+	@Override
+	public boolean onMenuItemSelected(int featureId, final MenuItem item) {
+		switch (item.getItemId()) {
+			case MENU_REFRESH_ID: {
+				sendBroadcast(new Intent(Strings.ACTION_REFRESHFEEDS));
+				break;
+			}
+			case CONTEXTMENU_REFRESH_ID: {
+				sendBroadcast(new Intent(Strings.ACTION_REFRESHFEEDS).putExtra(Strings.FEEDID, Long.toString(((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id)));
+				break;
+			}
+
+			case CONTEXTMENU_MARKASREAD_ID: {
+				new Thread() {
+					public void run() {
+						getContentResolver().update(FeedData.EntryColumns.CONTENT_URI(Long.toString(((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id)), getReadContentValues(), new StringBuilder(FeedData.EntryColumns.READDATE).append(Strings.DB_ISNULL).toString(), null);
+					}
+				}.start();
+				break;
+			}
+			case MENU_SETTINGS_ID: {
+				startActivityForResult(new Intent(this, ApplicationPreferencesActivity.class), ACTIVITY_APPLICATIONPREFERENCES_ID);
+				break;
+			}
+			case MENU_ALLREAD: {
+				new Thread() {
+					public void run() {
+						if (getContentResolver().update(FeedData.EntryColumns.CONTENT_URI, getReadContentValues(), new StringBuilder(FeedData.EntryColumns.READDATE).append(Strings.DB_ISNULL).toString(), null) > 0) {
+							getContentResolver().notifyChange(FeedData.FeedColumns.CONTENT_URI, null);
+						}
+					}
+				}.start();
+				break;
+			}
+			case MENU_ABOUT_ID: {
+				startActivity(new Intent(this, AboutActivity.class));
+				break;
+			}
+		}
+		return true;
+	}
+	
+	public static final ContentValues getReadContentValues() {
+		ContentValues values = new ContentValues();
+		
+		values.put(FeedData.EntryColumns.READDATE, System.currentTimeMillis());
+		return values;
+	}
+
+	@Override
+	protected void onListItemClick(ListView listView, View view, int position, long id) {
+		Intent intent = new Intent(Intent.ACTION_VIEW, FeedData.EntryColumns.CONTENT_URI(Long.toString(id)));
+		
+		intent.putExtra(FeedData.FeedColumns.NAME, ((TextView) view.findViewById(android.R.id.text1)).getText());
+		intent.putExtra(FeedData.FeedColumns.ICON, view.getTag() != null ? (byte[]) view.getTag() : null);
+		startActivity(intent);
+	}
+
+
+	
+	
+	
+	private Dialog createErrorDialog(int messageId) {
+		AlertDialog.Builder builder = new AlertDialog.Builder(this);
+		
+		builder.setMessage(messageId);
+		builder.setTitle(R.string.error);
+		builder.setIcon(android.R.drawable.ic_dialog_alert);
+		builder.setPositiveButton(android.R.string.ok, null);
+		return builder.create();
+	}
+    
+}

File android/placeUvote/src/com/placeuvote/android/PollMainList.java

+/**
+ * Sparse rss
+ * 
+ * Copyright (c) 2010 Stefan Handschuh
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+package com.placeuvote.android;
+
+import java.util.Date;
+
+import android.app.Activity;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.BitmapFactory;
+import android.graphics.Typeface;
+import android.graphics.drawable.BitmapDrawable;
+import android.view.View;
+import android.widget.ResourceCursorAdapter;
+import android.widget.TextView;
+import com.placeuvote.android.rss.FeedData;
+
+public class PollMainList extends ResourceCursorAdapter {
+	private static final String COUNT = "COUNT(*) - COUNT(readdate)";
+	
+	private static final String COLON = ": ";
+	
+	private static final String COMMA = ", ";
+	
+	private int nameColumnPosition;
+	
+	private int lastUpdateColumn;
+	
+	private int idPosition;
+	
+	private int linkPosition;
+	
+	private int errorPosition;
+	
+	private int iconPosition;
+	
+	public PollMainList(Activity context) {
+		super(context, R.layout.listitem, context.managedQuery(FeedData.FeedColumns.CONTENT_URI, null, null, null, null));
+		nameColumnPosition = getCursor().getColumnIndex(FeedData.FeedColumns.NAME);
+		lastUpdateColumn = getCursor().getColumnIndex(FeedData.FeedColumns.LASTUPDATE);
+		idPosition = getCursor().getColumnIndex(FeedData.FeedColumns._ID);
+		linkPosition = getCursor().getColumnIndex(FeedData.FeedColumns.URL);
+		errorPosition = getCursor().getColumnIndex(FeedData.FeedColumns.ERROR);
+		iconPosition = getCursor().getColumnIndex(FeedData.FeedColumns.ICON);
+	}
+
+	@Override
+	public void bindView(View view, Context context, Cursor cursor) {
+		TextView textView = ((TextView) view.findViewById(android.R.id.text1));
+		
+		textView.setSingleLine();
+		
+		Cursor countCursor = context.getContentResolver().query(FeedData.EntryColumns.CONTENT_URI(cursor.getString(idPosition)), new String[] {COUNT}, null, null, null);
+		
+		countCursor.moveToFirst();
+		
+		int unreadCount = countCursor.getInt(0);
+		
+		countCursor.close();
+		
+		long date = cursor.getLong(lastUpdateColumn);
+		
+		TextView updateTextView = ((TextView) view.findViewById(android.R.id.text2));;
+		
+		if (cursor.isNull(errorPosition)) {
+			updateTextView.setText(new StringBuilder(context.getString(R.string.update)).append(COLON).append(date == 0 ? context.getString(R.string.never) : new StringBuilder(EntriesListAdapter.DATEFORMAT.format(new Date(date))).append(COMMA).append(unreadCount).append(' ').append(context.getString(R.string.unread))));
+		} else {
+			updateTextView.setText(new StringBuilder(context.getString(R.string.error)).append(COLON).append(cursor.getString(errorPosition)));
+		}
+		if (unreadCount > 0) {
+			textView.setTypeface(Typeface.DEFAULT_BOLD);
+			textView.setEnabled(true);
+			updateTextView.setEnabled(true);
+		} else {
+			textView.setTypeface(Typeface.DEFAULT);
+			textView.setEnabled(false);
+			updateTextView.setEnabled(false);
+		}
+		
+		byte[] iconBytes = cursor.getBlob(iconPosition);
+		
+		if (iconBytes != null && iconBytes.length > 0) {
+			textView.setText(" " + (cursor.isNull(nameColumnPosition) ? cursor.getString(linkPosition) : cursor.getString(nameColumnPosition)));
+			textView.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length)), null, null, null);
+			view.setTag(iconBytes);
+		} else {
+			view.setTag(null);
+			textView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+			textView.setText(cursor.isNull(nameColumnPosition) ? cursor.getString(linkPosition) : cursor.getString(nameColumnPosition));
+		}
+	}
+}