系出名门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 ,如需转载请自行联系原作者

相关文章
|
2月前
|
API 数据库 C语言
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
175 0
|
2月前
|
网络协议 关系型数据库 MySQL
如何实现无公网ip远程访问本地安卓Termux部署的MySQL数据库【内网穿透】
如何实现无公网ip远程访问本地安卓Termux部署的MySQL数据库【内网穿透】
|
3月前
|
存储 监控 安全
内网屏幕监控软件的数据存储与管理:使用SQLite数据库保存监控记录和配置信息
在当今数字化时代,安全和监控在企业和组织中变得至关重要。内网屏幕监控软件作为一种关键工具,帮助组织监视员工的活动并确保信息安全。这种软件不仅需要高效地记录和管理监控数据,还需要能够方便地进行配置和调整。本文将讨论如何使用SQLite数据库来保存监控记录和配置信息,并介绍如何通过自动化机制将监控到的数据提交到指定网站。
185 2
|
13天前
|
SQL 存储 Ubuntu
在ubuntu中将dict.txt导入到数据库sqlite3
这样,你就成功将 `dict.txt` 中的数据导入到名为 `mydatabase.db` 的SQLite3数据库中的 `words` 表格中了。请根据实际情况调整表格结构和数据导入命令。
18 0
|
23天前
|
SQL 数据库 数据库管理
Python数据库操作(SQLAlchemy、SQLite等)面试题集
【4月更文挑战第15天】本文介绍了Python数据库操作的面试重点,涵盖SQLAlchemy ORM和SQLite。内容包括:1) 使用SQLAlchemy定义SQLite表的Python类及执行CRUD操作,强调ORM使用和会话管理;2) 查询优化与性能,涉及JOIN、分组、聚合查询,并提醒注意懒加载和索引创建;3) 异常处理和事务管理,展示如何捕获异常并进行事务控制。通过理解这些知识点并避免常见错误,可在面试中表现出色。
23 0
|
28天前
|
SQL 关系型数据库 数据库
Python中SQLite数据库操作详解:利用sqlite3模块
【4月更文挑战第13天】在Python编程中,SQLite数据库是一个轻量级的关系型数据库管理系统,它包含在一个单一的文件内,不需要一个单独的服务器进程或操作系统级别的配置。由于其简单易用和高效性,SQLite经常作为应用程序的本地数据库解决方案。Python的内置sqlite3模块提供了与SQLite数据库交互的接口,使得在Python中操作SQLite数据库变得非常容易。
|
1月前
|
关系型数据库 MySQL 数据库连接
Python+SQLite数据库实现服务端高并发写入
Python中使用SQLite内存模式实现高并发写入:创建内存数据库连接,建立表格,通过多线程并发写入数据。虽然能避免数据竞争,但由于SQLite内存模式采用锁机制,可能在高并发时引发性能瓶颈。若需更高性能,可选择MySQL或PostgreSQL。
37 0
|
2月前
|
数据库连接 API 数据库
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
66 0
|
2月前
|
关系型数据库 数据库 C++
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
|
2月前
|
存储 SQL 数据库
django如何连接sqlite数据库?
django如何连接sqlite数据库?
100 0