• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps NEED URGENT HELP [WILLING TO PAY FOR SOLUTION]

I have a very urgent problem that I need fixed by 26th.

I need to grasp a RSS from 2 specified sites.

http://loja.publico.pt/rss.php?type=rss
http://feeds.tsf.pt/TSF-Ultimas

I have tried for hours and hours, finding various "projects"and tried to adapt them to my websites and it always ends up in a GENERAL Crash.

I have a template of a working RSS feed app however editing all links to the websites above just makes my app Crash.

I will reward the person that finds a solution for me. I need the URGENTLY.

https://drive.google.com/file/d/0BwQRuHCmWXorZ2NROWdPR3F0a28/view?usp=sharing
 
What I want it to do is basicly get Title and Link from the RSS present list it on a View.
When clicked open the link with In-Built Browser.

The problem being I'm having issues being able to grab information from any website that isn't the one the one that the code template was initially built for.

This is the working and final result of the Template (Working edition), which is for which the template was created for.
aefca0c86eda87f5f8fcbf344788a3b5.png



So I have these Classes taking care of that.

Feeds.db
Code:
package com.example.fiox.exercicio22;

import android.provider.BaseColumns;

public class FeedsDB {
    // Nome da base de dados
    public static final String DB_NAME = "jogo.db";
    //versão da base de dados
    public static final int DB_VERSION = 1;
    //Esta classe não deve ser instanciada
    private FeedsDB() {
    }
    // Definição da tabela posts
    public static final class Posts implements BaseColumns {
        // Esta classe não deve ser instanciada
        private Posts() {
        }
        // ordem por defeito
        public static final String DEFAULT_SORT_ORDER = "_ID DESC";
        // Simplificação dos nomes de campos e tabela de constantes para
// facilitar alterações na estrutura interna da BD
        public static final String NOME_TABELA = "feeds";
        public static final String _ID = "_id";
        public static final String TITLE = "title";
        public static final String LINK = "link";
        public static final String COMMENTS = "comments";
        public static final String PUB_DATE = "pub_date";
        public static final String CREATOR = "creator";
        public static final String DESCRIPTION = "description";
        public static final String FRASE = "frase";
        public static final String _COUNT = "8";
    }
}


FeedsProvider.java
Code:
package com.example.fiox.exercicio22;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.example.fiox.exercicio22.FeedsDB.Posts;

public class FeedsProvider extends ContentProvider {
    public static final Uri CONTENT_URI = Uri.parse("content://blog.masterd.pt");
    private static final int POST = 1;
    private static final int POST_ID = 2;
    private static final UriMatcher uriMatcher;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("blog.masterd.pt", "post", POST);
        uriMatcher.addURI("blog.masterd.pt", "post/#", POST_ID);
    }
    private SQLiteDatabase feedsDB;
    @Override
    public boolean onCreate() {
        Context context = getContext();
        FeedsSQLHelper dbHelper = new FeedsSQLHelper(context);
        feedsDB = dbHelper.getWritableDatabase();
        return (feedsDB == null) ? false : true;
    }
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
// para conjunto de posts
            case POST:
                return "vnd.android.cursor.dir/vnd.masterd.post";
// para um único post
            case POST_ID:
                return "vnd.android.cursor.item/vnd.masterd.post";
            default:
                throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = feedsDB.replace(Posts.NOME_TABELA, "", values);
// se tudo correu bem devolvemos o Uri
        if (rowID > 0) {
            Uri baseUri = Uri.parse("content://blog.masterd.pt/post");
            Uri _uri = ContentUris.withAppendedId(baseUri, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            getContext().getContentResolver().notifyChange(baseUri, null);
            return _uri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }
    @Override
    public int delete(Uri uri, String where, String[] whereargs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case POST:
                count = feedsDB.delete(Posts.NOME_TABELA, where, whereargs);
                break;
            case POST_ID:
                String id = uri.getPathSegments().get(1);
                count = feedsDB.delete(Posts.NOME_TABELA,
                        Posts._ID
                                + " = "
                                + id
                                + (!TextUtils.isEmpty(where) ? " AND (" + where
                                + ')' : ""), whereargs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case POST:
                count = feedsDB.update(Posts.NOME_TABELA, values, selection,
                        selectionArgs);
                break;
            case POST_ID:
                count = feedsDB.update(Posts.NOME_TABELA, values,
                        Posts._ID
                                + " = "
                                + uri.getPathSegments().get(1)
                                + (!TextUtils.isEmpty(selection) ? " AND ("
                                + selection + ')' : ""), selectionArgs);
                break;
            default:throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
        sqlBuilder.setTables(Posts.NOME_TABELA);
        Log.d("TAG", "Entrei no Cursor_Query: " + uriMatcher.match(uri));
        if (uriMatcher.match(uri) == POST_ID) {
            Log.d("TAG", "Entrei no POST_ID");
            sqlBuilder.appendWhere(Posts._ID + " = "
                    + uri.getPathSegments().get(1));
        }
        if (sortOrder == null || sortOrder == "") {
            sortOrder = Posts.DEFAULT_SORT_ORDER;
        }
        Cursor c = sqlBuilder.query(feedsDB, projection, selection,
                selectionArgs, null, null, sortOrder);
// Registamos as alterações para que
// os nossos observers entrem
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }
}

FeedsSQLHelper.java
Code:
package com.example.fiox.exercicio22;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class FeedsSQLHelper extends SQLiteOpenHelper {
    /**
     * Construtor
     *
     * @param context
     */
    public FeedsSQLHelper(Context context) {
        super(context, FeedsDB.DB_NAME, null, FeedsDB.DB_VERSION);
    }
    /**
     * Criação da base de dados
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        if (db.isReadOnly()) {
            db = getWritableDatabase();
        }db.execSQL("CREATE TABLE " + FeedsDB.Posts.NOME_TABELA + " ("
                        + FeedsDB.Posts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                        + FeedsDB.Posts.TITLE + " TEXT," + FeedsDB.Posts.LINK
                        + " TEXT UNIQUE," + FeedsDB.Posts.COMMENTS + " TEXT,"
                        + FeedsDB.Posts.PUB_DATE + " INTEGER" + FeedsDB.Posts.CREATOR
                        + " TEXT, " + FeedsDB.Posts.DESCRIPTION + " TEXT," + FeedsDB.Posts.FRASE + " TEXT"+ ")");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// não precisa de fazer nada
    }
}

MasterDApplication.Java
Code:
package com.example.fiox.exercicio22;

import android.app.Application;

/**
* Created by FioX on 11/30/2015.
*/
public class MasterdApplication extends Application {
    public String getRssUrl() {return "http://blog.masterd.pt/index.php/feed";}
}

NoticiaActivity.java
Code:
package com.example.fiox.exercicio22;

import android.app.Activity;
import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.TextView;

import com.example.fiox.exercicio22.FeedsDB.Posts;

public class NoticiaActivity extends Activity {
    private TextView titulo;
    private TextView data;
    private WebView conteudo;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.noticia);
        setTitle(R.string.titulo_noticias);
        titulo = (TextView) findViewById(R.id.feedTitulo);
// Ao premir o título a janela será encerrada
        titulo.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        data = (TextView) findViewById(R.id.feedData);
        conteudo = (WebView) findViewById(R.id.feedConteudo);
// para forçar o redimensionamento da página
        conteudo.getSettings().setLoadWithOverviewMode(true);
        conteudo.getSettings().setUseWideViewPort(true);
    }
    @SuppressWarnings("deprecation")
    @Override
    protected void onStart() {
        super.onStart();
        try {
            Bundle extras = getIntent().getExtras();
            long idNoticia = extras.getLong("idNoticia");
            final String[] columnas = new String[] { Posts._ID, // 0
                    Posts.TITLE, // 1
                    Posts.PUB_DATE, // 2
                    Posts.LINK // 3
            };
            Uri uri = FeedsProvider.CONTENT_URI;
            uri = ContentUris.withAppendedId(uri, idNoticia);
            Log.d("uri",""+uri);
// Query "managed": A atividade fica encarregada de fechar e voltar a
// carregar o cursor quando for necessario
            Cursor cursor = managedQuery(uri, columnas, null, null, Posts.PUB_DATE + " DESC");
// Queremos entrar sem alterar os dados para recarregar o cursor
            cursor.setNotificationUri(getContentResolver(), uri);
// Para que a atividade se encarregue de manusear o cursor
// segundo os seus ciclos de vida
            startManagingCursor(cursor);
// mostramos os dados do cursor na vista
            int id= (int) idNoticia;
            if(cursor.moveToPosition(id-1)) {
                titulo.setText(cursor.getString(1));
                java.text.DateFormat dateFormat = DateFormat.getLongDateFormat(NoticiaActivity.this);
                data.setText(dateFormat.format(cursor.getLong(2)));
                String texto = new String(cursor.getString(3).getBytes(),"utf-8");
                String link= cursor.getString(3);
                conteudo.loadUrl(link);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

RssDownloadHelper.java
Code:
package com.example.fiox.exercicio22;

import android.content.ContentResolver;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import java.net.URL;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class RssDownloadHelper {
    public static void updateRssData(String rssUrl, ContentResolver contentResolver) {
        try {
            URL url = new URL(rssUrl);
// Obtemos o SAXParser
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser saxParser = spf.newSAXParser();
// Criamos o Handler
            RssHandler rssHandler = new RssHandler(contentResolver);
//RssHandler rssHandler = new RssHandler();
// Definimos o manuseador léxico
            saxParser.setProperty ("http://xml.org/sax/properties/lexical-handler", rssHandler);
// Obtemos o Reader
            XMLReader xr = saxParser.getXMLReader();
            xr.setContentHandler(rssHandler);
// Analisamos o conteúdo
            InputSource is = new InputSource(url.openStream());
            is.setEncoding("utf-8");
            xr.parse(is);
// A análise foi concluída
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

RssHandler.java
Code:
package com.example.fiox.exercicio22;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.util.Log;

import com.example.fiox.exercicio22.FeedsDB.Posts;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;

import java.util.Date;

public class RssHandler extends DefaultHandler implements LexicalHandler {
    // Onde iremos armazenando os dados do registo a guardar
    ContentValues rssItem;
    // Flags para saber em que nó estamos
    private boolean in_item = false;
    private boolean in_title = false;
    private boolean in_link = false;
    @SuppressWarnings("unused")
    private boolean in_comments = false;
    private boolean in_pubDate = false;
    @SuppressWarnings("unused")
    private boolean in_dcCreator = false;
    private boolean in_description = false;
    @SuppressWarnings("unused")
    private boolean in_CDATA;
    // Dados do fornecedor de conteúdos
    private ContentResolver contentProv;
    private static final String AUTORITIES = "blog.masterd.pt";
    Uri uri = Uri.parse("content://" + AUTORITIES + "/" +Posts.NOME_TABELA);
    public RssHandler(ContentResolver contentResolver){
        contentProv = contentResolver;
    }
    public RssHandler() {
// TODO Auto-generated constructor stub
    }
    @Override
    public void startElement(String namespaceURI, String localName, String qName, Attributes
            atts) throws SAXException {
// Vamo-nos centrar apenas nos itens
        if(localName.equalsIgnoreCase("item")) {
            in_item = true;
            rssItem = new ContentValues();
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.TITLE)) {
            in_title = true;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.LINK)) {
            in_link = true;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.COMMENTS)) {
            in_comments = true;
        }
        else if(localName.equalsIgnoreCase("pubDate")) {
            in_pubDate = true;
        }
        else if(localName.equalsIgnoreCase("dc:creator")) {
            in_dcCreator = true;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.DESCRIPTION)) {
            in_description = true;
        }
    }
    @Override
    public void endElement(String namespaceURI, String localName, String qName) throws
            SAXException {
        if(localName.equalsIgnoreCase("item")) {
            contentProv.insert(uri, rssItem);
            rssItem = new ContentValues();
            in_item = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.TITLE)) {
            in_title = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.LINK)) {
            in_link = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.COMMENTS)) {
            in_comments = false;
        }
        else if(localName.equalsIgnoreCase("pubDate")) {
            in_pubDate = false;
        }else if(localName.equalsIgnoreCase("dc:creator")) {
            in_dcCreator = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.DESCRIPTION)) {
            in_description = false;
        }
    }
    @Override
    public void characters(char ch[], int start, int length) {
        if (in_item) { // Estamos dentro de um item
            if (in_title) {
                rssItem.put(FeedsDB.Posts.TITLE, new String (ch, start, length));
            }
            else if (in_link) {
                rssItem.put(FeedsDB.Posts.LINK, new String (ch, start, length));
            }
            else if (in_description) {
                rssItem.put(FeedsDB.Posts.DESCRIPTION, new String(ch, start,length));
                String frase = rssItem.get(FeedsDB.Posts.DESCRIPTION).toString();
                int fim1 = frase.indexOf(". ")+1;
                int fim2 = frase.indexOf(", ")+1;
                if(fim1<fim2)
                    rssItem.put(FeedsDB.Posts.FRASE, frase.substring(0, fim2));
                else
                    rssItem.put(FeedsDB.Posts.FRASE, frase.substring(0, fim1));
            }
            else if (in_pubDate) {
                String strDate = new String(ch, start, length);
                Log.d("My debug data", strDate);
                try {
                    @SuppressWarnings("deprecation")
                    long data = Date.parse(strDate);
                    rssItem.put(FeedsDB.Posts.PUB_DATE, data);
                }
                catch (Exception e) {
                    Log.d("RssHandler", "Erro na análise da data");
                }
            }
        }
    }
    @Override
    public void comment(char[] ch, int start, int length) throws SAXException {}
    @Override
    public void endCDATA() throws SAXException {}
    @Override
    public void endDTD() throws SAXException {}
    @Override
    public void endEntity(String name) throws SAXException {}
    @Override
    public void startCDATA() throws SAXException {}
    @Override
    public void startDTD(String name, String publicId, String systemId) throws SAXException
    {}
    @Override
    public void startEntity(String name) throws SAXException {}
}

Titulos.java
Code:
package com.example.fiox.exercicio22;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorAdapter.ViewBinder;
import android.widget.TextView;

import com.example.fiox.exercicio22.FeedsDB.Posts;

public class Titulos extends ListActivity {
    private static final long FREQUENCIA_ATUALIZACAO = 60*60*1000; // recarrega a cadahora
    private static final int DIALOG_ABOUT = 0;
    private AtualizarPostAsyncTask tarefa;
    ListView lvFeeds;
    SimpleCursorAdapter adapter;
    int[] camposView;
    String[] camposDb;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_PROGRESS);
        setContentView(R.layout.feeds);
        setTitle(R.string.titulo_noticias);
        configurarAdapter();
    }
    @Override
    public void onResume() {
        super.onResume();
        carregarNoticias();
    }
    @SuppressWarnings("deprecation")
    public void configurarAdapter() {
// Obtemos todos os artigos da BD
        final String[] colunas = new String[] { Posts._ID, // 0
                Posts.TITLE, // 1
                Posts.FRASE, // 2
                Posts.PUB_DATE, // 3
        };
        Uri uri = Uri.parse("content://blog.masterd.pt/post");
        Cursor cursor = managedQuery(uri, colunas, null, null, Posts.PUB_DATE + " DESC");
// Queremos saber se alteram dados para
// recarregar -o cursor
        cursor.setNotificationUri(getContentResolver(), uri);
// Para que a atividade se encarregue de manusear o cursor
// conforme os seus ciclos de vida
        startManagingCursor(cursor);
// Mapeamos as querys SQL para os campos das vistas
        String[] camposDb = new String[] { Posts.TITLE, Posts.FRASE,
                Posts.PUB_DATE };
        int[] camposView = new int[] { R.id.feedTitulo,R.id.feedFrase, R.id.feedData };
// Criamos o adapter
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                R.layout.feeds_item, cursor, camposDb, camposView);
// A data deve ser formatada
        final java.text.DateFormat dateFormat = DateFormat
                .getLongDateFormat(Titulos.this);
        adapter.setViewBinder(new ViewBinder() {
            @Override
            public boolean setViewValue(View view, Cursor cursor,int columnIndex) {
                if (view.getId() == R.id.feedData) {
                    long timestamp = cursor.getLong(columnIndex);
                    ((TextView) view).setText(dateFormat.format(timestamp));
                    return true;
                } else {
                    return false; // Que se encarregue do adapter
                }
            }
        });
// Tudo pronto, carregamos o adapter
        setListAdapter(adapter);
    }
    class AtualizarPostAsyncTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            setBarraProgressoVisivel(true);
            super.onPreExecute();
        }
        @Override
        protected Void doInBackground(Void... params) {
            MasterdApplication app = (MasterdApplication) getApplication();
            RssDownloadHelper.updateRssData(app.getRssUrl(),
                    getContentResolver());
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            SharedPreferences prefs = getPreferences(MODE_PRIVATE);
            Editor editor = prefs.edit();
            editor.putLong("ultima_atualizacao", System.currentTimeMillis());
            editor.commit();
            setBarraProgressoVisivel(false);
            finish();
        }
        @Override
        protected void onCancelled() {
            setBarraProgressoVisivel(false);
// Se cancelado, da próxima vez que arrancar deverá voltar a
// carregá-la
            SharedPreferences prefs = getPreferences(MODE_PRIVATE);
            Editor editor = prefs.edit();
            editor.putLong("ultima_atualizacao", 0);
            editor.commit();
            super.onCancelled();
        }
    }
    public void carregarNoticias() {
        SharedPreferences prefs = getPreferences(MODE_PRIVATE);
        long ultima = prefs.getLong("ultima_atualizacao", 0);
        if ((System.currentTimeMillis() - ultima) > FREQUENCIA_ATUALIZACAO) {
            tarefa = new AtualizarPostAsyncTask();
            tarefa.execute();
        }
    }
    @Override
    protected void onStop() {
// Se estiver a ser executada uma tarefa em segundo plano,
// esta é parada
        if (tarefa != null
                && !tarefa.getStatus().equals(AsyncTask.Status.FINISHED)) {
            tarefa.cancel(true);
        }
        super.onStop();
    }
    public void setBarraProgressoVisivel(boolean visible) {
        final Window window = getWindow();
        if (visible) {
            window.setFeatureInt(Window.FEATURE_PROGRESS,
                    Window.PROGRESS_VISIBILITY_ON);
            window.setFeatureInt(Window.FEATURE_PROGRESS,
                    Window.PROGRESS_INDETERMINATE_ON);
        } else {
            window.setFeatureInt(Window.FEATURE_PROGRESS,
                    Window.PROGRESS_VISIBILITY_OFF);
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menuprincipal, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menuAcercaDe:
                showDialog(DIALOG_ABOUT);
                return true;
            case R.id.menuQuit:
                finish();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_ABOUT:
                AlertDialog dialogAbout = null;
                final AlertDialog.Builder builder;
                LayoutInflater li = LayoutInflater.from(this);
                View view = li.inflate(R.layout.acercade, null);
                builder = new AlertDialog.Builder(this)
                        .setIcon(R.mipmap.ic_launcher)
                        .setTitle(getString(R.string.app_name))
                        .setPositiveButton("Ok", null).setView(view);
                dialogAbout = builder.create();
                return dialogAbout;
            default:
                return null;
        }
    }
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent i = new Intent();
        i.setClass(Titulos.this, NoticiaActivity.class);
        i.putExtra("idNoticia", id);
        startActivity(i);
    }
}


So I edited everything that had anything related to "blog.masterd.pt"(Inicial feed website) to one of the above.


All I changed was FeedsProvider.Java to this
Code:
package com.example.fiox.exercicio22;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.example.fiox.exercicio22.FeedsDB.Posts;

public class FeedsProvider extends ContentProvider {
    public static final Uri CONTENT_URI = Uri.parse("content://feeds.tsf.pt");
    private static final int POST = 1;
    private static final int POST_ID = 2;
    private static final UriMatcher uriMatcher;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("feeds.tsf.pt", "post", POST);
        uriMatcher.addURI("feeds.tsf.pt", "post/#", POST_ID);
    }
    private SQLiteDatabase feedsDB;
    @Override
    public boolean onCreate() {
        Context context = getContext();
        FeedsSQLHelper dbHelper = new FeedsSQLHelper(context);
        feedsDB = dbHelper.getWritableDatabase();
        return (feedsDB == null) ? false : true;
    }
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
// para conjunto de posts
            case POST:
                return "vnd.android.cursor.dir/vnd.feeds.tsf.post";
// para um único post
            case POST_ID:
                return "vnd.android.cursor.item/vnd.feeds.tsf.post";
            default:
                throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = feedsDB.replace(Posts.NOME_TABELA, "", values);
// se tudo correu bem devolvemos o Uri
        if (rowID > 0) {
            Uri baseUri = Uri.parse("content://feeds.tsf.pt/post");
            Uri _uri = ContentUris.withAppendedId(baseUri, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            getContext().getContentResolver().notifyChange(baseUri, null);
            return _uri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }
    @Override
    public int delete(Uri uri, String where, String[] whereargs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case POST:
                count = feedsDB.delete(Posts.NOME_TABELA, where, whereargs);
                break;
            case POST_ID:
                String id = uri.getPathSegments().get(1);
                count = feedsDB.delete(Posts.NOME_TABELA,
                        Posts._ID
                                + " = "
                                + id
                                + (!TextUtils.isEmpty(where) ? " AND (" + where
                                + ')' : ""), whereargs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case POST:
                count = feedsDB.update(Posts.NOME_TABELA, values, selection,
                        selectionArgs);
                break;
            case POST_ID:
                count = feedsDB.update(Posts.NOME_TABELA, values,
                        Posts._ID
                                + " = "
                                + uri.getPathSegments().get(1)
                                + (!TextUtils.isEmpty(selection) ? " AND ("
                                + selection + ')' : ""), selectionArgs);
                break;
            default:throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
        sqlBuilder.setTables(Posts.NOME_TABELA);
        Log.d("TAG", "Entrei no Cursor_Query: " + uriMatcher.match(uri));
        if (uriMatcher.match(uri) == POST_ID) {
            Log.d("TAG", "Entrei no POST_ID");
            sqlBuilder.appendWhere(Posts._ID + " = "
                    + uri.getPathSegments().get(1));
        }
        if (sortOrder == null || sortOrder == "") {
            sortOrder = Posts.DEFAULT_SORT_ORDER;
        }
        Cursor c = sqlBuilder.query(feedsDB, projection, selection,
                selectionArgs, null, null, sortOrder);
// Registamos as alterações para que
// os nossos observers entrem
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }
}

MasterDApplication.java

[code
package com.example.fiox.exercicio22;

import android.app.Application;

/**
* Created by FioX on 11/30/2015.
*/
public class MasterdApplication extends Application {
public String getRssUrl() {return "http://feeds.tsf.pt/TSF-Ultimas";}
}[/code]

and RSS Handler.java
Code:
package com.example.fiox.exercicio22;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.util.Log;

import com.example.fiox.exercicio22.FeedsDB.Posts;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;

import java.util.Date;

public class RssHandler extends DefaultHandler implements LexicalHandler {
    // Onde iremos armazenando os dados do registo a guardar
    ContentValues rssItem;
    // Flags para saber em que nó estamos
    private boolean in_item = false;
    private boolean in_title = false;
    private boolean in_link = false;
    @SuppressWarnings("unused")
    private boolean in_comments = false;
    private boolean in_pubDate = false;
    @SuppressWarnings("unused")
    private boolean in_dcCreator = false;
    private boolean in_description = false;
    @SuppressWarnings("unused")
    private boolean in_CDATA;
    // Dados do fornecedor de conteúdos
    private ContentResolver contentProv;
    private static final String AUTORITIES = "http://feeds.tsf.pt/";
    Uri uri = Uri.parse("content://" + AUTORITIES + "/" +Posts.NOME_TABELA);
    public RssHandler(ContentResolver contentResolver){
        contentProv = contentResolver;
    }
    public RssHandler() {
// TODO Auto-generated constructor stub
    }
    @Override
    public void startElement(String namespaceURI, String localName, String qName, Attributes
            atts) throws SAXException {
// Vamo-nos centrar apenas nos itens
        if(localName.equalsIgnoreCase("item")) {
            in_item = true;
            rssItem = new ContentValues();
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.TITLE)) {
            in_title = true;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.LINK)) {
            in_link = true;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.COMMENTS)) {
            in_comments = true;
        }
        else if(localName.equalsIgnoreCase("pubDate")) {
            in_pubDate = true;
        }
        else if(localName.equalsIgnoreCase("dc:creator")) {
            in_dcCreator = true;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.DESCRIPTION)) {
            in_description = true;
        }
    }
    @Override
    public void endElement(String namespaceURI, String localName, String qName) throws
            SAXException {
        if(localName.equalsIgnoreCase("item")) {
            contentProv.insert(uri, rssItem);
            rssItem = new ContentValues();
            in_item = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.TITLE)) {
            in_title = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.LINK)) {
            in_link = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.COMMENTS)) {
            in_comments = false;
        }
        else if(localName.equalsIgnoreCase("pubDate")) {
            in_pubDate = false;
        }else if(localName.equalsIgnoreCase("dc:creator")) {
            in_dcCreator = false;
        }
        else if(localName.equalsIgnoreCase(FeedsDB.Posts.DESCRIPTION)) {
            in_description = false;
        }
    }
    @Override
    public void characters(char ch[], int start, int length) {
        if (in_item) { // Estamos dentro de um item
            if (in_title) {
                rssItem.put(FeedsDB.Posts.TITLE, new String (ch, start, length));
            }
            else if (in_link) {
                rssItem.put(FeedsDB.Posts.LINK, new String (ch, start, length));
            }
            else if (in_description) {
                rssItem.put(FeedsDB.Posts.DESCRIPTION, new String(ch, start,length));
                String frase = rssItem.get(FeedsDB.Posts.DESCRIPTION).toString();
                int fim1 = frase.indexOf(". ")+1;
                int fim2 = frase.indexOf(", ")+1;
                if(fim1<fim2)
                    rssItem.put(FeedsDB.Posts.FRASE, frase.substring(0, fim2));
                else
                    rssItem.put(FeedsDB.Posts.FRASE, frase.substring(0, fim1));
            }
            else if (in_pubDate) {
                String strDate = new String(ch, start, length);
                Log.d("My debug data", strDate);
                try {
                    @SuppressWarnings("deprecation")
                    long data = Date.parse(strDate);
                    rssItem.put(FeedsDB.Posts.PUB_DATE, data);
                }
                catch (Exception e) {
                    Log.d("RssHandler", "Erro na análise da data");
                }
            }
        }
    }
    @Override
    public void comment(char[] ch, int start, int length) throws SAXException {}
    @Override
    public void endCDATA() throws SAXException {}
    @Override
    public void endDTD() throws SAXException {}
    @Override
    public void endEntity(String name) throws SAXException {}
    @Override
    public void startCDATA() throws SAXException {}
    @Override
    public void startDTD(String name, String publicId, String systemId) throws SAXException
    {}
    @Override
    public void startEntity(String name) throws SAXException {}
}


The error giving:
12-24 06:32:09.780 1619-1619/com.example.fiox.exercicio22 E/ActivityThread: Failed to find provider info for feeds.tsf.pt
12-24 06:32:09.780 1619-1619/com.example.fiox.exercicio22 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.fiox.exercicio22, PID: 1619
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fiox.exercicio22/com.example.fiox.exercicio22.Titulos}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.fiox.exercicio22.Titulos.configurarAdapter(Titulos.java:60)
at com.example.fiox.exercicio22.Titulos.onCreate(Titulos.java:41)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
12-24 06:32:22.010 1619-1619/? I/Process: Sending signal. PID: 1619 SIG: 9
 
Well since that part of the coding was untoched (only website was changed) I asume that means there's a problem with the Link/Feed I provided?
 
Yes, URI is not null. Or at least shouldn't be.

public static final Uri CONTENT_URI = Uri.parse("content://feeds.tsf.pt");
private static final int POST = 1;
private static final int POST_ID = 2;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("feeds.tsf.pt", "post", POST);
uriMatcher.addURI("feeds.tsf.pt", "post/#", POST_ID);
}
 
Did you set a breakpoint at line 60 and verify that it isn't null?
 
Damn I have exact same problem with exact same code even... Would anyone be able to help me if I would post my code and my logcat? I really need help to finish this today i am on a deadline
 
So did you read and follow everything in the thread up until post #11, and what happened?
 
I am working on a app that has three feeds in a listview from three different news websites(from their own feeds) that shows the titles in listview and when you click it opens webview with the full article.

I used RSS Feed and SQL Database to do this and i coded everything as i did in another template exercise but
when I test in the emulator in eclipse once I click the icon to open the listview activity it just crashes the app and has some errors on the logcat. I really need help fixing this. I know the code is correct and the way to do this is also correct but there is just something i am missing that is just not working. I need this to work today. I am on a deadline for tonight. PLEASE HELP ME IF YOU CAN

Here's the code example of one my feeds alongside the logcat:

The FeedsDB
Java:
package com.example.casopratico2;

import android.provider.BaseColumns;

public class TSFFeedsDB {
    // Nome da base de dados
    public static final String DB_NAME = "jogo.db";
    // versão da base de dados
    public static final int DB_VERSION = 1;

    // Esta classe não deve ser instanciada
    private TSFFeedsDB() {
    }

    // Definição da tabela posts
    public static final class Posts implements BaseColumns {
        // Esta classe não deve ser instanciada
        private Posts() {
        }

        // ordem por defeito
        public static final String DEFAULT_SORT_ORDER = "_ID DESC";
        // Simplificação dos nomes de campos e tabela de constantes para
        // facilitar alterações na estrutura interna da BD
        public static final String NOME_TABELA = "feeds";
        public static final String _ID = "_id";
        public static final String TITLE = "title";
        public static final String LINK = "link";
        public static final String DESCRIPTION = "description";
        public static final String PUB_DATE = "pub_date";
        public static final String FRASE = "frase";
        public static final String _COUNT = "6";
    }
}

The FeedsProvider
Java:
package com.example.casopratico2;

import com.example.casopratico2.TSFFeedsDB.Posts;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class TSFFeedsProvider extends ContentProvider {
    public static final Uri CONTENT_URI = Uri.parse("content://feeds.tsf.pt");
    private static final int POST = 1;
    private static final int POST_ID = 2;
    private static final UriMatcher uriMatcher;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("feeds.tsf.pt", "post", POST);
        uriMatcher.addURI("feeds.tsf.pt", "post/#", POST_ID);
    }
    private SQLiteDatabase TSFfeedsDB;

    @Override
    public boolean onCreate() {
        Context context = getContext();
        TSFFeedsSQLHelper dbHelper = new TSFFeedsSQLHelper(context);
        TSFfeedsDB = dbHelper.getWritableDatabase();
        return (TSFfeedsDB == null) ? false : true;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
        // para conjunto de posts
        case POST:
            return "vnd.android.cursor.dir/vnd.tsf.post";
            // para um único post
        case POST_ID:
            return "vnd.android.cursor.item/vnd.tsf.post";
        default:
            throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = TSFfeedsDB.replace(Posts.NOME_TABELA, "", values);
        // se tudo correu bem devolvemos o Uri
        if (rowID > 0) {
            Uri baseUri = Uri.parse("content://feeds.tsf.pt/post");
            Uri _uri = ContentUris.withAppendedId(baseUri, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            getContext().getContentResolver().notifyChange(baseUri, null);
            return _uri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public int delete(Uri uri, String where, String[] whereargs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
        case POST:
            count = TSFfeedsDB.delete(Posts.NOME_TABELA, where, whereargs);
            break;
        case POST_ID:
            String id = uri.getPathSegments().get(1);
            count = TSFfeedsDB.delete(Posts.NOME_TABELA,
                    Posts._ID
                            + " = "
                            + id
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ')' : ""), whereargs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
        case POST:
            count = TSFfeedsDB.update(Posts.NOME_TABELA, values, selection,
                    selectionArgs);
            break;
        case POST_ID:
            count = TSFfeedsDB.update(Posts.NOME_TABELA, values,
                    Posts._ID
                            + " = "
                            + uri.getPathSegments().get(1)
                            + (!TextUtils.isEmpty(selection) ? " AND ("
                                    + selection + ')' : ""), selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
        sqlBuilder.setTables(Posts.NOME_TABELA);
        Log.d("TAG", "Entrei no Cursor_Query: " + uriMatcher.match(uri));
        if (uriMatcher.match(uri) == POST_ID) {
            Log.d("TAG", "Entrei no POST_ID");
            sqlBuilder.appendWhere(Posts._ID + " = "
                    + uri.getPathSegments().get(1));
        }
        if (sortOrder == null || sortOrder == "") {
            sortOrder = Posts.DEFAULT_SORT_ORDER;
        }
        Cursor c = sqlBuilder.query(TSFfeedsDB, projection, selection,
                selectionArgs, null, null, sortOrder);
        // Registamos as alterações para que
        // os nossos observers entrem
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }
}

The FeedsSQLHelper

Java:
package com.example.casopratico2;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class TSFFeedsSQLHelper extends SQLiteOpenHelper {
    /**
     * Construtor
     *
     * @param context
     */
    public TSFFeedsSQLHelper(Context context) {
        super(context, TSFFeedsDB.DB_NAME, null, TSFFeedsDB.DB_VERSION);
    }

    /**
     * Criação da base de dados
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        if (db.isReadOnly()) {
            db = getWritableDatabase();
        }
        db.execSQL("CREATE TABLE " + TSFFeedsDB.Posts.NOME_TABELA + " ("
                + TSFFeedsDB.Posts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + TSFFeedsDB.Posts.TITLE + " TEXT," + TSFFeedsDB.Posts.LINK
                + " TEXT UNIQUE," + TSFFeedsDB.Posts.DESCRIPTION + " TEXT,"
                + TSFFeedsDB.Posts.PUB_DATE + " INTEGER"
                + TSFFeedsDB.Posts.FRASE + " TEXT" + ")");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // não precisa de fazer nada
    }
}

The RSSDownloadHelper

Java:
package com.example.casopratico2;

import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.content.ContentResolver;

public class TSFRssDownloadHelper {
    public static void updateRssData(String rssUrl,
            ContentResolver contentResolver) {
        try {
            URL url = new URL(rssUrl);
            // Obtemos o SAXParser
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser saxParser = spf.newSAXParser();
            // Criamos o Handler
            TSFRssHandler rssHandler = new TSFRssHandler(contentResolver);
            // RssHandler rssHandler = new RssHandler();
            // Definimos o manuseador léxico
            saxParser
                    .setProperty(
                            "http://xml.org/sax/properties/lexical-handler",
                            rssHandler);
            // Obtemos o Reader
            XMLReader xr = saxParser.getXMLReader();
            xr.setContentHandler(rssHandler);
            // Analisamos o conteúdo
            InputSource is = new InputSource(url.openStream());
            is.setEncoding("utf-8");
            xr.parse(is);
            // A análise foi concluída
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The RSSHandler
Java:
package com.example.casopratico2;

import java.sql.Date;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
import com.example.casopratico2.TSFFeedsDB.Posts;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.util.Log;

public class TSFRssHandler extends DefaultHandler implements LexicalHandler {
    // Onde iremos armazenando os dados do registo a guardar
    ContentValues rssItem;
    // Flags para saber em que nó estamos
    private boolean in_item = false;
    private boolean in_title = false;
    private boolean in_link = false;
    @SuppressWarnings("unused")
    private boolean in_description = false;
    private boolean in_pubDate = false;

    // Dados do fornecedor de conteúdos
    private ContentResolver contentProv;
    private static final String AUTORITIES = "feeds.tsf.pt";
    Uri uri = Uri.parse("content://" + AUTORITIES + "/" + Posts.NOME_TABELA);

    public TSFRssHandler(ContentResolver contentResolver) {
        contentProv = contentResolver;
    }

    public TSFRssHandler() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public void startElement(String namespaceURI, String localName,
            String qName, Attributes atts) throws SAXException {
        // Vamo-nos centrar apenas nos itens
        if (localName.equalsIgnoreCase("item")) {
            in_item = true;
            rssItem = new ContentValues();
        } else if (localName.equalsIgnoreCase(TSFFeedsDB.Posts.TITLE)) {
            in_title = true;
        } else if (localName.equalsIgnoreCase(TSFFeedsDB.Posts.LINK)) {
            in_link = true;
        } else if (localName.equalsIgnoreCase(TSFFeedsDB.Posts.DESCRIPTION)) {
            in_description = true;
        } else if (localName.equalsIgnoreCase("pubDate")) {
            in_pubDate = true;
        }
    }

    @Override
    public void endElement(String namespaceURI, String localName, String qName)
            throws SAXException {
        if (localName.equalsIgnoreCase("item")) {
            contentProv.insert(uri, rssItem);
            rssItem = new ContentValues();
            in_item = false;
        } else if (localName.equalsIgnoreCase(TSFFeedsDB.Posts.TITLE)) {
            in_title = false;
        } else if (localName.equalsIgnoreCase(TSFFeedsDB.Posts.LINK)) {
            in_link = false;
        } else if (localName.equalsIgnoreCase("pubDate")) {
            in_pubDate = false;
        }
    }

    @Override
    public void characters(char ch[], int start, int length) {
        if (in_item) { // Estamos dentro de um item
            if (in_title) {
                rssItem.put(TSFFeedsDB.Posts.TITLE, new String(ch, start,
                        length));
            } else if (in_link) {
                rssItem.put(TSFFeedsDB.Posts.LINK,
                        new String(ch, start, length));
            } else if (in_description) {
                rssItem.put(TSFFeedsDB.Posts.DESCRIPTION, new String(ch, start,
                        length));
                String frase = rssItem.get(TSFFeedsDB.Posts.DESCRIPTION)
                        .toString();
                int fim1 = frase.indexOf(". ") + 1;
                int fim2 = frase.indexOf(", ") + 1;
                if (fim1 < fim2)
                    rssItem.put(TSFFeedsDB.Posts.FRASE,
                            frase.substring(0, fim2));
                else
                    rssItem.put(TSFFeedsDB.Posts.FRASE,
                            frase.substring(0, fim1));
            } else if (in_pubDate) {
                String strDate = new String(ch, start, length);
                Log.d("My debug data", strDate);
                try {
                    @SuppressWarnings("deprecation")
                    long data = Date.parse(strDate);
                    rssItem.put(TSFFeedsDB.Posts.PUB_DATE, data);
                } catch (Exception e) {
                    Log.d("RssHandler", "Erro na análise da data");
                }
            }
        }
    }

    @Override
    public void comment(char[] ch, int start, int length) throws SAXException {
    }

    @Override
    public void endCDATA() throws SAXException {
    }

    @Override
    public void endDTD() throws SAXException {
    }

    @Override
    public void endEntity(String name) throws SAXException {
    }

    @Override
    public void startCDATA() throws SAXException {
    }

    @Override
    public void startDTD(String name, String publicId, String systemId)
            throws SAXException {
    }

    @Override
    public void startEntity(String name) throws SAXException {
    }
}
The Application with the feed link

Java:
package com.example.casopratico2;

import android.app.Application;

public class TSFApplication extends Application {
    public String getRssUrl() {
        return "http://feeds.tsf.pt/TSF-Ultimas";
    }

}

The ListActivity with the titles
Java:
package com.example.casopratico2;

import com.example.casopratico2.TSFFeedsDB.Posts;
import android.app.ListActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter.ViewBinder;
import android.text.format.DateFormat;
import android.view.View;
import android.view.Window;
import android.widget.ListView;
import android.widget.TextView;


public class TsfTitulos extends ListActivity {
    private static final long FREQUENCIA_ATUALIZACAO = 60 * 60 * 1000; // recarrega
                                                                        // a
                                                                        // cada
                                                                        // hora

    private AtualizarPostAsyncTask tarefa;
    ListView lvFeeds;
    SimpleCursorAdapter adapter;
    int[] camposView;
    String[] camposDb;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_PROGRESS);
        setContentView(R.layout.feedstsf);
        configurarAdapter();
    }

    @Override
    public void onResume() {
        super.onResume();
        carregarNoticias();
    }

    @SuppressWarnings("deprecation")
    public void configurarAdapter() {
        // Obtemos todos os artigos da BD
        final String[] colunas = new String[] { Posts._ID, // 0
                Posts.TITLE, // 1
                Posts.DESCRIPTION, // 2
                Posts.PUB_DATE, // 3
        };
        Uri uri = Uri.parse("content://feeds.tsf.pt/post");
        Cursor cursor = managedQuery(uri, colunas, null, null, Posts.PUB_DATE
                + " DESC");
        // Queremos saber se alteram dados para
        // recarregar -o cursor
        cursor.setNotificationUri(getContentResolver(), uri);
        // Para que a atividade se encarregue de manusear o cursor
        // conforme os seus ciclos de vida
        startManagingCursor(cursor);
        // Mapeamos as querys SQL para os campos das vistas
        String[] camposDb = new String[] { Posts.TITLE, Posts.DESCRIPTION,
                Posts.PUB_DATE };
        int[] camposView = new int[] { R.id.feedTitulot, R.id.feedFraset,
                R.id.feedDatat };
        // Criamos o adapter
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                R.layout.feeds_itemtsf, cursor, camposDb, camposView);
        // A data deve ser formatada
        final java.text.DateFormat dateFormat = DateFormat
                .getLongDateFormat(TsfTitulos.this);
        adapter.setViewBinder(new ViewBinder() {
            @Override
            public boolean setViewValue(View view, Cursor cursor,
                    int columnIndex) {
                if (view.getId() == R.id.feedDatat) {
                    long timestamp = cursor.getLong(columnIndex);
                    ((TextView) view).setText(dateFormat.format(timestamp));
                    return true;
                } else {
                    return false; // Que se encarregue do adapter
                }
            }
        });
        // Tudo pronto, carregamos o adapter
        setListAdapter(adapter);
    }

    class AtualizarPostAsyncTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            setBarraProgressoVisivel(true);
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            TSFApplication app = (TSFApplication) getApplication();
            TSFRssDownloadHelper.updateRssData(app.getRssUrl(),
                    getContentResolver());
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            SharedPreferences prefs = getPreferences(MODE_PRIVATE);
            Editor editor = prefs.edit();
            editor.putLong("ultima_atualizacao", System.currentTimeMillis());
            editor.commit();
            setBarraProgressoVisivel(false);
        }

        @Override
        protected void onCancelled() {
            setBarraProgressoVisivel(false);
            // Se cancelado, da próxima vez que arrancar deverá voltar a
            // carregá-la
            SharedPreferences prefs = getPreferences(MODE_PRIVATE);
            Editor editor = prefs.edit();
            editor.putLong("ultima_atualizacao", 0);
            editor.commit();
            super.onCancelled();
        }
    }

    public void carregarNoticias() {
        SharedPreferences prefs = getPreferences(MODE_PRIVATE);
        long ultima = prefs.getLong("ultima_atualizacao", 0);
        if ((System.currentTimeMillis() - ultima) > FREQUENCIA_ATUALIZACAO) {
            tarefa = new AtualizarPostAsyncTask();
            tarefa.execute();
        }
    }

    @Override
    protected void onStop() {
        // Se estiver a ser executada uma tarefa em segundo plano,
        // esta é parada
        if (tarefa != null
                && !tarefa.getStatus().equals(AsyncTask.Status.FINISHED)) {
            tarefa.cancel(true);
        }
        super.onStop();
    }

    public void setBarraProgressoVisivel(boolean visible) {
        final Window window = getWindow();
        if (visible) {
            window.setFeatureInt(Window.FEATURE_PROGRESS,
                    Window.PROGRESS_VISIBILITY_ON);
            window.setFeatureInt(Window.FEATURE_PROGRESS,
                    Window.PROGRESS_INDETERMINATE_ON);
        } else {
            window.setFeatureInt(Window.FEATURE_PROGRESS,
                    Window.PROGRESS_VISIBILITY_OFF);
        }
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent i = new Intent();
        i.setClass(TsfTitulos.this, TsfNoticiaActivity.class);
        i.putExtra("idNoticia", id);
        startActivity(i);
    }
}

The Activity with webview for the article

Java:
package com.example.casopratico2;

import com.example.casopratico2.TSFFeedsDB.Posts;

import android.app.Activity;
import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.TextView;

public class TsfNoticiaActivity extends Activity {
    private TextView titulot;
    private TextView datat;
    private WebView conteudot;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.noticiatsf);
        titulot = (TextView) findViewById(R.id.feedTitulot);
        // Ao premir o título a janela será encerrada
        titulot.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        datat = (TextView) findViewById(R.id.feedDatat);
        conteudot = (WebView) findViewById(R.id.feedConteudot);
        // para forçar o redimensionamento da página
        conteudot.getSettings().setLoadWithOverviewMode(true);
        conteudot.getSettings().setUseWideViewPort(true);
    }

    @SuppressWarnings("deprecation")
    @Override
    protected void onStart() {
        super.onStart();
        try {
            Bundle extras = getIntent().getExtras();
            long idNoticia = extras.getLong("idNoticia");
            final String[] columnas = new String[] { Posts._ID, // 0
                    Posts.TITLE, // 1
                    Posts.PUB_DATE, // 2
                    Posts.LINK // 3
            };
            Uri uri = TSFFeedsProvider.CONTENT_URI;
            uri = ContentUris.withAppendedId(uri, idNoticia);
            Log.d("uri", "" + uri);
            // Query "managed": A atividade fica encarregada de fechar e voltar
            // a
            // carregar o cursor quando for necessario
            Cursor cursor = managedQuery(uri, columnas, null, null,
                    Posts.PUB_DATE + " DESC");
            // Queremos entrar sem alterar os dados para recarregar o cursor
            cursor.setNotificationUri(getContentResolver(), uri);
            // Para que a atividade se encarregue de manusear o cursor
            // segundo os seus ciclos de vida
            startManagingCursor(cursor);
            // mostramos os dados do cursor na vista
            int id = (int) idNoticia;
            if (cursor.moveToPosition(id - 1)) {
                titulot.setText(cursor.getString(1));
                java.text.DateFormat dateFormat = DateFormat
                        .getLongDateFormat(TsfNoticiaActivity.this);
                datat.setText(dateFormat.format(cursor.getLong(2)));
                String texto = new String(cursor.getString(3).getBytes(),
                        "utf-8");
                String link = cursor.getString(3);
                conteudot.loadUrl(link);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The androidmanifest
Java:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.casopratico2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.casopratico2.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.casopratico2.Gravador"
            android:label="Gravador" >
        </activity>
        <activity
            android:name="com.example.casopratico2.Reprodutor"
            android:label="Reprodutor" >
        </activity>
        <activity
            android:name="com.example.casopratico2.TsfTitulos"
            android:label="TsfTitulos" >
        </activity>
        <activity
            android:name="com.example.casopratico2.TsfNoticiaActivity"
            android:label="TsfNoticiaActivity" >
        </activity>
        <activity
            android:name="com.example.casopratico2.Correio"
            android:label="Correio" >
        </activity>
        <activity
            android:name="com.example.casopratico2.CTitulos"
            android:label="CTitulos" >
        </activity>
        <activity
            android:name="com.example.casopratico2.CNoticiaActivity"
            android:label="CNoticiaActivity" >
        </activity>
        <activity
            android:name="com.example.casopratico2.PTitulos"
            android:label="PTitulos" >
        </activity>
        <activity
            android:name="com.example.casopratico2.PNoticiaActivity"
            android:label="PNoticiaActivity" >
        </activity>

        <provider
            android:name="PFeedsProvider"
            android:authorities="loja.publico.pt" />
        <provider
            android:name="CFeedsProvider"
            android:authorities="www.cmjornal.xl.pt" />
        <provider
            android:name="TSFFeedsProvider"
            android:authorities="feeds.tsf.pt" />
    </application>

</manifest>
The Logcat errors:
05-23 11:48:26.522: W/dalvikvm(979): threadid=11: thread exiting with uncaught exception (group=0xb1aa7b90)
05-23 11:48:26.532: E/AndroidRuntime(979): FATAL EXCEPTION: AsyncTask #1
05-23 11:48:26.532: E/AndroidRuntime(979): Process: com.example.casopratico2, PID: 979
05-23 11:48:26.532: E/AndroidRuntime(979): java.lang.RuntimeException: An error occured while executing doInBackground()
05-23 11:48:26.532: E/AndroidRuntime(979): at android.os.AsyncTask$3.done(AsyncTask.java:300)
05-23 11:48:26.532: E/AndroidRuntime(979): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
05-23 11:48:26.532: E/AndroidRuntime(979): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
05-23 11:48:26.532: E/AndroidRuntime(979): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
05-23 11:48:26.532: E/AndroidRuntime(979): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-23 11:48:26.532: E/AndroidRuntime(979): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-23 11:48:26.532: E/AndroidRuntime(979): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-23 11:48:26.532: E/AndroidRuntime(979): at java.lang.Thread.run(Thread.java:841)
05-23 11:48:26.532: E/AndroidRuntime(979): Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.casopratico2.TSFApplication
05-23 11:48:26.532: E/AndroidRuntime(979): at com.example.casopratico2.TsfTitulos$AtualizarPostAsyncTask.doInBackground(TsfTitulos.java:101)
05-23 11:48:26.532: E/AndroidRuntime(979): at com.example.casopratico2.TsfTitulos$AtualizarPostAsyncTask.doInBackground(TsfTitulos.java:1)
05-23 11:48:26.532: E/AndroidRuntime(979): at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-23 11:48:26.532: E/AndroidRuntime(979): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-23 11:48:26.532: E/AndroidRuntime(979): ... 4 more
 
This is causing your problem

Code:
TSFApplication app =(TSFApplication) getApplication();

You're missing an attribute from your manifest declaration

Code:
<application android:name="com.example.casopratico2.TSFApplication"
  ...
 
Mhm remember I have two more news feeds as you can see in the androidmanifest that I programmed with the same code as the one i posted can i go an add to androidmanifest the two others too like
Java:
<application android:name="com.example.casopratico2.TSFApplication"
android:name="com.example.casopratico2.CorreioApplication"
android:name="com.example.casopratico2.PublicoApplication"
  ...
Could I do that?
 
It doesn't work. I dont know what could be wrong. Even with the logcat. My code seems correct. Seems I will fail this test...
 
Ok you can't have multiple application name attributes, but I would expect the single 'name' attribute to work

Code:
<application android:name="com.example.casopratico2.TSFApplication"

You are getting a ClassCastException, which means that getApplication() is returning an object of type Application, rather than your expected TSFApplication. That's because your manifest did not specify this as the specific Application class for your app.

But really, next time you should allow more time to complete your homework.
 
Back
Top Bottom