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.
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