系出名门Android(9) - 数据库支持(SQLite), 内容提供器(ContentProvider)

简介:
[索引页]
[源码下载]


系出名门Android(9) - 数据库支持(SQLite), 内容提供器(ContentProvider)


作者: webabcd


介绍
在 Android 中使用 SQLite, ContentProvider 
  • 数据库支持(SQLite) - Android 开发平台提供了操作 SQLite 数据库的相关 API 
  • 内容提供器(ContentProvider) - 当数据需要在应用程序之间共享时,可以在某程序中使用 ContentProvider 定义 URI, 以使其它应用程序可以通过此 URI 访问指定的数据


1、SQLite 的 Demo
DatabaseHelper.java
package com.webabcd.SQLite; 

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

// 数据库操作的 Helper 类 
public  class DatabaseHelper  extends SQLiteOpenHelper { 

        DatabaseHelper(Context context, String name, CursorFactory cursorFactory,  int version) { 
                 super(context, name, cursorFactory, version); 
        } 

        @Override 
         public  void onCreate(SQLiteDatabase db) { 
                 // TODO 创建数据库后,对数据库的操作 
        } 

        @Override 
         public  void onUpgrade(SQLiteDatabase db,  int oldVersion,  int newVersion) { 
                 // TODO 更改数据库版本的操作 
        } 

        @Override 
         public  void onOpen(SQLiteDatabase db) { 
                 super.onOpen(db); 
                 
                 // TODO 每次成功打开数据库后首先被执行 
        } 
}
 
Main.java
package com.webabcd.SQLite; 

import java.util.Random; 

import android.app.Activity; 
import android.content.ContentValues; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 

public  class Main  extends Activity { 

         private DatabaseHelper dbHelper; 

         private  static  final String DATABASE_NAME =  "db.db"
         private  static  final  int DATABASE_VERSION = 1; 
         private  static  final String TABLE_NAME =  "employee"

        TextView txtMsg; 

         /** Called when the activity is first created. */ 
        @Override 
         public  void onCreate(Bundle savedInstanceState) { 
                 super.onCreate(savedInstanceState); 
                setContentView(R.layout.main); 

                dbHelper =  new DatabaseHelper( this, DATABASE_NAME,  null
                                DATABASE_VERSION); 

                txtMsg = (TextView)  this.findViewById(R.id.txtMsg); 

                Button btn1 = (Button)  this.findViewById(R.id.btn1); 
                btn1.setText( "创建表"); 
                btn1.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                CreateTable(); 
                        } 
                }); 

                Button btn2 = (Button)  this.findViewById(R.id.btn2); 
                btn2.setText( "插入 3 条记录"); 
                btn2.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                insertItem(); 
                        } 
                }); 

                Button btn3 = (Button)  this.findViewById(R.id.btn3); 
                btn3.setText( "删除全部记录"); 
                btn3.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                deleteItem(); 
                        } 
                }); 

                Button btn4 = (Button)  this.findViewById(R.id.btn4); 
                btn4.setText( "更新指定数据"); 
                btn4.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                updateItem(); 
                        } 
                }); 

                Button btn5 = (Button)  this.findViewById(R.id.btn5); 
                btn5.setText( "显示全部数据"); 
                btn5.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                showItems(); 
                        } 
                }); 

                Button btn6 = (Button)  this.findViewById(R.id.btn6); 
                btn6.setText( "删除表"); 
                btn6.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                dropTable(); 
                        } 
                }); 
        } 

         // 创建数据表 
         private  void CreateTable() { 
                SQLiteDatabase db = dbHelper.getWritableDatabase(); 
                String sql =  "CREATE TABLE IF NOT EXISTS " + TABLE_NAME 
                                +  " (ID INTEGER PRIMARY KEY, Name VARCHAR, Age INTEGER);"
                 try { 
                        db.execSQL(sql); 
                        txtMsg.append( "数据表成功创建\n"); 
                }  catch (SQLException ex) { 
                        txtMsg.append( "数据表创建错误\n" + ex.toString() +  "\n"); 
                } 
        } 

         // 插入数据 
         private  void insertItem() { 
                SQLiteDatabase db = dbHelper.getWritableDatabase(); 
                 
                 try { 
                        Random random =  new Random(); 
                         for ( int i = 0; i < 3; i++) { 
                                String sql =  "insert into " + TABLE_NAME 
                                                +  " (name, age) values ('name" + String.valueOf(i) 
                                                +  "', " + random.nextInt() +  ")"
                                 // execSQL() - 执行指定的 sql 
                                db.execSQL(sql); 
                        } 
                        txtMsg.append( "成功插入 3 条数据\n"); 
                }  catch (SQLException ex) { 
                        txtMsg.append( "插入数据失败\n" + ex.toString() +  "\n"); 
                } 
        } 

         // 删除数据 
         private  void deleteItem() { 
                 try { 
                        SQLiteDatabase db = dbHelper.getWritableDatabase(); 
                        db.delete(TABLE_NAME,  " id < 999999"null); 
                        txtMsg.append( "成功删除数据\n"); 
                }  catch (SQLException e) { 
                        txtMsg.append( "删除数据失败\n"); 
                } 
        } 

         // 更新数据 
         private  void updateItem() { 
                SQLiteDatabase db = dbHelper.getWritableDatabase(); 

                 try { 
                        ContentValues values =  new ContentValues(); 
                        values.put( "name""批量更新后的名字"); 

                        db.update(TABLE_NAME, values,  "id<?"new String[] {  "3" }); 
                        txtMsg.append( "成功更新数据\n"); 
                }  catch (SQLException e) { 
                        txtMsg.append( "更新数据失败\n"); 
                } 
        } 

         // 查询数据 
         private  void showItems() { 
                SQLiteDatabase db = dbHelper.getReadableDatabase(); 

                 try { 
                        String[] column = {  "id""name""age" }; 
                        Cursor cursor = db.query(TABLE_NAME, column,  nullnullnull
                                         nullnull); 
                        Integer num = cursor.getCount(); 
                        txtMsg.append( "共 " + Integer.toString(num) +  " 条记录\n"); 
                        cursor.moveToFirst(); 

                         while (cursor.getPosition() != cursor.getCount()) { 
                                txtMsg.append(Integer.toString(cursor.getPosition()) +  "," 
                                                + String.valueOf(cursor.getString(0)) +  "," 
                                                + cursor.getString(1) +  "," 
                                                + String.valueOf(cursor.getString(2)) +  "\n"); 
                                cursor.moveToNext(); 
                        } 
                }  catch (SQLException ex) { 
                        txtMsg.append( "读取数据失败\n" + ex.toString() +  "\n"); 
                } 
        } 

         // 删除数据表 
         private  void dropTable() { 
                SQLiteDatabase db = dbHelper.getWritableDatabase(); 
                String sql =  "DROP TABLE IF EXISTS " + TABLE_NAME; 
                 try { 
                        db.execSQL(sql); 
                        txtMsg.append( "数据表删除成功\n"); 
                }  catch (SQLException ex) { 
                        txtMsg.append( "数据表删除错误\n" + ex.toString() +  "\n"); 
                } 
        } 
}
 
 
2、ContentProvider 的 Demo
MyUser.java
package com.webabcd.contentprovider; 

import android.net.Uri; 
import android.provider.BaseColumns; 

// 自定义 ContentProvider 所需的实体类 
public  class MyUser { 

         // 必须要有 _id 字段。本例中 BaseColumn 类中已经包含了 _id 字段 
         public  static  final  class User  implements BaseColumns { 
                 
                 // 定义 CONTENT_URI 
                 public  static  final Uri CONTENT_URI = Uri.parse( "content://com.webabcd.MyContentProvider"); 

                // 表数据列 
                public static final String USER_NAME = "USER_NAME"
        } 
}
 
MyContentProvider.java
package com.webabcd.contentprovider; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 

import org.apache.http.util.EncodingUtils; 

import android.content.ContentProvider; 
import android.content.ContentUris; 
import android.content.ContentValues; 
import android.database.Cursor; 
import android.database.MatrixCursor; 
import android.net.Uri; 

// 继承 ContentProvider 以实现自定义的 ContentProvider(基于文件的信息存储) 
public  class MyContentProvider  extends ContentProvider { 

         private File file; 
         private FileOutputStream out; 
         private FileInputStream in; 

         // ContentProvider 的删除数据接口 
        @Override 
         public  int delete(Uri uri, String selection, String[] selectionArgs) { 
                 // TODO Auto-generated method stub 
                 return 0; 
        } 

        @Override 
         public String getType(Uri uri) { 
                 // TODO Auto-generated method stub 
                 return  null
        } 

         // ContentProvider 的插入数据接口    
        @Override 
         public Uri insert(Uri uri, ContentValues values) { 

                 try { 
                        out =  new FileOutputStream(file); 
                        out.write(values.getAsString(MyUser.User.USER_NAME).getBytes()); 
                        out.close(); 

                         int rowId = 0; 
                        Uri rowUri = ContentUris.appendId( 
                                        MyUser.User.CONTENT_URI.buildUpon(), rowId).build(); 
                        getContext().getContentResolver().notifyChange(rowUri,  null); 

                         return rowUri; 
                }  catch (Exception e) { 
                         return  null
                } 
        } 

         // 创建用于保存信息的文件 
        @Override 
         public  boolean onCreate() { 
                 try { 
                         // 每个包中应用程序的私有目录为:/data/data/包名/ 
                         // SD 卡目录为:/sdcard 
                        file =  new File( "/data/data/com.webabcd.contentprovider/"
                                         "demo.txt"); 
                         if (!file.exists()) 
                                file.createNewFile(); 

                         return  true
                }  catch (Exception ex) { 
                         return  false
                } 
        } 

         // ContentProvider 的查询数据接口 
        @Override 
         public Cursor query(Uri uri, String[] projection, String selection, 
                        String[] selectionArgs, String sortOrder) { 
                 
                String content; 

                 try { 
                        in =  new FileInputStream(file); 
                         int length = ( int) file.length(); 
                         byte[] buffer =  new  byte[length]; 
                        in.read(buffer, 0, length); 
                        content = EncodingUtils.getString(buffer,  "UTF-8"); 
                        in.close(); 

                        String[] columns =  new String[] { MyUser.User._ID, MyUser.User.USER_NAME }; 
                        MatrixCursor cur =  new MatrixCursor(columns); 
                        String[] values =  new String[] {  "0", content }; 
                        cur.moveToFirst(); 
                        cur.addRow(values); 

                         return cur; 
                }  catch (Exception e) { 
                         return  null
                } 
        } 

         // ContentProvider 的更新数据接口 
        @Override 
         public  int update(Uri uri, ContentValues values, String selection, 
                        String[] selectionArgs) { 
                 // TODO Auto-generated method stub 
                 return 0; 
        } 
}
 
Main.java
package com.webabcd.contentprovider; 

import java.util.Random; 

import android.app.Activity; 
import android.content.ContentUris; 
import android.content.ContentValues; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.Bundle; 
import android.provider.Contacts; 
import android.provider.Contacts.People; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 

/* 
* 几个常用的系统内置的 ContentProvider 如下:    
* content://media/internal/images    这个URI将返回设备上存储的所有图片 
* content://contacts/people/ 这个URI将返回设备上的所有联系人信息 
* content://contacts/people/45 这个URI返回单个结果(联系人信息中ID为45的联系人记录) 
*/
 
public  class Main  extends Activity { 
         /** Called when the activity is first created. */ 
        @Override 
         public  void onCreate(Bundle savedInstanceState) { 
                 super.onCreate(savedInstanceState); 
                setContentView(R.layout.main); 

                Button btn1 = (Button)  this.findViewById(R.id.btn1); 
                btn1.setText( "新增联系人记录"); 
                btn1.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                Random random =  new Random(); 
                                insertRecords( "name" + String.valueOf(random.nextInt()), String 
                                                .valueOf(random.nextInt())); 
                        } 
                }); 

                Button btn2 = (Button)  this.findViewById(R.id.btn2); 
                btn2.setText( "查看联系人记录"); 
                btn2.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                displayRecords(); 
                        } 
                }); 

                Button btn3 = (Button)  this.findViewById(R.id.btn3); 
                btn3.setText( "清除联系人记录"); 
                btn3.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                deleteRecords(); 
                        } 
                }); 

                Button btn4 = (Button)  this.findViewById(R.id.btn4); 
                btn4.setText( "更新联系人记录"); 
                btn4.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                 // 此处只是演示,id 来自 People._ID ,可参见 displayRecords() 是如何获取 id 的 
                                 int id = 0; 
                                updateRecord(id,  "修改后的name"); 
                        } 
                }); 

                Button btn5 = (Button)  this.findViewById(R.id.btn5); 
                btn5.setText( "新增记录到 MyContentProvider"); 
                btn5.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                insertRecord2MyContentProvider( "webabcd"); 
                        } 
                }); 

                Button btn6 = (Button)  this.findViewById(R.id.btn6); 
                btn6.setText( "获取记录从 MyContentProvider"); 
                btn6.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                displayRecord2MyContentProvider(); 
                        } 
                }); 
        } 

         // 调用 ContentProvider 的插入接口 
         private  void insertRecords(String name, String phoneNum) { 
                ContentValues values =  new ContentValues(); 
                values.put(People.NAME, name); 
                Uri uri = getContentResolver().insert(People.CONTENT_URI, values); 
                Log.d( "MyDebug", uri.toString()); 
                Uri numberUri = Uri.withAppendedPath(uri, 
                                People.Phones.CONTENT_DIRECTORY); 
                Log.d( "MyDebug", numberUri.toString()); 

                values.clear(); 
                values.put(Contacts.Phones.TYPE, People.Phones.TYPE_MOBILE); 
                values.put(People.NUMBER, phoneNum); 
                getContentResolver().insert(numberUri, values); 
        } 

         // 调用 ContentProvider 的查询接口 
         private  void displayRecords() { 
                String[] columns =  new String[] { People._ID, People.NAME, 
                                People.NUMBER }; 
                Uri contacts = People.CONTENT_URI; 
                Log.d( "MyDebug", contacts.toString()); 
                Cursor cur = managedQuery(contacts, columns,  // 要返回的数据字段 
                                 null// WHERE子句 
                                 null// WHERE 子句的参数 
                                 null  // Order-by子句 
                ); 

                 if (cur.moveToFirst()) { 
                        String id =  null
                        String name =  null
                        String phoneNo =  null
                         while (cur.getPosition() != cur.getCount()) { 
                                id = cur.getString(cur.getColumnIndex(People._ID)); 
                                name = cur.getString(cur.getColumnIndex(People.NAME)); 
                                phoneNo = cur.getString(cur.getColumnIndex(People.NUMBER)); 

                                Toast.makeText( this, id +  " / " + name +  " / " + phoneNo, 
                                                Toast.LENGTH_SHORT).show(); 
                                cur.moveToNext(); 
                        } 
                } 
        } 

         // 调用 ContentProvider 的删除接口 
         private  void deleteRecords() { 
                Uri uri = People.CONTENT_URI; 
                Log.d( "MyDebug", uri.toString()); 
                getContentResolver().delete(uri,  nullnull); 
                 // getContentResolver().delete(uri, "NAME=" + "'name'", null); 
        } 

         // 调用 ContentProvider 的更新接口 
         private  void updateRecord( int recordNo, String name) { 
                Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, recordNo); 
                Log.d( "MyDebug", uri.toString()); 
                ContentValues values =  new ContentValues(); 
                values.put(People.NAME, name); 
                getContentResolver().update(uri, values,  nullnull); 
        } 

         
         // 调用自定义 ContentProvider 的插入接口 
         private  void insertRecord2MyContentProvider(String name) { 
                ContentValues values =  new ContentValues(); 
                values.put(MyUser.User.USER_NAME, name); 
                getContentResolver().insert(MyUser.User.CONTENT_URI, values); 

        } 

         // 调用自定义 ContentProvider 的查询接口 
         private  void displayRecord2MyContentProvider() { 
                String[] columns =  new String[] { MyUser.User.USER_NAME }; 
                Uri uri = MyUser.User.CONTENT_URI; 
                Cursor cur = managedQuery(uri, columns,  nullnullnull); 

                 while (cur.getPosition() != cur.getCount()) { 
                        String id = cur.getString(cur.getColumnIndex(People._ID)); 
                        String name = cur.getString(cur.getColumnIndex(MyUser.User.USER_NAME)); 
                        Toast.makeText( this
                                        id +  " / " + name, 
                                        Toast.LENGTH_SHORT).show(); 
                        cur.moveToNext(); 
                } 
        } 
}
 
AndroidManifest.xml
<? xml  version ="1.0"  encoding ="utf-8" ?> 
< manifest  xmlns:android ="http://schemas.android.com/apk/res/android" 
             package ="com.webabcd.contentprovider" 
             android:versionCode ="1" 
             android:versionName ="1.0" > 
         < application  android:icon ="@drawable/icon"  android:label ="@string/app_name" > 
                 < activity  android:name =".Main" 
                                     android:label ="@string/app_name" > 
                         < intent-filter > 
                                 < action  android:name ="android.intent.action.MAIN"  /> 
                                 < category  android:name ="android.intent.category.LAUNCHER"  /> 
                         </ intent-filter > 
                 </ activity > 
                 
                <!--  
                        配置一个自定义的 ContentProvider" 
                
--> 
                 < provider  android:name ="MyContentProvider"  android:authorities ="com.webabcd.MyContentProvider"  /> 
         </ application > 
         < uses-permission  android:name ="android.permission.WRITE_CONTACTS" > </ uses-permission > 
         < uses-permission  android:name ="android.permission.READ_CONTACTS" > </ uses-permission > 
         < uses-sdk  android:minSdkVersion ="3"  /> 
</ manifest >
 
 
 

     本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/342098 ,如需转载请自行联系原作者

相关文章
|
22天前
|
存储 SQL 数据库
数据库知识:了解SQLite或其他移动端数据库的使用
【10月更文挑战第22天】本文介绍了SQLite在移动应用开发中的应用,包括其优势、如何在Android中集成SQLite、基本的数据库操作(增删改查)、并发访问和事务处理等。通过示例代码,帮助开发者更好地理解和使用SQLite。此外,还提到了其他移动端数据库的选择。
25 8
|
1月前
|
Web App开发 SQL 数据库
使用 Python 解析火狐浏览器的 SQLite3 数据库
本文介绍如何使用 Python 解析火狐浏览器的 SQLite3 数据库,包括书签、历史记录和下载记录等。通过安装 Python 和 SQLite3,定位火狐数据库文件路径,编写 Python 脚本连接数据库并执行 SQL 查询,最终输出最近访问的网站历史记录。
|
1月前
|
存储 关系型数据库 数据库
轻量级数据库的利器:Python 及其内置 SQLite 简介
轻量级数据库的利器:Python 及其内置 SQLite 简介
|
1月前
|
应用服务中间件 PHP Apache
PbootCMS提示错误信息“未检测到您服务器环境的sqlite3数据库扩展...”
PbootCMS提示错误信息“未检测到您服务器环境的sqlite3数据库扩展...”
|
2月前
|
存储 API 数据库
QML使用Sqlite数据库存储ListModel数据
本文介绍了在QML中使用Sqlite数据库存储ListModel数据的方法,包括如何创建数据库、读取数据、动态添加和删除数据,以及如何在程序启动和退出时与数据库同步数据。
|
2月前
|
数据库 数据库管理
qt对sqlite数据库多线程的操作
本文总结了在Qt中进行SQLite数据库多线程操作时应注意的四个关键问题,包括数据库驱动加载、加锁、数据库的打开与关闭,以及QsqlQuery变量的使用。
144 1
|
1月前
|
存储 缓存 关系型数据库
sqlite 数据库 介绍
sqlite 数据库 介绍
35 0
|
3月前
|
人工智能 小程序 Java
【工具】轻松解锁SQLite数据库,一窥微信聊天记录小秘密
本文介绍了一款名为PyWxDump的开源工具,它可以获取微信账户信息、解密SQLite数据库以查看和备份聊天记录。此工具适用于已登录电脑版微信的用户,通过GitHub下载后简单几步即可操作。适合对数据恢复感兴趣的开发者,但请注意合法合规使用并尊重隐私。
503 2
【工具】轻松解锁SQLite数据库,一窥微信聊天记录小秘密
|
2月前
|
JSON NoSQL 数据库
和SQLite数据库对应的NoSQL数据库:TinyDB的详细使用(python3经典编程案例)
该文章详细介绍了TinyDB这一轻量级NoSQL数据库的使用方法,包括如何在Python3环境中安装、创建数据库、插入数据、查询、更新以及删除记录等操作,并提供了多个编程案例。
112 0
|
3月前
|
关系型数据库 Java MySQL
C#winform中使用SQLite数据库
C#winform中使用SQLite数据库
189 3
C#winform中使用SQLite数据库