提问人:Hefaz 提问时间:1/29/2022 最后编辑:Hefaz 更新时间:1/31/2022 访问量:281
如何在Android中将RSS提要数据保存到SQLite中?
How to save RSS feed data into SQLite in Android?
问:
我能够在android studio中成功解析RSS提要,但我想将解析后的数据保存到数据库中,因此如果我离线,我仍然能够从保存的数据中检索。
这是我的MainActivity
package com.jjurrius.simplerssvideo;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ListView lvRss;
ArrayList<String> titles;
ArrayList<String> links;
private DatabaseHandler db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvRss = (ListView) findViewById(R.id.lvRss);
titles = new ArrayList<String>();
links = new ArrayList<String>();
db = new DatabaseHandler(this);
try {
db.open();
NewsInformation item = new NewsInformation();
item.completeTextLink = "Your Link of news";
item.title = "title of news";
item.writerName = "writer of news";
item.dateWriten = "1999";
item.source = "something";
item.smallBody = "news body";
item.bigBody = "news text";
item.page = "1";
db.insertNewsInfo(item);
db.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
lvRss.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Uri uri = Uri.parse(links.get(position));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
new ProcessInBackground().execute();
}
public InputStream getInputStream(URL url)
{
try
{
return url.openConnection().getInputStream();
}
catch (IOException e)
{
return null;
}
}
public class ProcessInBackground extends AsyncTask<Integer, Void, Exception>
{
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
Exception exception = null;
@Override
protected void onPreExecute() {
progressDialog.setMessage("Fetching Latest News!");
progressDialog.show();
}
@Override
protected Exception doInBackground(Integer... integers) {
try
{
// rss feed site here
URL url = new URL("https://moxie.foxnews.com/feedburner/world.xml");
// factory new instance
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(getInputStream(url),"UTF_8");
boolean insideItem = false;
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
if(eventType == XmlPullParser.START_TAG)
{
if(xpp.getName().equalsIgnoreCase("item"))
{
insideItem = true;
}
else if (xpp.getName().equalsIgnoreCase("title"))
{
if(insideItem)
{
titles.add(xpp.nextText());
}
}
}
else if(eventType == XmlPullParser.START_TAG && xpp.getName().equalsIgnoreCase("item"))
{
insideItem = false;
}
eventType = xpp.next();
}
}
catch (MalformedURLException e)
{
exception = e;
}
catch (XmlPullParserException e)
{
exception = e;
}
catch (IOException e)
{
exception = e;
}
return null;
}
@Override
protected void onPostExecute(Exception s) {
super.onPostExecute(s);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,titles);
lvRss.setAdapter(adapter);
progressDialog.dismiss();
}
}
}
我NewsInformation.java
package com.jjurrius.simplerssvideo;
public class NewsInformation
{
public String completeTextLink;
public String title;
public String writerName;
public String dateWriten;
public String source;
public String smallBody;
public String bigBody;
public String page;
}
我DabaseHelper.java
package com.jjurrius.simplerssvideo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
private final String TAG = "DatabaseHelper";
private static final String DATABASE_NAME = "db_for_news";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 10);
//fdd
Log.i(TAG, "Object created.");
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE news ( page TEXT ," +
" completeTextLink TEXT ,title TEXT , writerName TEXT , dateWriten TEXT ," +
" source TEXT , smallBody TEXT , bigBody TEXT);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(DatabaseHelper.class.getName(), "Upgrading database from version "
+ oldVersion + " to " + newVersion + ", which will destroy all old data");
db.execSQL("Drop table if exists news" );
onCreate(db);
}
}
我DatabaseHandler.java
package com.jjurrius.simplerssvideo;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class DatabaseHandler {
private DatabaseHelper dbHelper;
private SQLiteDatabase database;
public DatabaseHandler(Context context) {
dbHelper = new DatabaseHelper(context);
}
//methods for all table
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public void clearTable(String tableName) {
database.delete( tableName, null, null);
}
//news table method
public void insertNewsInfo(NewsInformation newsInfo) {
ContentValues cv = new ContentValues();
cv.put("bigBody" , newsInfo.bigBody );
cv.put("completeTextLink" , newsInfo.completeTextLink );
cv.put("dateWriten" , newsInfo.dateWriten );
cv.put("source" , newsInfo.source );
cv.put("smallBody" , newsInfo.smallBody );
cv.put("title" , newsInfo.title );
cv.put("writerName" , newsInfo.writerName );
cv.put("page" , newsInfo.page );
database.insert("news" , "writerName", cv);
}
public List<NewsInformation> getAllNewsForPage(String page) {
List<NewsInformation> NewsInfoList = new ArrayList<NewsInformation>();
Cursor cursor = database.rawQuery("select completeTextLink " +
" , title , writerName , dateWriten , source , smallBody , bigBody" +
" FROM news where page = ?", new String[]{page});
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
NewsInformation newsInfo = new NewsInformation();
newsInfo.completeTextLink = cursor.getString(0);
newsInfo.title = cursor.getString(1);
newsInfo.writerName = cursor.getString(2);
newsInfo.dateWriten = cursor.getString(3);
newsInfo.source = cursor.getString(4);
newsInfo.smallBody = cursor.getString(5);
newsInfo.bigBody = cursor.getString(6);
newsInfo.page = page;
NewsInfoList.add(newsInfo);
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return NewsInfoList;
}
public String getBigBody(String completeBodyLink) {
Cursor cursor = database.rawQuery("select bigBody FROM news where completeTextLink = ?", new String[]{completeBodyLink});
cursor.moveToFirst();
String bigBody = cursor.getString(0);
cursor.close();
return bigBody;
}
}
当我运行该应用程序时,它会向我显示 rss 提要,但我无法保存它们。我不知道错误在哪里。
这是我的 github 存储库:SimpleRssFeed
答:
1赞
soheil ghanbari
1/29/2022
#1
你好,我的朋友;我已经更改了您的代码,为了更好地理解,我使用了 Document,Element,NodeList 对象来获取 Rss。 在 doInBackground 方法中,我们获取 rss 中的所有必填字段并创建 NewsInformation 对象,最后我们获取 NewsInformation 列表,并在 onPostExecute 方法中将它们添加到 DB 和 Listview 适配器中, 这是我对你的代码所做的更改:
您的数据对象
public class NewsInformation
{
public String link;
public String title;
public String pubdate;
public String category;
}
以及您的活动:
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
public class RssReader extends AppCompatActivity {
ListView lvRss;
ArrayList<String> titles;
ArrayList<String> links;
ArrayList<NewsInformation> news =new ArrayList<>();
private DatabaseHandler db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rss_reader);
lvRss = (ListView) findViewById(R.id.lvRss);
titles = new ArrayList<String>();
links = new ArrayList<String>();
db = new DatabaseHandler(this);
lvRss.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Uri uri = Uri.parse(links.get(position));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
new ProcessInBackground().execute();
}
public InputStream getInputStream(URL url) {
try {
return url.openConnection().getInputStream();
} catch (IOException e) {
return null;
}
}
public class ProcessInBackground extends AsyncTask<Integer, Void, Exception> {
ProgressDialog progressDialog = new ProgressDialog(RssReader.this);
Exception exception = null;
@Override
protected void onPreExecute() {
progressDialog.setMessage("Fetching Latest News!");
progressDialog.show();
}
@Override
protected Exception doInBackground(Integer... integers) {
try {
// rss feed site here
URL url = new URL("https://moxie.foxnews.com/feedburner/world.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(getInputStream(url));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
Log.e("node size:", String.valueOf(nodeList.getLength()));
//// fetch every node item in RSS and create news_item list
for (int i = 0; i < nodeList.getLength(); i++) {
NewsInformation news_item = new NewsInformation();
Node node = nodeList.item(i);
Element parentItem = (Element) node;
NodeList links = parentItem.getElementsByTagName("link");
Element element_link = (Element) links.item(0);
NodeList element_link_childNodes = element_link.getChildNodes();
news_item.link = element_link_childNodes.item(0).getNodeValue();
NodeList titles = parentItem.getElementsByTagName("title");
Element element_title = (Element) titles.item(0);
NodeList element_title_childNodes = element_title.getChildNodes();
news_item.title = element_title_childNodes.item(0).getNodeValue();
NodeList pubDates = parentItem.getElementsByTagName("pubDate");
Element element_pubDate = (Element) pubDates.item(0);
NodeList element_pubDate_childNodes = element_pubDate.getChildNodes();
news_item.pubdate = element_pubDate_childNodes.item(0).getNodeValue();
NodeList categorys = parentItem.getElementsByTagName("pubDate");
Element element_category = (Element) categorys.item(0);
NodeList element_category_childNodes = element_category.getChildNodes();
news_item.category = element_category_childNodes.item(0).getNodeValue();
news.add(news_item);
//////////////////////////////////////////////////////////////////////////////////////////////
}
} catch (MalformedURLException e) {
exception = e;
Log.e("nerror1:", String.valueOf(e));
} catch (IOException e) {
exception = e;
Log.e("nerror2:", String.valueOf(e));
} catch (ParserConfigurationException e) {
e.printStackTrace();
Log.e("nerror3:", String.valueOf(e));
} catch (SAXException e) {
e.printStackTrace();
Log.e("nerror4:", String.valueOf(e));
}
return null;
}
@Override
protected void onPostExecute(Exception s) {
super.onPostExecute(s);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(RssReader.this, android.R.layout.simple_list_item_1, titles);
lvRss.setAdapter(adapter);
//////////// after fetching data insert to db///////////////////////////////////////////
try {
db.open();
for (int i = 0; i < news.size(); ++i) {
db.insertNewsInfo(news.get(i));
}
db.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
/////////////////////////////////////////////////////////////////////////////
progressDialog.dismiss();
}
}
}
作为建议,我建议您:
使用协程库而不是 AsyncTask 类(阅读协程)
对于 HTTP/HTTPS 请求,请使用 Retrofit 库
使用 Room 而不是 dataBaseHandler
评论
0赞
Hefaz
1/29/2022
什么是rss_reader布局?我应该创建一个吗?
0赞
soheil ghanbari
1/29/2022
不,那是你的xml布局发生了变化,只是更改了文件名
0赞
Hefaz
1/29/2022
好的,让我试试。第一次尝试没有成功。RssReader 是 MainActivity 吗?你有回购什么的吗?
0赞
soheil ghanbari
1/29/2022
是的,这是mainactivity尝试,然后给我分数:))搜索关键字有很多关于它们的文档,官方网站android也可以
0赞
Hefaz
1/29/2022
你测试过代码吗?它是否在您当地的环境中工作?
下一个:如何解析xml字符串?
评论