SQLiteの使い方がわかったら次はContentProviderですよね。 ということで、SQLの部分はさくっと実装。
using Android.Content; using Android.Database.Sqlite; namespace ContentProviderSample { publicclass PeopleDatabase : SQLiteOpenHelper { privateconststring DbName = "people.db"; privateconststring TableName = "People"; privateconststring CreateTable = @" create table People ( _id integer primary key autoincrement, name varchar(150) );"; privateconstint DatabaseVersion = 2; public PeopleDatabase(Context context) : base(context, DbName, new PeopleCursorFactory(), DatabaseVersion) { } publicoverridevoid OnCreate(SQLiteDatabase db) { db.ExecSQL(CreateTable); for (int i = 0; i < 100; i++) { var c = new ContentValues(); c.Put("name", "tanaka" + i); db.Insert(TableName, null, c); } } publicoverridevoid OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public PeopleCursor GetAll() { return (PeopleCursor) this.ReadableDatabase.Query(TableName, new[] { "_id", "name" }, null, null, null, null, "_id"); } public PeopleCursor GetOne(long id) { return (PeopleCursor) this.ReadableDatabase.Query(TableName, new[] { "_id", "name" }, "_id = ?", new[] { id.ToString() }, null, null, null); } } publicclass PeopleCursor : SQLiteCursor { public PeopleCursor(ISQLiteCursorDriver driver, string editTable, SQLiteQuery query) : base(driver, editTable, query) { } publiclong Id { get { returnthis.GetLong(this.GetColumnIndex("_id")); } } publicstring Name { get { returnthis.GetString(this.GetColumnIndex("name")); } } } publicclass PeopleCursorFactory : Java.Lang.Object, SQLiteDatabase.ICursorFactory { public Android.Database.ICursor NewCursor(SQLiteDatabase db, ISQLiteCursorDriver masterQuery, string editTable, SQLiteQuery query) { returnnew PeopleCursor(masterQuery, editTable, query); } } }
ContentProvider
コンテンツプロバイダーを作っておくと、いろいろ便利らしいので、作っておきます。
using Android.Content; using System; namespace ContentProviderSample { // Authorityを属性で設定する [ContentProvider(new[] { Authority })] publicclass PeopleContentProvider : ContentProvider { // URI組立に必要な人たちprivateconststring Authority = "com.example.PeopleProvider"; privateconststring BasePath = "people"; publicstaticreadonly Android.Net.Uri ContentUri = Android.Net.Uri.Parse("content://" + Authority + "/" + BasePath); // Mimeprivateconststring MimeType = "/vnd.com.example.People"; // UriMatcherのマッチ結果privateconstint GetAll = 0; privateconstint GetOne = 1; privatestaticreadonly UriMatcher UriMatcher = CreateUriMatcher(); // UriMatcherを生成するprivatestatic UriMatcher CreateUriMatcher() { var r = new UriMatcher(UriMatcher.NoMatch); r.AddURI(Authority, BasePath, GetAll); r.AddURI(Authority, BasePath + "/#", GetOne); return r; } private PeopleDatabase db; // 列名の定数publicstaticclass PeopleColumns { publicconststring Id = "_id"; publicconststring Name = "name"; } // 削除。とりあえず未実装publicoverrideint Delete(Android.Net.Uri uri, string selection, string[] selectionArgs) { thrownew NotImplementedException(); } // Uriに応じてMimeを返す。今回は同じもの返すpublicoverridestring GetType(Android.Net.Uri uri) { switch (UriMatcher.Match(uri)) { case GetAll: case GetOne: return MimeType; default: thrownew Java.Lang.IllegalArgumentException(); } } // 挿入。とりあえず未実装publicoverride Android.Net.Uri Insert(Android.Net.Uri uri, ContentValues values) { thrownew NotImplementedException(); } // 作成時の処理。とりあえずDB作るpublicoverridebool OnCreate() { this.db = new PeopleDatabase(this.Context); returntrue; } // Uriを判別して全件返すか一件返すか処理をわけるpublicoverride Android.Database.ICursor Query(Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder) { switch (UriMatcher.Match(uri)) { case GetAll: returnthis.db.GetAll(); case GetOne: returnthis.db.GetOne(long.Parse(uri.LastPathSegment)); default: thrownew Java.Lang.IllegalArgumentException(); } } // 更新。とりあえず未実装publicoverrideint Update(Android.Net.Uri uri, ContentValues values, string selection, string[] selectionArgs) { thrownew NotImplementedException(); } } }
なんか定型でめんどくさい感じがしますね。
使う
ListViewにとりあえず表示してみようと思います。
using Android.App; using Android.Content; using Android.Database; using Android.OS; using Android.Widget; namespace ContentProviderSample { [Activity(Label = "ContentProviderSample", MainLauncher = true, Icon = "@drawable/icon")] publicclass MainActivity : Activity { protectedoverridevoid OnCreate(Bundle bundle) { base.OnCreate(bundle); // Set our view from the "main" layout resourcethis.SetContentView(Resource.Layout.Main); // ListViewを取得して var listView = this.FindViewById<ListView>(Resource.Id.Main_ListViewPeople); // 取得する列名を指定してstring[] projection = new[] { PeopleContentProvider.PeopleColumns.Id, PeopleContentProvider.PeopleColumns.Name }; // 表示列を指定string[] fromColumns = new[] { PeopleContentProvider.PeopleColumns.Name }; // 表示先コントロールのIDを指定int[] toControlIds = new[] { Android.Resource.Id.Text1 }; // コンテンツプロバイダーからデータを読み込む var loader = new CursorLoader(this, PeopleContentProvider.ContentUri, projection, null, null, null); var cursor = loader.LoadInBackground() as ICursor; // カーソルを使うアダプタを作って、ListViewに設定 var adapter = new SimpleCursorAdapter(this, Android.Resource.Layout.SimpleListItem1, cursor, fromColumns, toControlIds); listView.Adapter = adapter; } } }
見事表示できた。