Android Open Source - Sparse-RSS Feed Data Content Provider






From Project

Back to project page Sparse-RSS.

License

The source code is released under:

Sparse rss Copyright (c) 2010-2012 Stefan Handschuh Translators - Dutch: Eelko Berkenpies - Spanish: Sergio Mart?n - French: <unnamed> - Turkish: <unnamed> - Russian: Igor Nedoboy Code-Contri...

If you think the Android project Sparse-RSS listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Sparse rss/* www. j a  v a 2 s  .  com*/
 * 
 * Copyright (c) 2010-2012 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 de.shandschuh.sparserss.provider;

import java.io.File;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import de.shandschuh.sparserss.Strings;

public class FeedDataContentProvider extends ContentProvider {
  private static final String FOLDER = Environment.getExternalStorageDirectory()+"/sparserss/";
  
  private static final String DATABASE_NAME = "sparserss.db";
  
  private static final int DATABASE_VERSION = 15;
  
  private static final int URI_FEEDS = 1;
  
  private static final int URI_FEED = 2;
  
  private static final int URI_ENTRIES = 3;
  
  private static final int URI_ENTRY= 4;
  
  private static final int URI_ALLENTRIES = 5;
  
  private static final int URI_ALLENTRIES_ENTRY = 6;
  
  private static final int URI_FAVORITES = 7;
  
  private static final int URI_FAVORITES_ENTRY = 8;
  
  protected static final String TABLE_FEEDS = "feeds";
  
  private static final String TABLE_ENTRIES = "entries";
  
  private static final String ALTER_TABLE = "ALTER TABLE ";
  
  private static final String ADD = " ADD ";
  
  private static final String EQUALS_ONE = "=1";

  public static final String IMAGEFOLDER = Environment.getExternalStorageDirectory()+"/sparserss/images/"; // faster than FOLDER+"images/"
  
  public static final File IMAGEFOLDER_FILE = new File(IMAGEFOLDER);
  
  private static final String BACKUPOPML = Environment.getExternalStorageDirectory()+"/sparserss/backup.opml";
  
  private static UriMatcher URI_MATCHER;
  
  private static final String[] PROJECTION_PRIORITY = new String[] {FeedData.FeedColumns.PRIORITY};
  
  static {
    URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds", URI_FEEDS);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds/#", URI_FEED);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds/#/entries", URI_ENTRIES);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "feeds/#/entries/#", URI_ENTRY);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "entries", URI_ALLENTRIES);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "entries/#", URI_ALLENTRIES_ENTRY);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "favorites", URI_FAVORITES);
    URI_MATCHER.addURI(FeedData.AUTHORITY, "favorites/#", URI_FAVORITES_ENTRY);
  }
  
  private static class DatabaseHelper extends SQLiteOpenHelper {
    public DatabaseHelper(Context context, String name, int version) {
      super(context, name, null, version);
      context.sendBroadcast(new Intent(Strings.ACTION_UPDATEWIDGET));
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
      database.execSQL(createTable(TABLE_FEEDS, FeedData.FeedColumns.COLUMNS, FeedData.FeedColumns.TYPES));
      database.execSQL(createTable(TABLE_ENTRIES, FeedData.EntryColumns.COLUMNS, FeedData.EntryColumns.TYPES));
      
      File backupFile = new File(BACKUPOPML);
      
      if (backupFile.exists()) {
        /** Perform an automated import of the backup */
        OPML.importFromFile(backupFile, database);
      }
    }
    
    private String createTable(String tableName, String[] columns, String[] types) {
      if (tableName == null || columns == null || types == null || types.length != columns.length || types.length == 0) {
        throw new IllegalArgumentException("Invalid parameters for creating table "+tableName);
      } else {
        StringBuilder stringBuilder = new StringBuilder("CREATE TABLE ");
        
        stringBuilder.append(tableName);
        stringBuilder.append(" (");
        for (int n = 0, i = columns.length; n < i; n++) {
          if (n > 0) {
            stringBuilder.append(", ");
          }
          stringBuilder.append(columns[n]).append(' ').append(types[n]);
        }
        return stringBuilder.append(");").toString();
      }
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
      if (oldVersion < 2) {
        executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.PRIORITY).append(' ').append(FeedData.TYPE_INT).toString());
      }
      if (oldVersion < 3) {
        executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.FAVORITE).append(' ').append(FeedData.TYPE_BOOLEAN).toString());
      }
      if (oldVersion < 4) {
        executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.FETCHMODE).append(' ').append(FeedData.TYPE_INT).toString());
      }
      if (oldVersion < 5) {
        executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.REALLASTUPDATE).append(' ').append(FeedData.TYPE_DATETIME).toString());
      } 
      if (oldVersion < 6) {
        database.execSQL(new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.ALERT_RINGTONE).append(' ').append(FeedData.TYPE_TEXT).toString());
      }
      if (oldVersion < 7) {
        database.execSQL(new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.OTHER_ALERT_RINGTONE).append(' ').append(FeedData.TYPE_INT).toString());
      }
      if (oldVersion < 8) {
        database.execSQL(new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.SKIP_ALERT).append(' ').append(FeedData.TYPE_INT).toString());
      }
      if (oldVersion < 9) {
        Cursor cursor = database.query(TABLE_FEEDS, new String[] {FeedData.FeedColumns._ID}, null, null, null, null, FeedData.FeedColumns._ID);
        
        int count = 0;
        
        while (cursor.moveToNext()) {
          executeCatchedSQL(database, new StringBuilder("UPDATE ").append(TABLE_FEEDS).append(" SET ").append(FeedData.FeedColumns.PRIORITY).append('=').append(count++).append(" WHERE _ID=").append(cursor.getLong(0)).toString());
        }
        cursor.close();
      } 
      if (oldVersion < 10) {
        executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_FEEDS).append(ADD).append(FeedData.FeedColumns.WIFIONLY).append(' ').append(FeedData.TYPE_BOOLEAN).toString());
      }
      // we simply leave the "encoded" column untouched
      if (oldVersion < 12) {
        executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.ENCLOSURE).append(' ').append(FeedData.TYPE_TEXT).toString());
      }
      if (oldVersion < 14) {
        executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.GUID).append(' ').append(FeedData.TYPE_TEXT).toString());
      }
          if (oldVersion < 15) {
              executeCatchedSQL(database, new StringBuilder(ALTER_TABLE).append(TABLE_ENTRIES).append(ADD).append(FeedData.EntryColumns.AUTHOR).append(' ').append(FeedData.TYPE_TEXT).toString());   
          }
    }
    
    private void executeCatchedSQL(SQLiteDatabase database, String query) {
      try {
        database.execSQL(query);
      } catch (Exception e) {
      }
    }

    @Override
    public synchronized SQLiteDatabase getWritableDatabase() {
      File oldDatabaseFile = new File(Environment.getExternalStorageDirectory()+"/sparserss/sparserss.db");
      
      if (oldDatabaseFile.exists()) { // get rid of the old structure
        SQLiteDatabase newDatabase = super.getWritableDatabase();
        
        try {
          SQLiteDatabase oldDatabase  = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()+"/sparserss/sparserss.db", null, SQLiteDatabase.OPEN_READWRITE + SQLiteDatabase.CREATE_IF_NECESSARY);
          
          Cursor cursor = oldDatabase.query(TABLE_ENTRIES, null, null, null, null, null, null);
          
          newDatabase.beginTransaction();
          
          String[] columnNames = cursor.getColumnNames();
          
          int i = columnNames.length;
          
          int[] columnIndices = new int[i];
          
          for (int n = 0; n < i; n++) {
            columnIndices[n] = cursor.getColumnIndex(columnNames[n]);
          }
          
          
          
          while (cursor.moveToNext()) {
            ContentValues values = new ContentValues();
            
            for (int n = 0; n < i; n++) {
              if (!cursor.isNull(columnIndices[n])) {
                values.put(columnNames[n], cursor.getString(columnIndices[n]));
              }
            }
            
            newDatabase.insert(TABLE_ENTRIES, null, values);
          }
          cursor.close();
          cursor = oldDatabase.query(TABLE_FEEDS, null, null, null, null, null, FeedData.FeedColumns._ID);
          columnNames = cursor.getColumnNames();
          i = columnNames.length;
          columnIndices = new int[i];
          
          for (int n = 0; n < i; n++) {
            columnIndices[n] = cursor.getColumnIndex(columnNames[n]);
          }
          
          int count = 0;
          
          while (cursor.moveToNext()) {
            ContentValues values = new ContentValues();
            
            for (int n = 0; n < i; n++) {
              if (!cursor.isNull(columnIndices[n])) {
                if (FeedData.FeedColumns.ICON.equals(columnNames[n])) {
                  values.put(FeedData.FeedColumns.ICON, cursor.getBlob(columnIndices[n]));
                } else {
                  values.put(columnNames[n], cursor.getString(columnIndices[n]));
                }
              } 
            }
            values.put(FeedData.FeedColumns.PRIORITY, count++);
            newDatabase.insert(TABLE_FEEDS, null, values);
          }
          cursor.close();
          oldDatabase.close();
          oldDatabaseFile.delete();
          newDatabase.setTransactionSuccessful();
          newDatabase.endTransaction();
          OPML.exportToFile(BACKUPOPML, newDatabase);
        } catch (Exception e) {
          
        }
        return newDatabase;
      } else {
        return super.getWritableDatabase();
      }
    }
  }
  
  private DatabaseHelper databaseHelper;
  
  private String[] MAXPRIORITY = new String[] {"MAX("+FeedData.FeedColumns.PRIORITY+")"};

  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    int option = URI_MATCHER.match(uri);
    
    String table = null;
    
    StringBuilder where = new StringBuilder();
    
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    
    switch(option) {
      case URI_FEED : {
        table = TABLE_FEEDS;
      
        final String feedId = uri.getPathSegments().get(1);
        
        new Thread() {
          public void run() {
            delete(FeedData.EntryColumns.CONTENT_URI(feedId), null, null);
          }
        }.start();
        
        where.append(FeedData.FeedColumns._ID).append('=').append(feedId);
        
        /** Update the priorities */
        Cursor priorityCursor = database.query(TABLE_FEEDS, PROJECTION_PRIORITY, FeedData.FeedColumns._ID+"="+feedId, null, null, null, null);
        
        if (priorityCursor.moveToNext()) {
          database.execSQL("UPDATE "+TABLE_FEEDS+" SET "+FeedData.FeedColumns.PRIORITY+" = "+FeedData.FeedColumns.PRIORITY+"-1 WHERE "+FeedData.FeedColumns.PRIORITY+" > "+priorityCursor.getInt(0));
          priorityCursor.close();
        } else {
          priorityCursor.close();
        }
        break;
      }
      case URI_FEEDS : {
        table = TABLE_FEEDS;
        break;
      }
      case URI_ENTRY : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(3));
        break;
      }
      case URI_ENTRIES : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns.FEED_ID).append('=').append(uri.getPathSegments().get(1));
        break;
      }
      case URI_ALLENTRIES : {
        table = TABLE_ENTRIES;
        break;
      }
      case URI_FAVORITES_ENTRY : 
      case URI_ALLENTRIES_ENTRY : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(1));
        break;
      }
      case URI_FAVORITES : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns.FAVORITE).append(EQUALS_ONE);
        break;
      }
    }
    
    if (!TextUtils.isEmpty(selection)) {
      if (where.length() > 0) {
        where.append(Strings.DB_AND);
      }
      where.append(selection);
    }
    
    int count = database.delete(table, where.toString(), selectionArgs);
    
    if (table == TABLE_FEEDS) { // == is ok here
      OPML.exportToFile(BACKUPOPML, database);
    }
    if (count > 0) {
      getContext().getContentResolver().notifyChange(uri, null);
    }
    return count;
  }

  @Override
  public String getType(Uri uri) {
    int option = URI_MATCHER.match(uri);
    
    switch(option) {
      case URI_FEEDS : return "vnd.android.cursor.dir/vnd.feeddata.feed";
      case URI_FEED : return "vnd.android.cursor.item/vnd.feeddata.feed";
      case URI_FAVORITES : 
      case URI_ALLENTRIES :
      case URI_ENTRIES : return "vnd.android.cursor.dir/vnd.feeddata.entry";
      case URI_FAVORITES_ENTRY : 
      case URI_ALLENTRIES_ENTRY : 
      case URI_ENTRY : return "vnd.android.cursor.item/vnd.feeddata.entry";
      default : throw new IllegalArgumentException("Unknown URI: "+uri);
    }
  }

  @Override
  public Uri insert(Uri uri, ContentValues values) {
    long newId = -1;
    
    int option = URI_MATCHER.match(uri);
    
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    
    switch (option) {
      case URI_FEEDS : {
        Cursor cursor = database.query(TABLE_FEEDS, MAXPRIORITY, null, null, null, null, null, null);
        
        if (cursor.moveToNext()) {
          values.put(FeedData.FeedColumns.PRIORITY, cursor.getInt(0)+1);
        } else {
          values.put(FeedData.FeedColumns.PRIORITY, 1);
        }
        cursor.close();
        newId = database.insert(TABLE_FEEDS, null, values);
        OPML.exportToFile(BACKUPOPML, database);
        break;
      }
      case URI_ENTRIES : {
        values.put(FeedData.EntryColumns.FEED_ID, uri.getPathSegments().get(1));
        newId = database.insert(TABLE_ENTRIES, null, values);
        break;
      }
      case URI_ALLENTRIES : {
        newId = database.insert(TABLE_ENTRIES, null, values);
        break;
      }
      default : throw new IllegalArgumentException("Illegal insert");
    }
    if (newId > -1) {
      getContext().getContentResolver().notifyChange(uri, null);
      return ContentUris.withAppendedId(uri, newId);
    } else {
      throw new SQLException("Could not insert row into "+uri);
    }
  }

  @Override
  public boolean onCreate() {
    try {
      File folder = new File(FOLDER);
      
      folder.mkdir(); // maybe we use the boolean return value later
    } catch (Exception e) {
      
    }
    databaseHelper = new DatabaseHelper(getContext(), DATABASE_NAME, DATABASE_VERSION);
    return true;
  }

  @Override
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    
    int option = URI_MATCHER.match(uri);
    
    if ((option == URI_FEED || option == URI_FEEDS) && sortOrder == null) {
      sortOrder = FeedData.FEED_DEFAULTSORTORDER;
    }
    
    switch(option) {
      case URI_FEED : {
        queryBuilder.setTables(TABLE_FEEDS);
        queryBuilder.appendWhere(new StringBuilder(FeedData.FeedColumns._ID).append('=').append(uri.getPathSegments().get(1)));
        break;
      }
      case URI_FEEDS : {
        queryBuilder.setTables(TABLE_FEEDS);
        break;
      }
      case URI_ENTRY : {
        queryBuilder.setTables(TABLE_ENTRIES);
        queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(3)));
        break;
      }
      case URI_ENTRIES : {
        queryBuilder.setTables(TABLE_ENTRIES);
        queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns.FEED_ID).append('=').append(uri.getPathSegments().get(1)));
        break;
      }
      case URI_ALLENTRIES : {
        queryBuilder.setTables("entries join (select name, icon, _id as feed_id from feeds) as F on (entries.feedid = F.feed_id)");
        break;
      }
      case URI_FAVORITES_ENTRY : 
      case URI_ALLENTRIES_ENTRY : {
        queryBuilder.setTables(TABLE_ENTRIES);
        queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(1)));
        break;
      }
      case URI_FAVORITES : {
        queryBuilder.setTables("entries join (select name, icon, _id as feed_id from feeds) as F on (entries.feedid = F.feed_id)");
        queryBuilder.appendWhere(new StringBuilder(FeedData.EntryColumns.FAVORITE).append(EQUALS_ONE));
        break;
      }
    }
    
    SQLiteDatabase database = databaseHelper.getReadableDatabase();
    
    Cursor cursor = queryBuilder.query(database, projection, selection, selectionArgs, null, null, sortOrder);

    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    return cursor;
  }

  @Override
  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    int option = URI_MATCHER.match(uri);
    
    String table = null;
    
    StringBuilder where = new StringBuilder();
    
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    
    switch(option) {
      case URI_FEED : {
        table = TABLE_FEEDS;
        
        long feedId = Long.parseLong(uri.getPathSegments().get(1));
        
        where.append(FeedData.FeedColumns._ID).append('=').append(feedId);
        if (values != null && values.containsKey(FeedData.FeedColumns.PRIORITY)) {
          int newPriority = values.getAsInteger(FeedData.FeedColumns.PRIORITY);
          
          Cursor priorityCursor = database.query(TABLE_FEEDS, PROJECTION_PRIORITY, FeedData.FeedColumns._ID+"="+feedId, null, null, null, null);
        
          if (priorityCursor.moveToNext()) {
            int oldPriority = priorityCursor.getInt(0);
            
            priorityCursor.close();
            if (newPriority > oldPriority) {
              database.execSQL("UPDATE "+TABLE_FEEDS+" SET "+FeedData.FeedColumns.PRIORITY+" = "+FeedData.FeedColumns.PRIORITY+"-1 WHERE "+FeedData.FeedColumns.PRIORITY+" BETWEEN "+(oldPriority+1)+" AND "+newPriority);
            } else if (newPriority < oldPriority) {
              database.execSQL("UPDATE "+TABLE_FEEDS+" SET "+FeedData.FeedColumns.PRIORITY+" = "+FeedData.FeedColumns.PRIORITY+"+1 WHERE "+FeedData.FeedColumns.PRIORITY+" BETWEEN "+newPriority+" AND "+(oldPriority-1));
            }
          } else {
            priorityCursor.close();
          }
        }
        break;
      }
      case URI_FEEDS : {
        table = TABLE_FEEDS;
        // maybe this should be disabled
        break;
      }
      case URI_ENTRY : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(3));
        break;
      }
      case URI_ENTRIES : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns.FEED_ID).append('=').append(uri.getPathSegments().get(1));
        break;
      }
      case URI_ALLENTRIES: {
        table = TABLE_ENTRIES;
        break;
      }
      case URI_FAVORITES_ENTRY : 
      case URI_ALLENTRIES_ENTRY : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns._ID).append('=').append(uri.getPathSegments().get(1));
        break;
      }
      case URI_FAVORITES : {
        table = TABLE_ENTRIES;
        where.append(FeedData.EntryColumns.FAVORITE).append(EQUALS_ONE);        
        break;
      }
    }
    
    if (!TextUtils.isEmpty(selection)) {
      if (where.length() > 0) {
        where.append(Strings.DB_AND).append(selection);
      } else {
        where.append(selection);
      }
    }
    
    int count = database.update(table, values, where.toString(), selectionArgs);
    
    if (table == TABLE_FEEDS && (values.containsKey(FeedData.FeedColumns.NAME) || values.containsKey(FeedData.FeedColumns.URL) || values.containsKey(FeedData.FeedColumns.PRIORITY))) { // == is ok here
      OPML.exportToFile(BACKUPOPML, database);
    }
    if (count > 0) {
      getContext().getContentResolver().notifyChange(uri, null);
    }
    return count;
  }

}




Java Source Code List

de.shandschuh.sparserss.Animations.java
de.shandschuh.sparserss.ApplicationPreferencesActivity.java
de.shandschuh.sparserss.BASE64.java
de.shandschuh.sparserss.BootCompletedBroadcastReceiver.java
de.shandschuh.sparserss.CompatibilityHelper.java
de.shandschuh.sparserss.EmptyActivity.java
de.shandschuh.sparserss.EntriesListActivity.java
de.shandschuh.sparserss.EntriesListAdapter.java
de.shandschuh.sparserss.EntryActivity.java
de.shandschuh.sparserss.FeedConfigActivity.java
de.shandschuh.sparserss.FeedPrefsActivity.java
de.shandschuh.sparserss.MainTabActivity.java
de.shandschuh.sparserss.RSSOverviewListAdapter.java
de.shandschuh.sparserss.RSSOverview.java
de.shandschuh.sparserss.RefreshBroadcastReceiver.java
de.shandschuh.sparserss.SimpleTask.java
de.shandschuh.sparserss.Strings.java
de.shandschuh.sparserss.handler.PictureFilenameFilter.java
de.shandschuh.sparserss.handler.RSSHandler.java
de.shandschuh.sparserss.provider.FeedDataContentProvider.java
de.shandschuh.sparserss.provider.FeedData.java
de.shandschuh.sparserss.provider.OPML.java
de.shandschuh.sparserss.service.FetcherService.java
de.shandschuh.sparserss.service.RefreshService.java
de.shandschuh.sparserss.widget.ColorPickerDialogPreference.java
de.shandschuh.sparserss.widget.SparseRSSAppWidgetProvider.java
de.shandschuh.sparserss.widget.WidgetConfigActivity.java