创建并使用一个地震Content Provider

news/2024/5/20 3:42:52
  

已经创建了一个应用程序,它能够显示最近的地震列表。现在,你有一个极好的机会来和其它应用程序共享这些信息。

 

通过一个Content Provider来暴露这些数据,你或其他人都可以创建基于这些数据的应用程序,而不用加倍网络流量和相关的XML解析。

 

创建Content Provider

 

接下来的例子显示了如何创建一个地震Content Provider。每一个quake都将储存在一个SQLite数据库。

 

1. 打开Earthquake工程,创建一个新的EarthquakeProvider类,扩展Content Provider。重写onCreategetTypequeryinsertdeleteupdate方法。

 

package com.paad.earthquake;

import android.content.*;

import android.database.Cursor;

import android.database.SQLException;

import android.database.sqlite.SQLiteOpenHelper;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteQueryBuilder;

import android.net.Uri;

import android.text.TextUtils;

import android.util.Log;

public class EarthquakeProvider extends ContentProvider {

 

@Override

public boolean onCreate() {

}

 

@Override

public String getType(Uri url) {

}

 

@Override

public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sort) {

}

 

@Override

public Uri insert(Uri _url, ContentValues _initialValues) {

}

 

@Override

public int delete(Uri url, String where, String[] whereArgs) {

}

 

@Override

public int update(Uri url, ContentValues values, String where, String[] wArgs) {

}

}

 

2. 为这个Provider定义一个Content URI。这个URI将用于在程序组件中,使用ContentResolver来访问这个Content Provider

 

public static final Uri CONTENT_URI = Uri.parse(“content://com.paad.provider.earthquake/earthquakes”);

 

3. 创建数据库,用来存储地震数据。在EarthquakeProvider类中,创建一个新的SQLiteDatabase实例,并且暴露列名称和索引的公共变量。包含一个SQLiteOpenHelper的扩展类来管理数据库的创建和版本控制。

 

// The underlying database

private SQLiteDatabase earthquakeDB;

private static final String TAG = “EarthquakeProvider”;

private static final String DATABASE_NAME = “earthquakes.db”;

private static final int DATABASE_VERSION = 1;

private static final String EARTHQUAKE_TABLE = “earthquakes”;

 

// Column Names

public static final String KEY_ID = “_id”;

public static final String KEY_DATE = “date”;

public static final String KEY_DETAILS = “details”;

public static final String KEY_LOCATION_LAT = “latitude”;

public static final String KEY_LOCATION_LNG = “longitude”;

public static final String KEY_MAGNITUDE = “magnitude”;

public static final String KEY_LINK = “link”;

 

// Column indexes

public static final int DATE_COLUMN = 1;

public static final int DETAILS_COLUMN = 2;

public static final int LONGITUDE_COLUMN = 3;

public static final int LATITUDE_COLUMN = 4;

public static final int MAGNITUDE_COLUMN = 5;

public static final int LINK_COLUMN = 6;

// Helper class for opening, creating, and managing

// database version control

private static class earthquakeDatabaseHelper extends SQLiteOpenHelper {

private static final String DATABASE_CREATE =“create table “ + EARTHQUAKE_TABLE + “ (“

+ KEY_ID + “ integer primary key autoincrement, “

+ KEY_DATE + “ INTEGER, “

+ KEY_DETAILS + “ TEXT, “

+ KEY_LOCATION_LAT + “ FLOAT, “

+ KEY_LOCATION_LNG + “ FLOAT, “

+ KEY_MAGNITUDE + “ FLOAT, “

+ KEY_LINK + “ TEXT);”;

 

public earthquakeDatabaseHelper(Context context, String name, CursorFactory factory, int version) {

super(context, name, factory, version);

}

 

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(DATABASE_CREATE);

}

 

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

Log.w(TAG, “Upgrading database from version “ + oldVersion + “ to “

+ newVersion + “, which will destroy all old data”);

db.execSQL(“DROP TABLE IF EXISTS “ + EARTHQUAKE_TABLE);

onCreate(db);

}

}

 

4. 创建一个UriMatcher来处理不同不同的URI请求。包含对整个数据集(QUAKES)和单个记录的索引(QUAKE_ID)的查询和交互的支持。

 

// Create the constants used to differentiate between the different URI

// requests.

private static final int QUAKES = 1;

private static final int QUAKE_ID = 2;

private static final UriMatcher uriMatcher;

// Allocate the UriMatcher object, where a URI ending in ‘earthquakes’

// will correspond to a request for all earthquakes, and ‘earthquakes’

// with a trailing ‘/[rowID]’ will represent a single earthquake row.

static {

uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

uriMatcher.addURI(“com.paad.provider.Earthquake”, “earthquakes”, QUAKES);

uriMatcher.addURI(“com.paad.provider.Earthquake”, “earthquakes/#”, QUAKE_ID);

}

 

5. 重写getType方法来返回每个支持的URI结构的字符串。

 

@Override

public String getType(Uri uri) {

switch (uriMatcher.match(uri)) {

case QUAKES:

return “vnd.android.cursor.dir/vnd.paad.earthquake”;

case QUAKE_ID:

return “vnd.android.cursor.item/vnd.paad.earthquake”;

default:

throw new IllegalArgumentException(“Unsupported URI: “ + uri);

}

}

 

6. 重写ProvideronCreate方法,来创建一个数据库辅助类的实例,并打开一个数据库的连接。

 

@Override

public boolean onCreate() {

Context context = getContext();

earthquakeDatabaseHelper dbHelper;

dbHelper = new earthquakeDatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);

earthquakeDB = dbHelper.getWritableDatabase();

return (earthquakeDB == null) ? false : true;

}

 

7. 实现查询和交互的函数。首先是查询方法;它应该解析发送的请求(是所有的内容还是单行),并应用selectionprojectionsortorder等参数来返回一个Cursor

 

@Override

public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sort) {

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

qb.setTables(EARTHQUAKE_TABLE);

// If this is a row query, limit the result set to the passed in row.

switch (uriMatcher.match(uri)) {

case QUAKE_ID:

qb.appendWhere(KEY_ID + “=” + uri.getPathSegments().get(1));

break;

default: break;

}

 

// If no sort order is specified sort by date / time

String orderBy;

if (TextUtils.isEmpty(sort))

{

orderBy = KEY_DATE;

}

else

{

orderBy = sort;

}

 

// Apply the query to the underlying database.

Cursor c = qb.query(earthquakeDB,projection,selection, selectionArgs,null, null,orderBy);

 

// Register the contexts ContentResolver to be notified if

// the cursor result set changes.

c.setNotificationUri(getContext().getContentResolver(), uri);

 

// Return a cursor to the query result.

return c;

}

 

8. 现在实现insertdeleteupdate方法。在这种情况下,这个过程基本上是练习将Content Provider的交互请求映射到数据库上。

 

@Override

public Uri insert(Uri _uri, ContentValues _initialValues) {

// Insert the new row, will return the row number if

// successful.

long rowID = earthquakeDB.insert(EARTHQUAKE_TABLE, “quake”,_initialValues);

// Return a URI to the newly inserted row on success.

if (rowID > 0)

{

Uri uri = ContentUris.withAppendedId(CONTENT_URI, rowID);

getContext().getContentResolver().notifyChange(uri, null);

return uri;

}

throw new SQLException(“Failed to insert row into “ + _uri);

}

 

@Override

public int delete(Uri uri, String where, String[] whereArgs) {

int count;

switch (uriMatcher.match(uri)) {

case QUAKES:

count = earthquakeDB.delete(EARTHQUAKE_TABLE, where, whereArgs);

break;

case QUAKE_ID:

String segment = uri.getPathSegments().get(1);

count = earthquakeDB.delete(EARTHQUAKE_TABLE, KEY_ID + “=”+ segment

+ (!TextUtils.isEmpty(where) ? “ AND (“

+ where + ‘)’ : “”), whereArgs);

break;

default: throw new IllegalArgumentException(“Unsupported URI: “ + uri);

}

getContext().getContentResolver().notifyChange(uri, null);

return count;

}

 

@Override

public int update(Uri uri, ContentValues values, String where,String[] whereArgs) {

int count;

switch (uriMatcher.match(uri)) {

case QUAKES:

count = earthquakeDB.update(EARTHQUAKE_TABLE, values,where, whereArgs);

break;

case QUAKE_ID:

String segment = uri.getPathSegments().get(1);

count = earthquakeDB.update(EARTHQUAKE_TABLE, values, KEY_ID + “=” + segment

+ (!TextUtils.isEmpty(where) ? “ AND (“

+ where + ‘)’ : “”), whereArgs);

break;

default: throw new IllegalArgumentException(“Unknown URI “ + uri);

}

getContext().getContentResolver().notifyChange(uri, null);

return count;

}

 

9. 当Content Provider完成时,在程序的manifestapplication标签中添加一个节点来注册它。

 

<provider android:name=”.EarthquakeProvider” android:authorities=”com.paad.provider.earthquake” />

 

使用Provider

 

现在,你可以更新Earthquake Activity来使用EarthquakeProvider来储存quake,并使用它们来填入ListView

 

1. 在Earthquake Activity中,更新addNewQuake方法。它应该使用程序的ContentResolver来插入每个地震信息。把现有的数组控制逻辑移动到新的addQuakeToArray方法中。

 

private void addNewQuake(Quake _quake) {

ContentResolver cr = getContentResolver();

// Construct a where clause to make sure we don’t already have this

// earthquake in the provider.

String w = EarthquakeProvider.KEY_DATE + “ = “ + _quake.getDate().getTime();

// If the earthquake is new, insert it into the provider.

Cursor c = cr.query(EarthquakeProvider.CONTENT_URI,null, w, null, null);

int dbCount = c.getCount();

c.close();

if (dbCount > 0) (应该是 == 0 的判断)

{

ContentValues values = new ContentValues();

values.put(EarthquakeProvider.KEY_DATE, _quake.getDate().getTime());

values.put(EarthquakeProvider.KEY_DETAILS, _quake.getDetails());

double lat = _quake.getLocation().getLatitude();

double lng = _quake.getLocation().getLongitude();

values.put(EarthquakeProvider.KEY_LOCATION_LAT, lat);

values.put(EarthquakeProvider.KEY_LOCATION_LNG, lng);

values.put(EarthquakeProvider.KEY_LINK, _quake.getLink());

values.put(EarthquakeProvider.KEY_MAGNITUDE, _quake.getMagnitude());

cr.insert(EarthquakeProvider.CONTENT_URI, values);

earthquakes.add(_quake);(似乎多插入了一次。)

addQuakeToArray(_quake);

}

}

 

private void addQuakeToArray(Quake _quake) {

if (_quake.getMagnitude() > minimumMagnitude)

{

// Add the new quake to our list of earthquakes.

earthquakes.add(_quake);

// Notify the array adapter of a change.

aa.notifyDataSetChanged();

}

}

 

2. 创建一个loadQuakesFromProvider方法来从EarthquakeProvider加载所有的地震数据,并且使用addQuakeToArray方法来将它们插入到数组列表中。

 

private void loadQuakesFromProvider() {

// Clear the existing earthquake array

earthquakes.clear();

 

ContentResolver cr = getContentResolver();

// Return all the saved earthquakes

 

Cursor c = cr.query(EarthquakeProvider.CONTENT_URI, null, null, null, null);

if (c.moveToFirst())

{

do

{

// Extract the quake details.

Long datems = c.getLong(EarthquakeProvider.DATE_COLUMN);

String details;

details = c.getString(EarthquakeProvider.DETAILS_COLUMN);

Float lat = c.getFloat(EarthquakeProvider.LATITUDE_COLUMN);

Float lng = c.getFloat(EarthquakeProvider.LONGITUDE_COLUMN);

Double mag = c.getDouble(EarthquakeProvider.MAGNITUDE_COLUMN);

String link = c.getString(EarthquakeProvider.LINK_COLUMN);

Location location = new Location(“dummy”);

location.setLongitude(lng);

location.setLatitude(lat);

Date date = new Date(datems);

Quake q = new Quake(date, details, location, mag, link);

addQuakeToArray(q);

} while(c.moveToNext());

}

c.close();

}

 

3. 在onCreate方法中调用loadQuakeFromProvider方法来初始化EarthquakeListView

 

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

earthquakeListView =

(ListView)this.findViewById(R.id.earthquakeListView);

earthquakeListView.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView _av, View _v, int _index, long arg3) {

selectedQuake = earthquakes.get(_index);

showDialog(QUAKE_DIALOG);

}

});

int layoutID = android.R.layout.simple_list_item_1;

aa = new ArrayAdapter<Quake>(this, layoutID , earthquakes);

earthquakeListView.setAdapter(aa);

loadQuakesFromProvider();

updateFromPreferences();

refreshEarthquakes();

}

 

4. 最后,对refreshEarthquake方法做一项变更,在清除数组之后,添加新的quake之前,加载保存的地震数据。

 

private void refreshEarthquakes() {

[ ... exiting refreshEarthquakes method ... ]

// Clear the old earthquakes

earthquakes.clear();

loadQuakesFromProvider();

[ ... exiting refreshEarthquakes method ... ]

}

 


http://www.niftyadmin.cn/n/1978334.html

相关文章

操作dom获取datatable中的某一行的某一列的数据

需求描述&#xff1a;编辑的时候&#xff0c;点击的那一行&#xff0c;进入后台的验证方法&#xff0c;验证通过后&#xff0c;再进入编辑页面&#xff0c;进入的时候需要把本行<tr>数据中的某一列<td>的值传递过去 思路表述&#xff1a;之前我想的是&#xff0c;给…

MES四大市场需求各异

MES四大市场需求各异各个国家和地区对MES需求不尽相同。众所周知&#xff0c;制造业一直追求的三大境界是最短的市场响应时间、最高的产品质量以及最低的生产成本。随着环境的变化&#xff0c;企业追求这三者的方法和所面临的挑战也随之改变。管理的扁平化是对企业的一个内在要…

纯干货!live2d动画制作简述以及踩坑

本文来自网易云社区&#xff0c;转载务必请注明出处。1. 概述live2d是由日本Cybernoids公司开发&#xff0c;通过扭曲像素位置营造伪3d空间感的二维动画软件。官网下载安装包直接安装可以得到两种软件&#xff0c;分别是Cubism Modeler和Cubism Animator&#xff0c;最后我们还…

使用Silverlight Toolkit 等级控件---Rating

乍一看到这个控件&#xff0c;就让我想起了电影里的“悬赏缉拿”的海报。在头像下面有一排星&#xff0c;根据实心星的数目来标识该罪犯的‘危险程度’。其实在一些电影网站上也 有对某部片子打星的功能。而在Silverlight Toolkit 3就是真的提供了这么一个控件&#xff0c;通过…

mysql 开发进阶篇系列 48 物理备份与恢复(xtrabackup 的增量备份与恢复,以及备份总结)...

一.增量备份概述 xtrabackup 和innobackupex 二个工具都支持增量备份&#xff0c;这意味着能复制自上次备份以来更改的数据。可以在每个完整备份之间执行许多增量备份&#xff0c;因此&#xff0c;您可以设置一个备份过程&#xff0c;例如每周一次完整备份和每天一次增量备份…

最强安装虚拟机到安装GAMIT/GLOBK教程步骤汇总(建议安装16.04LST)

Gamit/Globk软件是搭载在Linux系统下的&#xff0c;我们熟悉了WIN的界面操作&#xff0c;完全可以借助在WIN下安装虚拟机软件来安装使用Linux系统&#xff0c;目前Linux系统底下的乌班图系统分为16.04和18.04版本&#xff0c;操作差不多&#xff0c;但是新版本也有差异。安装的…

备份和还原Exchange Server 2007邮箱存储组

备份和还原Exchange Server 2007邮箱存储组 出处&#xff1a;Windows中文站 作者&#xff1a;卡西莫多 时间&#xff1a;2007-12-17 0:00:15263企业邮箱&#xff0c;注册即可免费试用邮箱服务器作为Exchange Server 2007中最重要的角色承担着存储用户邮件、文件夹的重任。那么备…

GAMIT/GLOBK解算北斗数据(version:10.71)

解算北斗数据的流程方法和处理GPS 的方法整体上一样&#xff0c;只在一些操作的命令上会有一些差异。由于现在GAMIT还不支持现在三点几的命名方式所以还要把数据文件名转换为二点几的。新建工程文件目录&#xff0c;在里面新建文件夹&#xff1a;brdc、igs、rinex、rinex3四个文…