I am having problems with acquiring proper uriType
on Jellybean 4.2.2.
The code given below works fine on other versions.
package com.karacraft.security;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.karacraft.data.ItemsContract;
import com.karacraft.data.MasterSahabDatabaseHelper;
import com.karacraft.data.MerchandisesContract;
import com.karacraft.data.OrdersContract;
import com.karacraft.data.StaffContract;
import com.karacraft.data.StatsContract;
import com.karacraft.data.SuitsContract;
import com.karacraft.data.TailorsContract;
import com.karacraft.utils.Constants;
public class MasterSahabProvider extends ContentProvider
{
public static final String AUTHORITY ="com.karacraft.security.mastersahab";
public static final String KEY_URI = "/#";
//database
private MasterSahabDatabaseHelper database;
//Table Names
private static final String ITEMS_TABLE = "/" + ItemsContract.TABLE_ITEMS;
private static final String MERCHANDISES_TABLE = "/" + MerchandisesContract.TABLE_MERCHANDISES;
private static final String ORDERS_TABLE = "/" + OrdersContract.TABLE_ORDERS;
private static final String SUITS_TABLE = "/" + SuitsContract.TABLE_SUITS;
private static final String TAILORS_TABLE = "/" + TailorsContract.TABLE_TAILORS;
private static final String STAFF_TABLE = "/" + StaffContract.TABLE_STAFF;
private static final String STATS_TABLE = "/" + StatsContract.TABLE_STATS;
//Uri for Multiple Tables
public static final Uri CONTENT_URI_ITEMS = Uri.parse("content://" + AUTHORITY + ITEMS_TABLE);
public static final Uri CONTENT_URI_MERCHANDISES = Uri.parse("content://" + AUTHORITY + MERCHANDISES_TABLE);
public static final Uri CONTENT_URI_ORDERS = Uri.parse("content://" + AUTHORITY + ORDERS_TABLE);
public static final Uri CONTENT_URI_SUITS = Uri.parse("content://" + AUTHORITY + SUITS_TABLE);
public static final Uri CONTENT_URI_TAILORS = Uri.parse("content://" + AUTHORITY + TAILORS_TABLE);
public static final Uri CONTENT_URI_STAFF = Uri.parse("content://" + AUTHORITY + STAFF_TABLE);
public static final Uri CONTENT_URI_STATS = Uri.parse("content://" + AUTHORITY + STATS_TABLE);
public static final Uri CONTENT_URI_ORDERS_BY_MERC = Uri.parse("content://" + AUTHORITY + ORDERS_TABLE);
//Return value setup for Uri Matchers
private static final int ITEMS = 10;
private static final int ITEM_ID = 20;
private static final int MERCHANDISES = 30;
private static final int MERCHANDISE_ID = 40;
private static final int ORDERS = 50;
private static final int ORDERS_ID = 60;
private static final int SUITS = 70;
private static final int SUITS_ID = 80;
private static final int TAILORS = 90;
private static final int TAILORS_ID = 100;
private static final int STAFF = 110;
private static final int STAFF_ID = 120;
private static final int STATS = 130;
private static final int STATS_ID = 140;
private static final int ORDERS_BY_MERC = 200;
//Custom Method
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, ITEMS_TABLE,ITEMS);
uriMatcher.addURI(AUTHORITY, ITEMS_TABLE + KEY_URI,ITEM_ID);
uriMatcher.addURI(AUTHORITY, MERCHANDISES_TABLE,MERCHANDISES);
uriMatcher.addURI(AUTHORITY, MERCHANDISES_TABLE + KEY_URI,MERCHANDISE_ID);
uriMatcher.addURI(AUTHORITY, ORDERS_TABLE,ORDERS);
uriMatcher.addURI(AUTHORITY, ORDERS_TABLE + KEY_URI,ORDERS_ID);
uriMatcher.addURI(AUTHORITY, SUITS_TABLE,SUITS);
uriMatcher.addURI(AUTHORITY, SUITS_TABLE + KEY_URI,SUITS_ID);
uriMatcher.addURI(AUTHORITY, TAILORS_TABLE,TAILORS);
uriMatcher.addURI(AUTHORITY, TAILORS_TABLE + KEY_URI,TAILORS_ID);
uriMatcher.addURI(AUTHORITY, STAFF_TABLE , STAFF);
uriMatcher.addURI(AUTHORITY, STAFF_TABLE + KEY_URI, STAFF_ID);
uriMatcher.addURI(AUTHORITY, STATS_TABLE , STATS);
uriMatcher.addURI(AUTHORITY, STATS_TABLE + KEY_URI, STATS_ID);
uriMatcher.addURI(AUTHORITY,ORDERS_TABLE ,ORDERS);
}
public boolean onCreate()
{
//Create Database
database = new MasterSahabDatabaseHelper(getContext());
return false;
}
/**
URI uri The URI of the object(s) to access. This is the only argument that must not be null
String[] projection This String array indicates which columns/attributes of the objects you want to access
String selection With this argument you can determine which records to return
String[] selectionArgs The binding parameters to the previous selection argument
String sortOrder If the result should be ordered you must use this argument to determine the sort order
*/
@Nullable
@Override
public Cursor query(Uri uri
, String[] projection
, String selection
, String[] selectionArgs
, String sortOrder)
{
//Using SQLiteQueryBuilder instead of query() method
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor=null;
int uriType = uriMatcher.match(uri);
Log.d(Constants.APP_TAG,"URIType is : " + uriType);
Log.d(Constants.APP_TAG,"URI is : " + uri.toString());
switch (uriType){
case ITEMS:
//Set the table
builder.setTables(ItemsContract.TABLE_ITEMS);
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case ITEM_ID:
//Set the table
builder.setTables(ItemsContract.TABLE_ITEMS);
//adding the ID to original Query
builder.appendWhere(ItemsContract.ITEM_ID + "=" + uri.getLastPathSegment());
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(), uri);
break;
case MERCHANDISES:
//Set the table
builder.setTables(MerchandisesContract.TABLE_MERCHANDISES);
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case MERCHANDISE_ID:
//Set the table
builder.setTables(MerchandisesContract.TABLE_MERCHANDISES);
//adding the ID to original Query
builder.appendWhere(MerchandisesContract.MERCHANDISE_ID + "=" + uri.getLastPathSegment());
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case ORDERS:
//Set the table
builder.setTables(OrdersContract.TABLE_ORDERS);
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case ORDERS_ID:
//Set the table
builder.setTables(OrdersContract.TABLE_ORDERS);
//adding the ID to original Query
builder.appendWhere(OrdersContract.ORDER_ID + "=" + uri.getLastPathSegment());
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case TAILORS:
//Set the table
builder.setTables(TailorsContract.TABLE_TAILORS);
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case TAILORS_ID:
//Set the table
builder.setTables(TailorsContract.TABLE_TAILORS);
//adding the ID to original Query
builder.appendWhere(TailorsContract.TAILOR_ID + "=" + uri.getLastPathSegment());
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case SUITS:
//Set the table
builder.setTables(SuitsContract.TABLE_SUITS);
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case SUITS_ID:
//Set the table
builder.setTables(SuitsContract.TABLE_SUITS);
//adding the ID to original Query
builder.appendWhere(SuitsContract.SUITS_ID + "=" + uri.getLastPathSegment());
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case STAFF:
//Set the table
builder.setTables(StaffContract.TABLE_STAFF);
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case STAFF_ID:
//Set the table
builder.setTables(StaffContract.TABLE_STAFF);
//adding the ID to original Query
builder.appendWhere(StaffContract.STAFF_ID + "=" + uri.getLastPathSegment());
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case STATS:
//Set the table
builder.setTables(StatsContract.TABLE_STATS);
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case STATS_ID:
//Set the table
builder.setTables(StatsContract.TABLE_STATS);
//adding the ID to original Query
builder.appendWhere(StatsContract.STATS_ID + "=" + uri.getLastPathSegment());
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
break;
case ORDERS_BY_MERC:
//Set the table
//builder.setTables("orders LEFT OUTER JOIN staff ON (orders.staff_id = staff._id)");
builder.setTables("orders LEFT OUTER JOIN staff ON orders.staff_id = staff._id");
//builder.setTables("orders,staff");
//adding the ID to original Query
cursor = builder.query(db,projection,selection,selectionArgs,null,null,sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(),uri);
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
return cursor;
}
@Nullable
@Override
public String getType(Uri uri)
{
return null;
}
@Nullable
@Override
public Uri insert(Uri uri
, ContentValues values)
{
int uriType = uriMatcher.match(uri);
SQLiteDatabase db = database.getWritableDatabase();
Log.d(Constants.APP_TAG,"URIType is : " + uriType);
Log.d(Constants.APP_TAG,"URI is : " + uri.toString());
long id = 0;
switch (uriType){
case ITEMS:
id = db.insert(ItemsContract.TABLE_ITEMS, null, values);
getContext().getContentResolver().notifyChange(uri,null);
return Uri.parse(ITEMS_TABLE + "/" + id);
case MERCHANDISES:
id = db.insert(MerchandisesContract.TABLE_MERCHANDISES,null,values);
getContext().getContentResolver().notifyChange(uri,null);
return Uri.parse(MERCHANDISES_TABLE + "/" + id);
case ORDERS:
id = db.insert(OrdersContract.TABLE_ORDERS,null,values);
getContext().getContentResolver().notifyChange(uri,null);
return Uri.parse(ORDERS_TABLE + "/" + id);
case SUITS:
id = db.insert(SuitsContract.TABLE_SUITS,null,values);
getContext().getContentResolver().notifyChange(uri,null);
return Uri.parse(SUITS_TABLE + "/" + id);
case STAFF:
id = db.insert(StaffContract.TABLE_STAFF,null, values);
getContext().getContentResolver().notifyChange(uri,null);
return Uri.parse(STAFF_TABLE + "/" + id);
case TAILORS:
id = db.insert(TailorsContract.TABLE_TAILORS,null,values);
getContext().getContentResolver().notifyChange(uri,null);
return Uri.parse(TAILORS_TABLE + "/" + id);
case STATS:
id = db.insert(StatsContract.TABLE_STATS,null,values);
getContext().getContentResolver().notifyChange(uri,null);
return Uri.parse(STATS_TABLE + "/" + id);
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public int delete(Uri uri
, String selection
, String[] selectionArgs)
{
int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
String id ="";
Log.d(Constants.APP_TAG,"URIType is : " + uriType);
Log.d(Constants.APP_TAG,"URI is : " + uri.toString());
switch (uriType) {
case ITEMS:
rowsDeleted = sqlDB.delete(ItemsContract.TABLE_ITEMS, selection, selectionArgs);
break;
case ITEM_ID:
id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(ItemsContract.TABLE_ITEMS, ItemsContract.ITEM_ID + "=" + id, null);
} else {
rowsDeleted = sqlDB.delete(ItemsContract.TABLE_ITEMS, ItemsContract.ITEM_ID + "=" + id + " AND " + selection, selectionArgs);
}
break;
case MERCHANDISES:
rowsDeleted = sqlDB.delete(MerchandisesContract.TABLE_MERCHANDISES, selection, selectionArgs);
break;
case MERCHANDISE_ID:
id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(MerchandisesContract.TABLE_MERCHANDISES, MerchandisesContract.MERCHANDISE_ID+ "=" + id, null);
} else {
rowsDeleted = sqlDB.delete(MerchandisesContract.TABLE_MERCHANDISES, MerchandisesContract.MERCHANDISE_ID + "=" + id + " AND " + selection, selectionArgs);
}
break;
case TAILORS:
rowsDeleted = sqlDB.delete(TailorsContract.TABLE_TAILORS, selection, selectionArgs);
break;
case TAILORS_ID:
id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(TailorsContract.TABLE_TAILORS, TailorsContract.TAILOR_ID + "=" + id, null);
} else {
rowsDeleted = sqlDB.delete(TailorsContract.TABLE_TAILORS, TailorsContract.TAILOR_ID + "=" + id + " AND " + selection, selectionArgs);
}
break;
case STAFF:
rowsDeleted = sqlDB.delete(StaffContract.TABLE_STAFF, selection, selectionArgs);
break;
case STAFF_ID:
id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(StaffContract.TABLE_STAFF, StaffContract.STAFF_ID + "=" + id, null);
} else {
rowsDeleted = sqlDB.delete(StaffContract.TABLE_STAFF, StaffContract.STAFF_ID + "=" + id + " AND " + selection, selectionArgs);
}
break;
case SUITS:
rowsDeleted = sqlDB.delete(SuitsContract.TABLE_SUITS, selection, selectionArgs);
break;
case SUITS_ID:
id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(SuitsContract.TABLE_SUITS, SuitsContract.SUITS_ID + "=" + id, null);
} else {
rowsDeleted = sqlDB.delete(SuitsContract.TABLE_SUITS, SuitsContract.SUITS_ID + "=" + id + " AND " + selection, selectionArgs);
}
break;
case ORDERS:
rowsDeleted = sqlDB.delete(OrdersContract.TABLE_ORDERS, selection, selectionArgs);
break;
case ORDERS_ID:
id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(OrdersContract.TABLE_ORDERS, OrdersContract.ORDER_ID + "=" + id, null);
} else {
rowsDeleted = sqlDB.delete(OrdersContract.TABLE_ORDERS, OrdersContract.ORDER_ID + "=" + id + " AND " + selection, selectionArgs);
}
break;
case STATS:
rowsDeleted = sqlDB.delete(StatsContract.TABLE_STATS, selection, selectionArgs);
break;
case STATS_ID:
id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(StatsContract.TABLE_STATS, StatsContract.STATS_ID + "=" + id, null);
} else {
rowsDeleted = sqlDB.delete(StatsContract.TABLE_STATS, StatsContract.STATS_ID + "=" + id + " AND " + selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
@Override
public int update(Uri uri
, ContentValues values
, String selection
, String[] selectionArgs)
{
int uriType = uriMatcher.match(uri);
SQLiteDatabase db = database.getWritableDatabase();
int rowsUpdated=0;
Log.d(Constants.APP_TAG,"URIType is : " + uriType);
Log.d(Constants.APP_TAG,"URI is : " + uri.toString());
switch (uriType){
case ITEMS:
rowsUpdated = db.update(ItemsContract.TABLE_ITEMS,values,selection,selectionArgs);
break;
case ITEM_ID:
String id = uri.getLastPathSegment();
if(TextUtils.isEmpty(selection)){
rowsUpdated = db.update(ItemsContract.TABLE_ITEMS,values, ItemsContract.ITEM_ID + "=" + id,null);
}else{
rowsUpdated = db.update(ItemsContract.TABLE_ITEMS,values, ItemsContract.ITEM_ID + "=" + id + " AND " + selection,selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri,null);
return rowsUpdated;
}
}
I've checked the above content provider code with Emulators and physical sets, and all are working fine (I've tried it on 5.0, 5.1 and 6.0 emulator).
And here is the Logcat For (JellyBean 4.2.2):
02-20 21:12:27.480 1796-1808/? D/PTI: URIType is : -1
02-20 21:12:27.480 1796-1808/? D/PTI: URI is : content://com.karacraft.security.mastersahab/items
02-20 21:12:27.480 1796-1808/? E/DatabaseUtils: Writing exception to parcel
java.lang.IllegalArgumentException: Unknown URI: content://com.karacraft.security.mastersahab/items
at com.karacraft.security.MasterSahabProvider.query(MasterSahabProvider.java:260)
at android.content.ContentProvider.query(ContentProvider.java:652)
at android.content.ContentProvider$Transport.query(ContentProvider.java:189)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:113)
at android.os.Binder.execTransact(Binder.java:351)
at dalvik.system.NativeStart.run(Native Method)
On other systems, URI always comes out as intended.
Here is Logcat for KitKat 4.4.4:
02-21 01:06:51.591 1872-1884/? D/PTI: URIType is : 10
02-21 01:06:51.591 1872-1884/? D/PTI: URI is : content://com.karacraft.security.mastersahab/items
02-21 01:06:51.631 1872-1883/? D/PTI: URIType is : 50
02-21 01:06:51.631 1872-1883/? D/PTI: URI is : content://com.karacraft.security.mastersahab/orders
02-21 01:06:51.631 1872-1884/? D/PTI: URIType is : 70
02-21 01:06:51.631 1872-1884/? D/PTI: URI is : content://com.karacraft.security.mastersahab/suits
02-21 01:06:51.631 1872-1883/? D/PTI: URIType is : 90
02-21 01:06:51.631 1872-1883/? D/PTI: URI is : content://com.karacraft.security.mastersahab/tailors
02-21 01:06:51.631 1872-1884/? D/PTI: URIType is : 130
02-21 01:06:51.631 1872-1884/? D/PTI: URI is : content://com.karacraft.security.mastersahab/stats
02-21 01:06:51.641 1872-1883/? D/PTI: URIType is : 110
02-21 01:06:51.641 1872-1883/? D/PTI: URI is : content://com.karacraft.security.mastersahab/staff
02-21 01:06:51.641 1872-1884/? D/PTI: URIType is : 30
02-21 01:06:51.641 1872-1884/? D/PTI: URI is : content://com.karacraft.security.mastersahab/merchandises
It's showing proper URI's on Kitkat.
Changing the Leading Slash from Table Name to URI solved the problem.
//Table Names
private static final String ITEMS_TABLE = "/" + ItemsContract.TABLE_ITEMS;
private static final String MERCHANDISES_TABLE = "/" + MerchandisesContract.TABLE_MERCHANDISES;
private static final String ORDERS_TABLE = "/" + OrdersContract.TABLE_ORDERS;
private static final String SUITS_TABLE = "/" + SuitsContract.TABLE_SUITS;
private static final String TAILORS_TABLE = "/" + TailorsContract.TABLE_TAILORS;
private static final String STAFF_TABLE = "/" + StaffContract.TABLE_STAFF;
private static final String STATS_TABLE = "/" + StatsContract.TABLE_STATS;
//Uri for Multiple Tables
public static final Uri CONTENT_URI_ITEMS = Uri.parse("content://" + AUTHORITY + ITEMS_TABLE);
public static final Uri CONTENT_URI_MERCHANDISES = Uri.parse("content://" + AUTHORITY + MERCHANDISES_TABLE);
public static final Uri CONTENT_URI_ORDERS = Uri.parse("content://" + AUTHORITY + ORDERS_TABLE);
public static final Uri CONTENT_URI_SUITS = Uri.parse("content://" + AUTHORITY + SUITS_TABLE);
public static final Uri CONTENT_URI_TAILORS = Uri.parse("content://" + AUTHORITY + TAILORS_TABLE);
public static final Uri CONTENT_URI_STAFF = Uri.parse("content://" + AUTHORITY + STAFF_TABLE);
public static final Uri CONTENT_URI_STATS = Uri.parse("content://" + AUTHORITY + STATS_TABLE);
This
//Table Names
private static final String ITEMS_TABLE = ItemsContract.TABLE_ITEMS;
private static final String MERCHANDISES_TABLE = MerchandisesContract.TABLE_MERCHANDISES;
private static final String ORDERS_TABLE = OrdersContract.TABLE_ORDERS;
private static final String SUITS_TABLE = SuitsContract.TABLE_SUITS;
private static final String TAILORS_TABLE = TailorsContract.TABLE_TAILORS;
private static final String STAFF_TABLE = StaffContract.TABLE_STAFF;
private static final String STATS_TABLE = StatsContract.TABLE_STATS;
//Uri for Multiple Tables
public static final Uri CONTENT_URI_ITEMS = Uri.parse("content://" + AUTHORITY + "/" + ITEMS_TABLE);
public static final Uri CONTENT_URI_MERCHANDISES = Uri.parse("content://" + AUTHORITY + "/" +MERCHANDISES_TABLE);
public static final Uri CONTENT_URI_ORDERS = Uri.parse("content://" + AUTHORITY + "/" +ORDERS_TABLE);
public static final Uri CONTENT_URI_SUITS = Uri.parse("content://" + AUTHORITY + "/" +SUITS_TABLE);
public static final Uri CONTENT_URI_TAILORS = Uri.parse("content://" + AUTHORITY + "/" +TAILORS_TABLE);
public static final Uri CONTENT_URI_STAFF = Uri.parse("content://" + AUTHORITY + "/" +STAFF_TABLE);
public static final Uri CONTENT_URI_STATS = Uri.parse("content://" + AUTHORITY + "/" +STATS_TABLE);
Support for paths with leading slashes has been added in Android 4.3. See the description of addUri, which states
Starting from API level JELLY_BEAN_MR2, this method will accept a leading slash in the path.
So just remove the leading slashes in your paths.
i.e. replace
uriMatcher.addURI(AUTHORITY, ITEMS_TABLE,ITEMS);
by
uriMatcher.addURI(AUTHORITY, ItemsContract.TABLE_ITEMS);
btw. the last case
statement in your query
method is missing a break;
which means that Uri
will always throw an exception.