16b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn/* 26b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project 36b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * 46b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 56b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * you may not use this file except in compliance with the License. 66b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * You may obtain a copy of the License at 76b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * 86b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 96b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * 106b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 116b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 126b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * See the License for the specific language governing permissions and 146b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * limitations under the License. 156b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 166b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1710c33528e033643099783a5bc4eedb4b8a1e9a0eDianne Hackbornpackage com.example.android.supportv4.app; 186b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 196b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn//BEGIN_INCLUDE(complete) 206b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.content.ContentProvider; 216b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.content.ContentResolver; 226b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.content.ContentUris; 236b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.content.ContentValues; 246b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.content.Context; 256b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.content.UriMatcher; 266b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.database.Cursor; 276b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.database.SQLException; 286b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.database.sqlite.SQLiteDatabase; 296b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.database.sqlite.SQLiteOpenHelper; 306b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.database.sqlite.SQLiteQueryBuilder; 316b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.net.Uri; 326b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.os.AsyncTask; 336b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.os.Bundle; 346b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.provider.BaseColumns; 35a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.app.FragmentActivity; 36a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.app.FragmentManager; 37a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.app.ListFragment; 38a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.app.LoaderManager; 39a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.content.CursorLoader; 40a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.content.Loader; 41a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.database.DatabaseUtilsCompat; 42a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.view.MenuItemCompat; 43a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganovimport android.support.v4.widget.SimpleCursorAdapter; 446b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.text.TextUtils; 456b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.util.Log; 466b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.view.Menu; 476b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.view.MenuInflater; 486b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.view.MenuItem; 496b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.view.View; 506b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport android.widget.ListView; 516b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 526b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornimport java.util.HashMap; 536b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 546b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn/** 556b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Demonstration of bottom to top implementation of a content provider holding 566b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * structured data through displaying it in the UI, using throttling to reduce 576b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * the number of queries done when its data changes. 586b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 596b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackbornpublic class LoaderThrottleSupport extends FragmentActivity { 606b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Debugging. 616b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn static final String TAG = "LoaderThrottle"; 626b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 636b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 646b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * The authority we use to get to our sample provider. 656b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 667ffb7d4b2face7d2ce5cee82c92ec36fd0ba2932Dianne Hackborn public static final String AUTHORITY = "com.example.android.apis.supportv4.app.LoaderThrottle"; 676b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 686b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 696b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Definition of the contract for the main table of our provider. 706b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 716b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final class MainTable implements BaseColumns { 726b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 736b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // This class cannot be instantiated 746b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private MainTable() {} 756b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 766b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 776b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * The table name offered by this provider 786b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 796b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final String TABLE_NAME = "main"; 806b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 816b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 826b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * The content:// style URL for this table 836b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 846b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/main"); 856b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 866b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 876b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * The content URI base for a single row of data. Callers must 886b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * append a numeric row id to this Uri to retrieve a row 896b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 906b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final Uri CONTENT_ID_URI_BASE 916b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn = Uri.parse("content://" + AUTHORITY + "/main/"); 926b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 936b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 946b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * The MIME type of {@link #CONTENT_URI}. 956b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 966b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final String CONTENT_TYPE 976b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn = "vnd.android.cursor.dir/vnd.example.api-demos-throttle"; 986b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 996b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1006b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * The MIME type of a {@link #CONTENT_URI} sub-directory of a single row. 1016b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1026b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final String CONTENT_ITEM_TYPE 1036b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn = "vnd.android.cursor.item/vnd.example.api-demos-throttle"; 1046b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1056b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * The default sort order for this table 1066b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1076b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final String DEFAULT_SORT_ORDER = "data COLLATE LOCALIZED ASC"; 1086b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1096b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1106b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Column name for the single column holding our data. 1116b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * <P>Type: TEXT</P> 1126b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1136b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static final String COLUMN_NAME_DATA = "data"; 1146b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 1156b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1166b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1176b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * This class helps open, create, and upgrade the database file. 1186b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1196b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn static class DatabaseHelper extends SQLiteOpenHelper { 1206b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1216b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private static final String DATABASE_NAME = "loader_throttle.db"; 1226b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private static final int DATABASE_VERSION = 2; 1236b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1246b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn DatabaseHelper(Context context) { 1256b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1266b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // calls the super constructor, requesting the default cursor factory. 1276b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn super(context, DATABASE_NAME, null, DATABASE_VERSION); 1286b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 1296b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1306b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1316b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * 1326b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Creates the underlying database with table name and column names taken from the 1336b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * NotePad class. 1346b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1356b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 1366b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public void onCreate(SQLiteDatabase db) { 1376b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn db.execSQL("CREATE TABLE " + MainTable.TABLE_NAME + " (" 1386b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn + MainTable._ID + " INTEGER PRIMARY KEY," 1396b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn + MainTable.COLUMN_NAME_DATA + " TEXT" 1406b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn + ");"); 1416b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 1426b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1436b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1446b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * 1456b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Demonstrates that the provider must consider what happens when the 1466b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * underlying datastore is changed. In this sample, the database is upgraded the database 1476b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * by destroying the existing data. 1486b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * A real application should upgrade the database in place. 1496b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1506b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 1516b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 1526b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1536b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Logs that the database is being upgraded 1546b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn Log.w(TAG, "Upgrading database from version " + oldVersion + " to " 1556b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn + newVersion + ", which will destroy all old data"); 1566b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1576b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Kills the table and existing data 1586b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn db.execSQL("DROP TABLE IF EXISTS notes"); 1596b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1606b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Recreates the database with a new version 1616b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn onCreate(db); 1626b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 1636b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 1646b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1656b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1666b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * A very simple implementation of a content provider. 1676b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1686b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static class SimpleProvider extends ContentProvider { 1696b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // A projection map used to select columns from the database 1706b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private final HashMap<String, String> mNotesProjectionMap; 1716b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Uri matcher to decode incoming URIs. 1726b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private final UriMatcher mUriMatcher; 1736b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1746b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // The incoming URI matches the main table URI pattern 1756b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private static final int MAIN = 1; 1766b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // The incoming URI matches the main table row ID URI pattern 1776b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private static final int MAIN_ID = 2; 1786b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1796b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Handle to a new DatabaseHelper. 1806b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn private DatabaseHelper mOpenHelper; 1816b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1826b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1836b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Global provider initialization. 1846b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 1856b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public SimpleProvider() { 1866b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Create and initialize URI matcher. 1876b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 1886b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME, MAIN); 1896b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME + "/#", MAIN_ID); 1906b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1916b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Create and initialize projection map for all columns. This is 1926b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // simply an identity mapping. 1936b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mNotesProjectionMap = new HashMap<String, String>(); 1946b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mNotesProjectionMap.put(MainTable._ID, MainTable._ID); 1956b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mNotesProjectionMap.put(MainTable.COLUMN_NAME_DATA, MainTable.COLUMN_NAME_DATA); 1966b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 1976b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 1986b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 1996b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Perform provider creation. 2006b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 2016b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 2026b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public boolean onCreate() { 2036b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mOpenHelper = new DatabaseHelper(getContext()); 2046b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Assumes that any failures will be reported by a thrown exception. 2056b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return true; 2066b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2076b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2086b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 2096b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Handle incoming queries. 2106b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 2116b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 2126b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public Cursor query(Uri uri, String[] projection, String selection, 2136b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn String[] selectionArgs, String sortOrder) { 2146b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2156b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Constructs a new query builder and sets its table name 2166b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 2176b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn qb.setTables(MainTable.TABLE_NAME); 2186b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2196b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn switch (mUriMatcher.match(uri)) { 2206b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN: 2216b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If the incoming URI is for main table. 2226b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn qb.setProjectionMap(mNotesProjectionMap); 2236b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn break; 2246b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2256b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN_ID: 2266b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // The incoming URI is for a single row. 2276b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn qb.setProjectionMap(mNotesProjectionMap); 2286b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn qb.appendWhere(MainTable._ID + "=?"); 229a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov selectionArgs = DatabaseUtilsCompat.appendSelectionArgs(selectionArgs, 2306b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn new String[] { uri.getLastPathSegment() }); 2316b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn break; 2326b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2336b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn default: 2346b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn throw new IllegalArgumentException("Unknown URI " + uri); 2356b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2366b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2376b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2386b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (TextUtils.isEmpty(sortOrder)) { 2396b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn sortOrder = MainTable.DEFAULT_SORT_ORDER; 2406b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2416b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2426b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 2436b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2446b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn Cursor c = qb.query(db, projection, selection, selectionArgs, 2456b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn null /* no group */, null /* no filter */, sortOrder); 2466b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2476b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn c.setNotificationUri(getContext().getContentResolver(), uri); 2486b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return c; 2496b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2506b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2516b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 2526b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Return the MIME type for an known URI in the provider. 2536b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 2546b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 2556b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public String getType(Uri uri) { 2566b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn switch (mUriMatcher.match(uri)) { 2576b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN: 2586b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return MainTable.CONTENT_TYPE; 2596b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN_ID: 2606b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return MainTable.CONTENT_ITEM_TYPE; 2616b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn default: 2626b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn throw new IllegalArgumentException("Unknown URI " + uri); 2636b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2646b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2656b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2666b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 2676b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Handler inserting new data. 2686b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 2696b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 2706b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public Uri insert(Uri uri, ContentValues initialValues) { 2716b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (mUriMatcher.match(uri) != MAIN) { 2726b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Can only insert into to main URI. 2736b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn throw new IllegalArgumentException("Unknown URI " + uri); 2746b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2756b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2766b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn ContentValues values; 2776b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2786b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (initialValues != null) { 2796b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn values = new ContentValues(initialValues); 2806b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } else { 2816b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn values = new ContentValues(); 2826b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2836b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2846b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (values.containsKey(MainTable.COLUMN_NAME_DATA) == false) { 2856b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn values.put(MainTable.COLUMN_NAME_DATA, ""); 2866b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2876b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2886b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 2896b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2906b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn long rowId = db.insert(MainTable.TABLE_NAME, null, values); 2916b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2926b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If the insert succeeded, the row ID exists. 2936b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (rowId > 0) { 2946b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn Uri noteUri = ContentUris.withAppendedId(MainTable.CONTENT_ID_URI_BASE, rowId); 2956b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn getContext().getContentResolver().notifyChange(noteUri, null); 2966b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return noteUri; 2976b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 2986b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 2996b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn throw new SQLException("Failed to insert row into " + uri); 3006b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3016b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3026b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 3036b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Handle deleting data. 3046b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 3056b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 3066b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public int delete(Uri uri, String where, String[] whereArgs) { 3076b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 3086b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn String finalWhere; 3096b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3106b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn int count; 3116b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3126b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn switch (mUriMatcher.match(uri)) { 3136b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN: 3146b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If URI is main table, delete uses incoming where clause and args. 3156b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn count = db.delete(MainTable.TABLE_NAME, where, whereArgs); 3166b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn break; 3176b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3186b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If the incoming URI matches a single note ID, does the delete based on the 3196b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // incoming data, but modifies the where clause to restrict it to the 3206b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // particular note ID. 3216b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN_ID: 3226b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If URI is for a particular row ID, delete is based on incoming 3236b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // data but modified to restrict to the given ID. 324a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov finalWhere = DatabaseUtilsCompat.concatenateWhere( 3256b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn MainTable._ID + " = " + ContentUris.parseId(uri), where); 3266b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn count = db.delete(MainTable.TABLE_NAME, finalWhere, whereArgs); 3276b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn break; 3286b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3296b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn default: 3306b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn throw new IllegalArgumentException("Unknown URI " + uri); 3316b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3326b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3336b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn getContext().getContentResolver().notifyChange(uri, null); 3346b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3356b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return count; 3366b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3376b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3386b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn /** 3396b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn * Handle updating data. 3406b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn */ 3416b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 3426b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { 3436b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 3446b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn int count; 3456b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn String finalWhere; 3466b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3476b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn switch (mUriMatcher.match(uri)) { 3486b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN: 3496b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If URI is main table, update uses incoming where clause and args. 3506b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn count = db.update(MainTable.TABLE_NAME, values, where, whereArgs); 3516b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn break; 3526b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3536b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case MAIN_ID: 3546b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If URI is for a particular row ID, update is based on incoming 3556b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // data but modified to restrict to the given ID. 356a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov finalWhere = DatabaseUtilsCompat.concatenateWhere( 3576b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn MainTable._ID + " = " + ContentUris.parseId(uri), where); 3586b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn count = db.update(MainTable.TABLE_NAME, values, finalWhere, whereArgs); 3596b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn break; 3606b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3616b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn default: 3626b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn throw new IllegalArgumentException("Unknown URI " + uri); 3636b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3646b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3656b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn getContext().getContentResolver().notifyChange(uri, null); 3666b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3676b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return count; 3686b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3696b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3706b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3716b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override 3726b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn protected void onCreate(Bundle savedInstanceState) { 3736b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn super.onCreate(savedInstanceState); 3746b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3756b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn FragmentManager fm = getSupportFragmentManager(); 3766b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3776b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Create the list fragment and add it as our sole content. 3786b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (fm.findFragmentById(android.R.id.content) == null) { 3796b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn ThrottledLoaderListFragment list = new ThrottledLoaderListFragment(); 3806b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn fm.beginTransaction().add(android.R.id.content, list).commit(); 3816b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3826b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 3836b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3846b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public static class ThrottledLoaderListFragment extends ListFragment 3856b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn implements LoaderManager.LoaderCallbacks<Cursor> { 3866b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3876b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Menu identifiers 3886b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn static final int POPULATE_ID = Menu.FIRST; 3896b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn static final int CLEAR_ID = Menu.FIRST+1; 3906b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3916b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // This is the Adapter being used to display the list's data. 3926b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn SimpleCursorAdapter mAdapter; 3936b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3946b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // If non-null, this is the current filter the user has provided. 3956b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn String mCurFilter; 3966b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 3976b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Task we have running to populate the database. 3986b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn AsyncTask<Void, Void, Void> mPopulatingTask; 3996b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4006b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override public void onActivityCreated(Bundle savedInstanceState) { 4016b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn super.onActivityCreated(savedInstanceState); 4026b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4036b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn setEmptyText("No data. Select 'Populate' to fill with data from Z to A at a rate of 4 per second."); 4046b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn setHasOptionsMenu(true); 4056b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4066b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Create an empty adapter we will use to display the loaded data. 4076b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mAdapter = new SimpleCursorAdapter(getActivity(), 4086b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn android.R.layout.simple_list_item_1, null, 4096b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn new String[] { MainTable.COLUMN_NAME_DATA }, 4106b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn new int[] { android.R.id.text1 }, 0); 4116b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn setListAdapter(mAdapter); 4126b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 413be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn // Start out with a progress indicator. 414be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn setListShown(false); 415be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn 4166b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Prepare the loader. Either re-connect with an existing one, 4176b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // or start a new one. 4186b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn getLoaderManager().initLoader(0, null, this); 4196b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4206b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4216b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 422a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov MenuItem populateItem = menu.add(Menu.NONE, POPULATE_ID, 0, "Populate"); 423a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov MenuItemCompat.setShowAsAction(populateItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); 424a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov MenuItem clearItem = menu.add(Menu.NONE, CLEAR_ID, 0, "Clear"); 425a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov MenuItemCompat.setShowAsAction(clearItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM); 4266b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4276b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4286b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override public boolean onOptionsItemSelected(MenuItem item) { 4296b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn final ContentResolver cr = getActivity().getContentResolver(); 4306b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4316b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn switch (item.getItemId()) { 4326b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case POPULATE_ID: 4336b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (mPopulatingTask != null) { 4346b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mPopulatingTask.cancel(false); 4356b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4366b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mPopulatingTask = new AsyncTask<Void, Void, Void>() { 4376b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override protected Void doInBackground(Void... params) { 4386b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn for (char c='Z'; c>='A'; c--) { 4396b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (isCancelled()) { 4406b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn break; 4416b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4426b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn StringBuilder builder = new StringBuilder("Data "); 4436b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn builder.append(c); 4446b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn ContentValues values = new ContentValues(); 4456b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn values.put(MainTable.COLUMN_NAME_DATA, builder.toString()); 4466b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn cr.insert(MainTable.CONTENT_URI, values); 4476b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Wait a bit between each insert. 4486b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn try { 4496b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn Thread.sleep(250); 4506b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } catch (InterruptedException e) { 4516b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4526b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4536b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return null; 4546b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4556b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn }; 456a09e21a223dd1db2f3d16c1250f6607b712155dcSvetoslav Ganov mPopulatingTask.execute((Void[]) null); 4576b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return true; 4586b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4596b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn case CLEAR_ID: 4606b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn if (mPopulatingTask != null) { 4616b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mPopulatingTask.cancel(false); 4626b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mPopulatingTask = null; 4636b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4646b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { 4656b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override protected Void doInBackground(Void... params) { 4666b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn cr.delete(MainTable.CONTENT_URI, null, null); 4676b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return null; 4686b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4696b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn }; 4706b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn task.execute((Void[])null); 4716b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return true; 4726b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4736b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn default: 4746b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return super.onOptionsItemSelected(item); 4756b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4766b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4776b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4786b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn @Override public void onListItemClick(ListView l, View v, int position, long id) { 4796b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // Insert desired behavior here. 4806b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn Log.i(TAG, "Item clicked: " + id); 4816b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4826b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4836b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn // These are the rows that we will retrieve. 4846b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn static final String[] PROJECTION = new String[] { 4856b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn MainTable._ID, 4866b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn MainTable.COLUMN_NAME_DATA, 4876b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn }; 4886b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4896b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public Loader<Cursor> onCreateLoader(int id, Bundle args) { 4906b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn CursorLoader cl = new CursorLoader(getActivity(), MainTable.CONTENT_URI, 4916b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn PROJECTION, null, null, null); 4926b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn cl.setUpdateThrottle(2000); // update at most every 2 seconds. 4936b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn return cl; 4946b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 4956b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 4966b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 4976b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mAdapter.swapCursor(data); 498be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn 499be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn // The list should now be shown. 500be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn if (isResumed()) { 501be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn setListShown(true); 502be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn } else { 503be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn setListShownNoAnimation(true); 504be6b6b494f094eea0abcd83eb8770bc4b9f7e34eDianne Hackborn } 5056b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 5066b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn 5076b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn public void onLoaderReset(Loader<Cursor> loader) { 5086b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn mAdapter.swapCursor(null); 5096b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 5106b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn } 5116b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn} 5126b3f9b3ac9327d22e73f4aa2b61e4fb6c3933a33Dianne Hackborn//END_INCLUDE(complete) 513