Android的从数据库中提取数据 [英] Android Pulling Data from database
本文介绍了Android的从数据库中提取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想拉数据库的历史....但是它从来没有拉任何东西...任何人都看到我在做什么错
下面是内容提供商:
包com.projectcaruso.naturalfamilyplaning;进口android.content.ContentProvider;
进口android.content.ContentUris;
进口android.content.ContentValues;
进口android.database.Cursor;
进口android.database.sqlite.SQLiteDatabase;
进口android.net.Uri;
进口android.util.Log;公共类StatusProvider扩展ContentProvider的{
私有静态最后弦乐TAG = StatusProvider.class.getSimpleName(); 公共静态最终乌里CONTENT_URI = Uri.parse(内容://com.projectcaruso.naturalfamilyplaning.statusprovider);
公共静态最后弦乐SINGLE_RECORD_MIME_TYPE =vnd.android.cursor.item / vnd.projectcaruso.naturalfamilyplaning.status
公共静态最后弦乐MULTIPLE_RECORDS_MIME_TYPE =vnd.android.cursor.dir / vnd.projectcaruso.naturalfamilyplaning.status StatusData statusData; @覆盖
公共字符串的getType(URI URI){
返回this.getId(URI)下; 0? MULTIPLE_RECORDS_MIME_TYPE
:SINGLE_RECORD_MIME_TYPE;
} @覆盖
公共布尔的onCreate(){
statusData =新StatusData(的getContext());
返回true;
} @覆盖
公共乌里插入(URI URI,ContentValues值){
SQLiteDatabase分贝= statusData.dbHelper.getWritableDatabase();
尝试{
长ID = db.insertOrThrow(StatusData.DATABASE_TABLE,空,价值);
如果(ID == -1){
抛出新的RuntimeException(的String.format(
%S:失败[%S]插入到[%S],原因不明,TAG,
值,URI));
}其他{
乌里newUri = ContentUris.withAppendedId(URI,ID);
//通知上下文的ContentResolver的变化的
。的getContext()getContentResolver()有NotifyChange(newUri,NULL);
返回newUri;
}
} {最后
db.close();
}
} @覆盖
公众诠释更新(开放的URI,ContentValues值,字符串的选择,
的String [] selectionArgs两个){
长ID = this.getId(URI);
诠释计数;
SQLiteDatabase分贝= statusData.dbHelper.getWritableDatabase();
尝试{
如果(ID℃,){
数= db.update(StatusData.DATABASE_TABLE,价值观,选择,selectionArgs两个);
}其他{
数= db.update(StatusData.DATABASE_TABLE,价值观,StatusData.KEY_ROWID +=+ ID,
空值);
}
} {最后
db.close();
} //通知上下文的ContentResolver的变化的
的getContext()getContentResolver()有NotifyChange(URI,空)。 返回计数;
} @覆盖
公众诠释删除(URI URI,选择字符串,字符串[] selectionArgs两个){
长ID = this.getId(URI);
诠释计数;
SQLiteDatabase分贝= statusData.dbHelper.getWritableDatabase();
尝试{
如果(ID℃,){
数= db.delete(StatusData.DATABASE_TABLE,选择selectionArgs两个);
}其他{
数= db.delete(StatusData.DATABASE_TABLE,StatusData.KEY_ROWID +=+ ID,NULL);
}
} {最后
db.close();
} //通知上下文的ContentResolver的变化的
的getContext()getContentResolver()有NotifyChange(URI,空)。 返回计数;
} @覆盖
公共光标查询(URI URI,字符串[]投影,字符串的选择,
的String [] selectionArgs两个,字符串中将sortOrder){
长ID = this.getId(URI);
SQLiteDatabase分贝= statusData.dbHelper.getReadableDatabase();
Log.d(TAG,查询); 光标C; 如果(ID℃,){
C = db.query(StatusData.DATABASE_TABLE,投影,选择,selectionArgs两个,
NULL,NULL,中将sortOrder);
}其他{
C = db.query(StatusData.DATABASE_TABLE,投影,StatusData.KEY_ROWID +=+ ID,
NULL,NULL,NULL,NULL);
} 如果游标结果集的变化//通知上下文的ContentResolver的
c.setNotificationUri(的getContext()getContentResolver(),URI); 返回℃;
} //辅助方法从乌里提取ID
私人长期的getId(URI URI){
串lastPathSegment = uri.getLastPathSegment();
如果(lastPathSegment!= NULL){
尝试{
返回的Long.parseLong(lastPathSegment);
}赶上(NumberFormatException的E){
//至少我们尝试
}
}
返回-1;
}
}
历史片段:
包com.projectcaruso.naturalfamilyplaning; 进口com.projectcaruso.naturalfamilyplanning.R;
进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;
进口android.content.IntentFilter;
进口android.database.Cursor;
进口android.os.Bundle;
进口android.support.v4.app.Fragment;
进口android.text.format.DateUtils;
进口android.util.Log;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.ViewGroup;
进口android.widget.ListView;
进口android.widget.SimpleCursorAdapter;
进口android.widget.TextView;
进口android.widget.SimpleCursorAdapter.ViewBinder;
公共类HistoryFragment扩展片段{
静态最后弦乐SEND_TIMELINE_NOTIFICATIONS =com.marakana.yamba.SEND_TIMELINE_NOTIFICATIONS; 光标光标;
ListView的listTimeline;
SimpleCursorAdapter适配器;
静态最后的String [] FROM = {StatusData.KEY_CHARTING_DATE,StatusData.KEY_NAME,StatusData.KEY_CHARTING_NOTES};
静态最终诠释[] TO = {R.id.textCreatedAt,R.id.textUser,R.id.textText};
TimelineReceiver接收机;
IntentFilter的过滤器; @覆盖
公共无效的onCreate(捆绑savedInstanceState){
super.onCreate(savedInstanceState);
} @覆盖
公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,捆绑savedInstanceState){ 查看查看= inflater.inflate(R.layout.fragment_history,集装箱,FALSE);
listTimeline =(ListView控件)view.findViewById(R.id.listTimeline); //创建接收器
//接收器=新TimelineReceiver();
//过滤器=新的IntentFilter(UpdaterService.NEW_STATUS_INTENT); 返回视图。
} @覆盖
公共无效onResume(){
super.onResume(); this.setupList(); //注册接收器
//super.registerReceiver(receiver,过滤器,
// SEND_TIMELINE_NOTIFICATIONS,NULL);
} @覆盖
公共无效的onPause(){
super.onPause(); //注销接收器
// unregisterReceiver(接收机);
} //负责获取数据和设置列表和适配器
私人无效setupList(){//&下; 5个
//获取数据
光标C = getActivity()getContentResolver()查询(StatusProvider.CONTENT_URI,NULL,NULL,NULL,StatusData.KEY_CHARTING_DATE +DESC)。 //&所述3是氢;
。getActivity()startManagingCursor(光标); //设置适配器
适配器=新SimpleCursorAdapter(getActivity(),R.layout.row,光标,FROM,TO);
adapter.setViewBinder(VIEW_BINDER); //&所述; 6个
listTimeline.setAdapter(适配器);
} //浏览粘结剂不断注入业务逻辑时间戳相对
//时间转换
静态最终ViewBinder VIEW_BINDER =新ViewBinder(){ 公共布尔setViewValue(查看视图,光标光标,诠释参数:columnIndex){
如果(view.getId()= R.id.textCreatedAt!)返回false; //更新在文本相对时间创建
长时间戳= cursor.getLong(参数:columnIndex);
CharSequence的reltime指示= DateUtils.getRelativeTimeSpanString(view.getContext(),时间戳);
((的TextView)视图).setText(reltime指示); 返回true;
}
}; //接收醒来时UpdaterService得到一个新的状态
//它通过重新查询光标刷新时间表列表
类TimelineReceiver扩展广播接收器{
@覆盖
公共无效的onReceive(上下文的背景下,意图意图){
setupList();
Log.d(TimelineReceiver,onReceived);
}
}
}
历史片段:
<?XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:方向=垂直
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT> <! - 标题 - >
<的TextView
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:比重=中心
机器人:layout_margin =10dp
机器人:文字=@字符串/ title_history
机器人:文字颜色=#FFF
机器人:TEXTSIZE =30sp/> < ListView控件
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT
机器人:ID =@ + ID / listTimeline/> < / LinearLayout中>
历史行:
<?XML版本=1.0编码=UTF-8&GT?;
&所述;! - &所述1为卤素; - >
< LinearLayout中的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:layout_height =WRAP_CONTENT机器人:方向=垂直
机器人:layout_width =FILL_PARENT> &所述;! - 2> - >
<的LinearLayout机器人:layout_height =WRAP_CONTENT
机器人:layout_width =FILL_PARENT> &所述;! - 3;> - >
< TextView的机器人:layout_height =WRAP_CONTENT
机器人:layout_width =FILL_PARENT机器人:layout_weight =1
机器人:ID =@ + ID / textUser机器人:文本=Slashdot的
机器人:文字样式=大胆/> &所述;! - &下; 4为H. - >
< TextView的机器人:layout_height =WRAP_CONTENT
机器人:layout_width =FILL_PARENT机器人:layout_weight =1
机器人:重力=正确的机器人:ID =@ + ID / textCreatedAt
机器人:文字=10分钟前/>
< / LinearLayout中> &所述;! - &下; 5个 - >
< TextView的机器人:layout_height =WRAP_CONTENT
机器人:layout_width =FILL_PARENT机器人:ID =@ + ID / textText
机器人:文字=火狐谈到Android的/>
< / LinearLayout中>
数据库:
公共类StatusData { //数据库信息
私有静态最后弦乐DATABASE_NAME =NFP;
私有静态最终诠释DATABASE_VERSION = 1; //表信息
静态最后弦乐DATABASE_TABLE =图表;
公共静态最后弦乐KEY_ROWID =_id;
公共静态最后弦乐KEY_NAME =用户名;
公共静态最后弦乐KEY_CHARTING_DATE =日期;
公共静态最后弦乐KEY_CHARTING_TEMPERATURE =温度;
公共静态最后弦乐KEY_CHARTING_STAMPS =邮票;
公共静态最后弦乐KEY_CHARTING_FERTILE =沃
公共静态最后弦乐KEY_CHARTING_NOTES =说明;
公共静态最后弦乐KEY_CHARTING_PROC =过程; 私有静态最后弦乐GET_ALL_ORDER_BY = KEY_CHARTING_DATE +DESC;
私有静态最后的String [] = MAX_CREATED_AT_COLUMNS {MAX(+ StatusData.KEY_CHARTING_DATE +)};
私有静态最后的String [] = DB_TEXT_COLUMNS {KEY_CHARTING_NOTES}; //调用一次
@覆盖
公共无效的onCreate(SQLiteDatabase DB){
db.execSQL(CREATE TABLE+ DATABASE_TABLE +(+
KEY_ROWID +INTEGER PRIMARY KEY AUTOINCREMENT,+
KEY_CHARTING_DATE +TEXT NOT NULL,+
KEY_NAME +TEXT+
KEY_CHARTING_TEMPERATURE +INTEGER,+
KEY_CHARTING_STAMPS +INTEGER,+
KEY_CHARTING_FERTILE +TEXT+
KEY_CHARTING_NOTES +TEXT+
KEY_CHARTING_PROC +);
);
} 最后DbHelper dbHelper; 公共StatusData(上下文的背景下){
this.dbHelper =新DbHelper(背景);
} 公共无效的close(){
this.dbHelper.close();
} 公共无效insertOrIgnore(ContentValues值){
SQLiteDatabase分贝= this.dbHelper.getWritableDatabase();
尝试{
db.insertWithOnConflict(DATABASE_TABLE,空,价值观,
SQLiteDatabase.CONFLICT_IGNORE);
} {最后
db.close();
}
} / **
*
* @返回光标所在的列将是编号,created_at,用户,TXT
* /
公共光标getStatusUpdates(){
SQLiteDatabase分贝= this.dbHelper.getReadableDatabase();
返回db.query(DATABASE_TABLE,NULL,NULL,NULL,NULL,NULL,GET_ALL_ORDER_BY);
} 众长getLatestStatusCreatedAtTime(){
SQLiteDatabase分贝= this.dbHelper.getReadableDatabase();
尝试{
光标光标= db.query(DATABASE_TABLE,MAX_CREATED_AT_COLUMNS,NULL,NULL,NULL,
NULL,NULL);
尝试{
返回cursor.moveToNext()? cursor.getLong(0):Long.MIN_VALUE;
} {最后
cursor.close();
}
} {最后
db.close();
}
} 公共字符串getStatusTextById(长ID){
SQLiteDatabase分贝= this.dbHelper.getReadableDatabase();
尝试{
光标光标= db.query(DATABASE_TABLE,DB_TEXT_COLUMNS,KEY_ROWID +=+ ID,空,
NULL,NULL,NULL);
尝试{
返回cursor.moveToNext()? cursor.getString(0):空;
} {最后
cursor.close();
}
} {最后
db.close();
}
} / **
*删除所有数据
* /
公共无效删除(){
//打开数据库
SQLiteDatabase分贝= dbHelper.getWritableDatabase(); //删除数据
db.delete(DATABASE_TABLE,NULL,NULL); //关闭数据库
db.close();
}
}
添加到体现:
<应用>
...
<供应商的android:NAME =。StatusProvider机器人:当局=com.projectcaruso.naturalfamilyplaning/>
< /用途>
编辑:
05-16 21:41:20.514:E / ActivityThread(7147):无法找到com.projectcaruso.naturalfamilyplaning.statusprovider供应商信息
05-16 21:41:20.514:V / SlidingMenu(7147):改变layerType。硬件?真正
05-16 21:41:20.584:D / dalvikvm(7147):GC_FOR_ALLOC释放2595K,8%的免费3305K / 3564K,暂停为33ms,总42ms
05-16 21:41:20.594:I / dalvikvm堆(7147):成长堆(frag的情况下),以4.476MB为1188736字节分配
05-16 21:41:20.694:D / dalvikvm(7147):GC_CONCURRENT释放1K,6%免费4464K / 4728K,暂停73ms + 5ms的,总105ms
05-16 21:41:20.694:D / dalvikvm(7147):WAIT_FOR_CONCURRENT_GC受阻19ms
05-16 21:41:20.744:D / dalvikvm(7147):GC_FOR_ALLOC释放< 1K,6%免费4464K / 4728K,暂停30毫秒,30毫秒总
05-16 21:41:20.754:I / dalvikvm堆(7147):成长堆(frag的情况下),以5.870MB为1463056字节分配
05-16 21:41:20.864:D / dalvikvm(7147):GC_CONCURRENT释放0K,5%的游离5893K / 6160K,暂停76ms + 5ms的,总107ms
05-16 21:41:20.864:D / dalvikvm(7147):WAIT_FOR_CONCURRENT_GC受阻18毫秒
05-16 21:41:20.894:I /编舞(7147):47跳过帧!该应用程序可能会做它的主线程的工作太多了。
05-16 21:41:20.937:V / CustomViewBehind(7147):看不见的背后
05-16 21:41:21.025:V / SlidingMenu(7147):改变layerType。硬件?假
编辑2:
05-17 13:20:41.013:D / dalvikvm(21373):GC_CONCURRENT释放0K,12%免费6199K / 7004K,暂停73ms + 6ms的,总111ms
05-17 13:20:41.013:D / dalvikvm(21373):WAIT_FOR_CONCURRENT_GC受阻24ms
05-17 13:20:41.054:V / SlidingMenu(21373):改变layerType。硬件?真正
05-17 13:20:41.054:V / SlidingMenu(21373):改变layerType。硬件?假
05-17 13:20:41.073:I /编舞(21373):跳过54帧!该应用程序可能会做它的主线程的工作太多了。
05-17 13:20:41.844:D / StatusProvider(21373):查询
05-17 13:20:41.855:I /编舞(21373):跳过39帧!该应用程序可能会做它的主线程的工作太多了。
05-17 13:20:41.924:V / SlidingMenu(21373):改变layerType。硬件?真正
05-17 13:20:41.984:W / CursorWrapperInner(21373):没有事先关闭游标敲定()
05-17 13:20:41.984:D / dalvikvm(21373):GC_FOR_ALLOC释放2601K,49%免费3627K / 7004K,暂停为35ms,总持续时间43ms
05-17 13:20:41.994:I / dalvikvm堆(21373):成长堆(frag的情况下),以4.791MB为1188736字节分配
05-17 13:20:42.104:D / dalvikvm(21373):GC_CONCURRENT释放23K,32%免费4765K / 7004K,暂停73ms + 5ms的,总113ms
05-17 13:20:42.104:D / dalvikvm(21373):WAIT_FOR_CONCURRENT_GC受阻为35ms
05-17 13:20:42.154:D / dalvikvm(21373):GC_FOR_ALLOC释放1K,32%免费4764K / 7004K,暂停36ms,总36ms
05-17 13:20:42.154:I / dalvikvm堆(21373):成长堆(frag的情况下),以6.163MB为1463056字节分配
05-17 13:20:42.265:D / dalvikvm(21373):GC_CONCURRENT释放0K,12%免费6193K / 7004K,暂停74ms + 5ms的,共有110毫秒
05-17 13:20:42.265:D / dalvikvm(21373):WAIT_FOR_CONCURRENT_GC受阻29ms
05-17 13:20:42.294:V / SlidingMenu(21373):改变layerType。硬件?真正
05-17 13:20:42.294:I /编舞(21373):跳过45帧!该应用程序可能会做它的主线程的工作太多了。
05-17 13:20:42.335:V / CustomViewBehind(21373):后面隐形
05-17 13:20:42.424:V / SlidingMenu(21373):改变layerType。硬件?假
解决方案
您在
错误 公共静态最终乌里CONTENT_URI =乌里
.parse(内容://com.projectcaruso.naturalfamilyplaning.statusprovider);
应
公共静态最终乌里CONTENT_URI =乌里
.parse(内容://com.projectcaruso.naturalfamilyplaning/statusprovider);
URI解析器解析由元素/不点。因此,供应商无法找到,因为没有权威com.projectcaruso.naturalfamilyplaning.statusprovider在您的清单中声明。
I'm trying to pull the history for the database.... However it never pulls anything... Anyone see what i'm doing wrong
Here's the content provider:
package com.projectcaruso.naturalfamilyplaning;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
public class StatusProvider extends ContentProvider {
private static final String TAG = StatusProvider.class.getSimpleName();
public static final Uri CONTENT_URI = Uri.parse("content://com.projectcaruso.naturalfamilyplaning.statusprovider");
public static final String SINGLE_RECORD_MIME_TYPE = "vnd.android.cursor.item/vnd.projectcaruso.naturalfamilyplaning.status";
public static final String MULTIPLE_RECORDS_MIME_TYPE = "vnd.android.cursor.dir/vnd.projectcaruso.naturalfamilyplaning.status";
StatusData statusData;
@Override
public String getType(Uri uri) {
return this.getId(uri) < 0 ? MULTIPLE_RECORDS_MIME_TYPE
: SINGLE_RECORD_MIME_TYPE;
}
@Override
public boolean onCreate() {
statusData = new StatusData(getContext());
return true;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = statusData.dbHelper.getWritableDatabase();
try {
long id = db.insertOrThrow(StatusData.DATABASE_TABLE, null, values);
if (id == -1) {
throw new RuntimeException(String.format(
"%s: Failed to insert [%s] to [%s] for unknown reasons.", TAG,
values, uri));
} else {
Uri newUri = ContentUris.withAppendedId(uri, id);
// Notify the Context's ContentResolver of the change
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
} finally {
db.close();
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
long id = this.getId(uri);
int count;
SQLiteDatabase db = statusData.dbHelper.getWritableDatabase();
try {
if (id < 0) {
count = db.update(StatusData.DATABASE_TABLE, values, selection, selectionArgs);
} else {
count = db.update(StatusData.DATABASE_TABLE, values, StatusData.KEY_ROWID + "=" + id,
null);
}
} finally {
db.close();
}
// Notify the Context's ContentResolver of the change
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
long id = this.getId(uri);
int count;
SQLiteDatabase db = statusData.dbHelper.getWritableDatabase();
try {
if (id < 0) {
count = db.delete(StatusData.DATABASE_TABLE, selection, selectionArgs);
} else {
count = db.delete(StatusData.DATABASE_TABLE, StatusData.KEY_ROWID + "=" + id, null);
}
} finally {
db.close();
}
// Notify the Context's ContentResolver of the change
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
long id = this.getId(uri);
SQLiteDatabase db = statusData.dbHelper.getReadableDatabase();
Log.d(TAG, "querying");
Cursor c;
if (id < 0) {
c = db.query(StatusData.DATABASE_TABLE, projection, selection, selectionArgs,
null, null, sortOrder);
} else {
c = db.query(StatusData.DATABASE_TABLE, projection, StatusData.KEY_ROWID + "=" + id,
null, null, null, null);
}
// Notify the context's ContentResolver if the cursor result set changes
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// Helper method to extract ID from Uri
private long getId(Uri uri) {
String lastPathSegment = uri.getLastPathSegment();
if (lastPathSegment != null) {
try {
return Long.parseLong(lastPathSegment);
} catch (NumberFormatException e) {
// at least we tried
}
}
return -1;
}
}
History Fragment:
package com.projectcaruso.naturalfamilyplaning;
import com.projectcaruso.naturalfamilyplanning.R;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.SimpleCursorAdapter.ViewBinder;
public class HistoryFragment extends Fragment {
static final String SEND_TIMELINE_NOTIFICATIONS = "com.marakana.yamba.SEND_TIMELINE_NOTIFICATIONS";
Cursor cursor;
ListView listTimeline;
SimpleCursorAdapter adapter;
static final String[] FROM = { StatusData.KEY_CHARTING_DATE, StatusData.KEY_NAME, StatusData.KEY_CHARTING_NOTES };
static final int[] TO = { R.id.textCreatedAt, R.id.textUser, R.id.textText };
TimelineReceiver receiver;
IntentFilter filter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_history, container, false);
listTimeline = (ListView) view.findViewById(R.id.listTimeline);
// Create the receiver
//receiver = new TimelineReceiver();
//filter = new IntentFilter( UpdaterService.NEW_STATUS_INTENT );
return view;
}
@Override
public void onResume() {
super.onResume();
this.setupList();
// Register the receiver
//super.registerReceiver(receiver, filter,
// SEND_TIMELINE_NOTIFICATIONS, null);
}
@Override
public void onPause() {
super.onPause();
// UNregister the receiver
//unregisterReceiver(receiver);
}
// Responsible for fetching data and setting up the list and the adapter
private void setupList() { // <5>
// Get the data
Cursor c = getActivity().getContentResolver().query(StatusProvider.CONTENT_URI, null, null, null, StatusData.KEY_CHARTING_DATE + " DESC"); // <3>
getActivity().startManagingCursor(cursor);
// Setup Adapter
adapter = new SimpleCursorAdapter(getActivity(), R.layout.row, cursor, FROM, TO);
adapter.setViewBinder(VIEW_BINDER); // <6>
listTimeline.setAdapter(adapter);
}
// View binder constant to inject business logic for timestamp to relative
// time conversion
static final ViewBinder VIEW_BINDER = new ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(view.getId() != R.id.textCreatedAt) return false;
// Update the created at text to relative time
long timestamp = cursor.getLong(columnIndex);
CharSequence relTime = DateUtils.getRelativeTimeSpanString(view.getContext(), timestamp);
((TextView)view).setText(relTime);
return true;
}
};
// Receiver to wake up when UpdaterService gets a new status
// It refreshes the timeline list by requerying the cursor
class TimelineReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
setupList();
Log.d("TimelineReceiver", "onReceived");
}
}
}
fragment history:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation ="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<!-- Title -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="10dp"
android:text="@string/title_history"
android:textColor="#fff"
android:textSize="30sp" />
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/listTimeline" />
</LinearLayout>
History row:
<?xml version="1.0" encoding="utf-8"?>
<!-- <1> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="fill_parent">
<!-- <2> -->
<LinearLayout android:layout_height="wrap_content"
android:layout_width="fill_parent">
<!-- <3> -->
<TextView android:layout_height="wrap_content"
android:layout_width="fill_parent" android:layout_weight="1"
android:id="@+id/textUser" android:text="Slashdot"
android:textStyle="bold" />
<!-- <4> -->
<TextView android:layout_height="wrap_content"
android:layout_width="fill_parent" android:layout_weight="1"
android:gravity="right" android:id="@+id/textCreatedAt"
android:text="10 minutes ago" />
</LinearLayout>
<!-- <5> -->
<TextView android:layout_height="wrap_content"
android:layout_width="fill_parent" android:id="@+id/textText"
android:text="Firefox comes to Android" />
</LinearLayout>
Database:
public class StatusData {
//Database information
private static final String DATABASE_NAME = "NFP";
private static final int DATABASE_VERSION = 1;
//Table Information
static final String DATABASE_TABLE = "charting";
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "username";
public static final String KEY_CHARTING_DATE = "Date";
public static final String KEY_CHARTING_TEMPERATURE = "temperature";
public static final String KEY_CHARTING_STAMPS = "Stamps";
public static final String KEY_CHARTING_FERTILE = "Fertile";
public static final String KEY_CHARTING_NOTES = "Notes";
public static final String KEY_CHARTING_PROC = "Proc";
private static final String GET_ALL_ORDER_BY = KEY_CHARTING_DATE + " DESC";
private static final String[] MAX_CREATED_AT_COLUMNS = { "max(" + StatusData.KEY_CHARTING_DATE + ")" };
private static final String[] DB_TEXT_COLUMNS = { KEY_CHARTING_NOTES };
//called once
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL( "CREATE table " + DATABASE_TABLE + " (" +
KEY_ROWID + " INTEGER primary key AUTOINCREMENT, " +
KEY_CHARTING_DATE + " TEXT NOT NULL, " +
KEY_NAME + " TEXT, " +
KEY_CHARTING_TEMPERATURE + " INTEGER, " +
KEY_CHARTING_STAMPS + " INTEGER, " +
KEY_CHARTING_FERTILE + " TEXT, " +
KEY_CHARTING_NOTES + " TEXT, " +
KEY_CHARTING_PROC + " ); "
);
}
final DbHelper dbHelper;
public StatusData(Context context) {
this.dbHelper = new DbHelper(context);
}
public void close() {
this.dbHelper.close();
}
public void insertOrIgnore(ContentValues values) {
SQLiteDatabase db = this.dbHelper.getWritableDatabase();
try {
db.insertWithOnConflict(DATABASE_TABLE, null, values,
SQLiteDatabase.CONFLICT_IGNORE);
} finally {
db.close();
}
}
/**
*
* @return Cursor where the columns are going to be id, created_at, user, txt
*/
public Cursor getStatusUpdates() {
SQLiteDatabase db = this.dbHelper.getReadableDatabase();
return db.query(DATABASE_TABLE, null, null, null, null, null, GET_ALL_ORDER_BY);
}
public long getLatestStatusCreatedAtTime() {
SQLiteDatabase db = this.dbHelper.getReadableDatabase();
try {
Cursor cursor = db.query(DATABASE_TABLE, MAX_CREATED_AT_COLUMNS, null, null, null,
null, null);
try {
return cursor.moveToNext() ? cursor.getLong(0) : Long.MIN_VALUE;
} finally {
cursor.close();
}
} finally {
db.close();
}
}
public String getStatusTextById(long id) {
SQLiteDatabase db = this.dbHelper.getReadableDatabase();
try {
Cursor cursor = db.query(DATABASE_TABLE, DB_TEXT_COLUMNS, KEY_ROWID + "=" + id, null,
null, null, null);
try {
return cursor.moveToNext() ? cursor.getString(0) : null;
} finally {
cursor.close();
}
} finally {
db.close();
}
}
/**
* Deletes ALL the data
*/
public void delete() {
// Open Database
SQLiteDatabase db = dbHelper.getWritableDatabase();
// Delete the data
db.delete(DATABASE_TABLE, null, null);
// Close Database
db.close();
}
}
added to manifest:
<application>
...
<provider android:name=".StatusProvider" android:authorities="com.projectcaruso.naturalfamilyplaning"/>
</application>
EDIT:
05-16 21:41:20.514: E/ActivityThread(7147): Failed to find provider info for com.projectcaruso.naturalfamilyplaning.statusprovider
05-16 21:41:20.514: V/SlidingMenu(7147): changing layerType. hardware? true
05-16 21:41:20.584: D/dalvikvm(7147): GC_FOR_ALLOC freed 2595K, 8% free 3305K/3564K, paused 33ms, total 42ms
05-16 21:41:20.594: I/dalvikvm-heap(7147): Grow heap (frag case) to 4.476MB for 1188736-byte allocation
05-16 21:41:20.694: D/dalvikvm(7147): GC_CONCURRENT freed 1K, 6% free 4464K/4728K, paused 73ms+5ms, total 105ms
05-16 21:41:20.694: D/dalvikvm(7147): WAIT_FOR_CONCURRENT_GC blocked 19ms
05-16 21:41:20.744: D/dalvikvm(7147): GC_FOR_ALLOC freed <1K, 6% free 4464K/4728K, paused 30ms, total 30ms
05-16 21:41:20.754: I/dalvikvm-heap(7147): Grow heap (frag case) to 5.870MB for 1463056-byte allocation
05-16 21:41:20.864: D/dalvikvm(7147): GC_CONCURRENT freed 0K, 5% free 5893K/6160K, paused 76ms+5ms, total 107ms
05-16 21:41:20.864: D/dalvikvm(7147): WAIT_FOR_CONCURRENT_GC blocked 18ms
05-16 21:41:20.894: I/Choreographer(7147): Skipped 47 frames! The application may be doing too much work on its main thread.
05-16 21:41:20.937: V/CustomViewBehind(7147): behind INVISIBLE
05-16 21:41:21.025: V/SlidingMenu(7147): changing layerType. hardware? false
EDIT 2:
05-17 13:20:41.013: D/dalvikvm(21373): GC_CONCURRENT freed 0K, 12% free 6199K/7004K, paused 73ms+6ms, total 111ms
05-17 13:20:41.013: D/dalvikvm(21373): WAIT_FOR_CONCURRENT_GC blocked 24ms
05-17 13:20:41.054: V/SlidingMenu(21373): changing layerType. hardware? true
05-17 13:20:41.054: V/SlidingMenu(21373): changing layerType. hardware? false
05-17 13:20:41.073: I/Choreographer(21373): Skipped 54 frames! The application may be doing too much work on its main thread.
05-17 13:20:41.844: D/StatusProvider(21373): querying
05-17 13:20:41.855: I/Choreographer(21373): Skipped 39 frames! The application may be doing too much work on its main thread.
05-17 13:20:41.924: V/SlidingMenu(21373): changing layerType. hardware? true
05-17 13:20:41.984: W/CursorWrapperInner(21373): Cursor finalized without prior close()
05-17 13:20:41.984: D/dalvikvm(21373): GC_FOR_ALLOC freed 2601K, 49% free 3627K/7004K, paused 35ms, total 43ms
05-17 13:20:41.994: I/dalvikvm-heap(21373): Grow heap (frag case) to 4.791MB for 1188736-byte allocation
05-17 13:20:42.104: D/dalvikvm(21373): GC_CONCURRENT freed 23K, 32% free 4765K/7004K, paused 73ms+5ms, total 113ms
05-17 13:20:42.104: D/dalvikvm(21373): WAIT_FOR_CONCURRENT_GC blocked 35ms
05-17 13:20:42.154: D/dalvikvm(21373): GC_FOR_ALLOC freed 1K, 32% free 4764K/7004K, paused 36ms, total 36ms
05-17 13:20:42.154: I/dalvikvm-heap(21373): Grow heap (frag case) to 6.163MB for 1463056-byte allocation
05-17 13:20:42.265: D/dalvikvm(21373): GC_CONCURRENT freed 0K, 12% free 6193K/7004K, paused 74ms+5ms, total 110ms
05-17 13:20:42.265: D/dalvikvm(21373): WAIT_FOR_CONCURRENT_GC blocked 29ms
05-17 13:20:42.294: V/SlidingMenu(21373): changing layerType. hardware? true
05-17 13:20:42.294: I/Choreographer(21373): Skipped 45 frames! The application may be doing too much work on its main thread.
05-17 13:20:42.335: V/CustomViewBehind(21373): behind INVISIBLE
05-17 13:20:42.424: V/SlidingMenu(21373): changing layerType. hardware? false
解决方案
You have an error in
public static final Uri CONTENT_URI = Uri
.parse("content://com.projectcaruso.naturalfamilyplaning.statusprovider");
should be
public static final Uri CONTENT_URI = Uri
.parse("content://com.projectcaruso.naturalfamilyplaning/statusprovider");
uri parser parses elements by "/" not by dot. So Provider can't be found because there is no authority "com.projectcaruso.naturalfamilyplaning.statusprovider" declared in your manifest.
这篇关于Android的从数据库中提取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文