ContentsProviderの使い方の基本
対象者
・異なるアプリ間でDBを共有したい方
使用するもの
・SQLiteOpenHelperクラス(データベースの作成等に使用します)
・ContentsProviderクラス(データの挿入、削除、データベースの更新等に使用します)
データベース構成
今回は簡単に作成します。
データベース名:database.db
テーブル名: user
使用するデータ
・id(自動インクリメント)
・username
・email
のみです。
まずはデータベースを作成します。
ちなみにSQLiteで使用できる型は、NULL,INTEGER,REAL,TEXT,BLOBのみです。
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MySQLliteOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;//データベースのバージョン
private static final String DATABASE_NAME = "database.db";//データベースの名前
public MySQLliteOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//テーブル作成
db.execSQL(
"create table user (" +
"id integer primary key autoincrement, "+
"username TEXT not null, "+
"email TEXT not null );"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table user");//テーブルの削除
onCreate(db);
}
}
コンストラクタでデータベース作成、
OnCreateでテーブル作成しています。
ここがよくわからない方は、これを参照して学んでください。
https://techbooster.org/android/application/567/
ContentsProviderの作成
コンテンツプロバイダは、query,insert,delete,update等が使用できます。
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;
import java.net.URI;
public class MyContentProvider extends ContentProvider {
private MySQLliteOpenHelper helper;
public MyContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
final int count=db.delete(uri.getPathSegments().get(0),selection,selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
//MiMEタイプのリクエスト
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
long newRowId = db.insert("user", null, values);
Uri returnUri = ContentUris.withAppendedId(uri, newRowId);
return returnUri;
}
@Override
public boolean onCreate() {
helper=new MySQLliteOpenHelper(getContext());//ヘルパーインスタンの作成
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables("user");
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query(
uri.getPathSegments().get(0),//テーブル名
null, // fields(取得したいフィールド
null, // where句
null, // where args(whereの引数)
null, // groupBy句
null, // having句
null,//order_by句
null // LIMIT句
);
Log.d("ContentsPro","");
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
final int count = db.update(uri.getPathSegments().get(0),values,selection,selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
queryメソッドは適当に変えてください。
query,insert,delete,update
次にデータを操作する場合の処理を記述します。
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private Uri uri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
insert();
query();
update();
delete();
}
public void insert(){
for(int i=0;i<30;i++){
//ContentValuesにデータを入れる
ContentValues values=new ContentValues();
values.put("username","username:"+String.valueOf(i));
values.put("email","testemail:"+String.valueOf(i)+"@gmail.com");
getContentResolver().insert(uri,values);//MyContentsProviderのinsertを実行
Log.d("mainActivity",uri.getPathSegments().get(0));
}
}
public void query(){
//テーブルのデータを全件表示.
Cursor c= getContentResolver().query(uri, null, null, null, null);
while (c.moveToNext()) {
int id=0;
String username="";
String email="";
id = c.getInt(c.getColumnIndex("id"));
username=c.getString(c.getColumnIndex("username"));
email = c.getString(c.getColumnIndex("email"));
Log.d("DB_TESTS", "id: " + id + " username: " + username + " email: " + email);
}
c.close();//カーソルを閉じる
}
public void update(){
ContentValues values=new ContentValues();
values.put("username","username:"+String.valueOf("abc"));
values.put("email","testemail:"+String.valueOf("1")+"@gmail.com");
getContentResolver().update(uri,values,"id=7",null);
}
public void delete(){
getContentResolver().delete(uri,"id=5",null);
}
}
ContentValuesは(key,value)の形式でputします。
またgetContentsResolverでコンテンツプロバイダの取得ができます。
さらに大事なポイントとして、URIは一意に決めなければなりません。
また他のアプリから、DBにアクセスする場合は、このURIを指定してあげれば、
データを操作することが可能になります。
Uriの形式は"contens://authorities/テーブル名"
です。
またauthoritiesはManifestファイルに記述しなければなりません。
Permission
最後にContentsProviderはPermission設定が必要なので、設定します。
<provider
android:name=".MyContentProvider"
android:authorities="com.example.main"
android:enabled="true"
android:exported="true"></provider>
これをapplicationタグ内に記述してください。
またexportedをtrueにしないと、他のアプリからデータを使用できないので、
ご注意を
最後に
これで、どのアプリからでもURIを指定してやれば、共通のDBを使用することができます。
電話帳やメモなどに有効そうですね。
間違っている点や、わからない点がありましたら、言ってください。