Sunday, December 2, 2018

Sqlite Example using Content Provider

Step 1: Create a DatabaseHelper

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String TAG = "DatabaseHelper";
    private static DatabaseHelper databaseHelper = null;
    private Context context;
    private File localDb;
    public String backUpFilePath;

    // Logcat tag
    private static final String LOG = DatabaseHelper.class.getName();

    // Database Version
    private static final int DATABASE_VERSION = 1;

    public static void init(Context context) {

        if (databaseHelper == null) {
            databaseHelper = new DatabaseHelper(context);
            Log.i(TAG, "Database init successful");
        } else {
            Log.e(TAG, "Database init already.");
        }
    }

    public static DatabaseHelper getInstance() {
        if (databaseHelper == null) {
            Log.e(TAG, "database is not initialized. call function init(Context) first.");
            throw new NullPointerException();
        }
        return databaseHelper;
    }

    private DatabaseHelper(Context context) {
        super(context, context.getApplicationInfo().packageName + ".db", null, DATABASE_VERSION);
        this.context = context;

        localDb = context.getDatabasePath(context.getApplicationInfo().packageName + ".db");
        //make directory first if not exist
        //backUpFilePath =  FileUtils.makeDirectory("slideit_db") +  "/slideit_db_exported.db";
    }

    public Boolean backUpDatabase() {

        if (isSDCardWritable()) {
            Log.i(TAG, "localDb: " + localDb);
            try {
                // Open your local db as the input stream
                FileInputStream inputStream = new FileInputStream(localDb);

                // Open the empty db as the output stream
                Log.i(TAG, "backUpDb: " + backUpFilePath);
                OutputStream output = new FileOutputStream(backUpFilePath);

                // transfer bytes from the input file to the output file
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    output.write(buffer, 0, length);
                }

                output.flush();
                output.close();
                inputStream.close();
                return true;

            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG, "Error: " + e.getMessage());
                return false;
            }
        } else {
            Log.e(TAG, "SD card not mounted");
            return false;
        }
    }

    private boolean isSDCardWritable() {
        boolean isMounted = false;
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            isMounted = true;
        }
        return isMounted;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(UserDAO.createContactRoom());

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        /****************** DATABASE MIGRATION START ***********************/
        Log.d(TAG, "onUpgrade() from " + oldVersion + " to " + newVersion);

        // NOTE: This switch statement is designed to handle cascading database
        // updates, starting at the current version and falling through to all
        // future upgrade cases. Only use "break;" when you want to drop and
        // recreate the entire database.
//        int version = oldVersion;
//        switch (version) {
//            case 9: // Other app version
//            case 10: // invitation app version
//                // Version 10 added columns for add Offline json to DB.
//                db.execSQL("ALTER TABLE " + SyncDAO.SYNC_HISTORY_TABLE + " ADD //COLUMN " + SyncDAO.KEY_IS_OFFLINE + " INTEGER");
//               db.execSQL("ALTER TABLE " + SyncDAO.SYNC_HISTORY_TABLE + " ADD //COLUMN " + SyncDAO.KEY_OFFLINE_JSON + " TEXT");
//               db.execSQL("ALTER TABLE " + SyncDAO.SYNC_HISTORY_TABLE + " ADD //COLUMN " + SyncDAO.KEY_UPDATED_AT + " DATETIME");
//                version = 11;
//           case 11:
                // Version 11 added table for sync advertisement.
//                db.execSQL(AdvertiseDAO.createAdvertiseTable());
//                version = 12;
//            case 12:
//                db.execSQL("DROP TABLE IF EXISTS " + //PurchaseDAO.PURCHASE_ITEM_TABLE);
//                db.execSQL(PurchaseDAO.createPurchaseItemTbl());
//                version = 13;
//        }

        Log.d(TAG, "after upgrade logic, version is " + version);
//        if (version != DATABASE_VERSION) {
//            Log.w(TAG, "Destroying old data during upgrade");

//            db.execSQL("DROP TABLE IF EXISTS " + UserDAO.USER_MASTER_TABLE);

            // create new tables
 //           onCreate(db);
//        }
        /****************** DATABASE MIGRATION END ***********************/

        /****************** DROP TABLE START ***********************/
        // on upgrade drop older tables
        db.execSQL("DROP TABLE IF EXISTS " + UserDAO.USER_MASTER_TABLE);

        // create new tables
        onCreate(db);

        /****************** DROP TABLE END ***********************/
    }

}

Step 2: Create Content Provider


public class MainCardContentProvider extends ContentProvider {

    private String TAG = "MainCardContentProvider ";

    //buildContentUri(<same_As_in_ProviderUriEnum>) -> must be unique
    public static Uri CONTACT_ROOM_CONTENT_URI;
    
    // database
    private DatabaseHelper database;
    private ProviderUriMatcher mProviderUriMatcher;
    public static Uri BASE_CONTENT_URI;
    private static Context context;

    @Override
    public boolean onCreate() {
        Log.e(TAG, "onCreate()");

        context = getContext();
        DatabaseHelper.init(context);
        database = DatabaseHelper.getInstance();
        mProviderUriMatcher = new ProviderUriMatcher(context);

        BASE_CONTENT_URI = Uri.parse("content://" + context.getString(R.string.app_content_provider));
        Log.i(TAG, "BASE_CONTENT_URI: " + BASE_CONTENT_URI);

        CONTACT_ROOM_CONTENT_URI = buildContentUri(context, UserDAO.USER_MASTER_TABLE);
        

        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        ProviderUriEnum mProviderUriEnum = mProviderUriMatcher.matchUri(uri);

        switch (mProviderUriEnum) {
            case USER:
                queryBuilder.setTables(UserDAO.USER_MASTER_TABLE);
                break;
           
            default:
                throw new IllegalArgumentException("Unsupported URI: " + uri);
        }


        return queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
    }

    /**
     * @param uri uri
     * @return Returns the mime time for the given uri
     */
    @Nullable
    @Override
    public String getType(Uri uri) {
        ProviderUriEnum matcherEnum = mProviderUriMatcher.matchUri(uri);
        return matcherEnum.contentType;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();

        ProviderUriEnum mProviderUriEnum = mProviderUriMatcher.matchUri(uri);
        Uri mUri = null;
        switch (mProviderUriEnum) {
            case USER:

                //Add a new record
                long rowID = db.insert(UserDAO.USER_MASTER_TABLE, "", values);
                //If record is added successfully
                if (rowID > 0) {
                    mUri = ContentUris.withAppendedId(CONTACT_ROOM_CONTENT_URI, rowID);
                    getContext().getContentResolver().notifyChange(mUri, null);
                }
                break;
            
            default:
                throw new SQLException("Failed to add a record into " + uri);
        }

        return mUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();

        ProviderUriEnum mProviderUriEnum = mProviderUriMatcher.matchUri(uri);

        int count = 0;
        switch (mProviderUriEnum) {
            case USER:
                count = db.delete(UserDAO.USER_MASTER_TABLE, selection, selectionArgs);
                break;
            
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase db = DatabaseHelper.getInstance().getWritableDatabase();

        ProviderUriEnum mProviderUriEnum = mProviderUriMatcher.matchUri(uri);

        int count = 0;
        switch (mProviderUriEnum) {
            case USER:
                count = db.update(UserDAO.USER_MASTER_TABLE, values, selection, selectionArgs);
                break;
            
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
}

Step 3: Create ProviderBuilder


public class ProviderBuilder {

    public static final String CONTENT_TYPE_BASE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/";

    public static final String CONTENT_ITEM_TYPE_BASE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/";


    public static String makeContentType(String id) {
        if (id != null) {
            return CONTENT_TYPE_BASE + id;
        } else {
            return null;
        }

    }

    public static String makeContentItemType(String id) {
        if (id != null) {
            return CONTENT_ITEM_TYPE_BASE + id;
        } else {
            return null;
        }
    }


    public static Uri buildContentUri(Context context,String base) {
        return Uri.parse("content://" + context.getString(R.string.app_content_provider)).buildUpon().appendPath(base).build();
    }

}

Step 4: Create ProviderUriEnum

public enum ProviderUriEnum {

    USER(1, UserDAO.USER_MASTER_TABLE, false);

    public int uriCode;
    public String uriBasePath;
    public String contentType;

    ProviderUriEnum(int uriCode, String uriBasePath, Boolean isItem) {
        this.uriCode = uriCode;
        this.uriBasePath = uriBasePath;
        this.contentType = isItem ? ProviderBuilder.makeContentItemType(uriBasePath)
                : ProviderBuilder.makeContentType(uriBasePath);
    }

}

Step 5: Create ProviderUriMatcher

public class ProviderUriMatcher {

    private android.content.UriMatcher mUriMatcher;
    private SparseArray<ProviderUriEnum> mEnumsMap = new SparseArray<>();
    final String authority;

    public ProviderUriMatcher(Context context) {
        mUriMatcher = new android.content.UriMatcher(android.content.UriMatcher.NO_MATCH);
        authority = context.getString(R.string.app_content_provider);
        buildUriMatcher();
    }


    private void buildUriMatcher() {

        ProviderUriEnum[] uris = ProviderUriEnum.values();
        for (ProviderUriEnum uri : uris) {
            mUriMatcher.addURI(authority, uri.uriBasePath, uri.uriCode);
            mEnumsMap.put(uri.uriCode, uri);
        }

        //buildEnumsMap();

    }

    private void buildEnumsMap() {
        ProviderUriEnum[] uris = ProviderUriEnum.values();
        for (ProviderUriEnum uri : uris) {
            mEnumsMap.put(uri.uriCode, uri);
        }
    }


    /**
     * Matches a {@code uri} to a {@link ProviderUriEnum}.
     *
     * @return the {@link ProviderUriEnum}, or throws new UnsupportedOperationException if no match.
     */
    public ProviderUriEnum matchUri(Uri uri) {
        final int code = mUriMatcher.match(uri);
        try {
            return matchCode(code);
        } catch (UnsupportedOperationException e) {
            throw new UnsupportedOperationException("Unknown uri " + uri);
        }
    }

    /**
     * Matches a {@code code} to a {@link ProviderUriEnum}.
     *
     * @return the {@link ProviderUriEnum}, or throws new UnsupportedOperationException if no match.
     */
    public ProviderUriEnum matchCode(int code) {
        ProviderUriEnum scheduleUriEnum = mEnumsMap.get(code);
        if (scheduleUriEnum != null) {
            return scheduleUriEnum;
        } else {
            throw new UnsupportedOperationException("Unknown uri with code " + code);
        }
    }
}

Step 6: Add Utils

private static final String TAG = "DatabaseUtils";
    private ContentResolver mContentResolver;

    private static SimpleDateFormat DBFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());

    public DatabaseUtils(Context context) {
        mContentResolver = context.getContentResolver();
    }

    public Boolean isRowExist(Uri content_uri, String[] projection, String selection, Long id) {

        Cursor cursor = mContentResolver
                .query(content_uri,
                        projection,
                        selection + " = ?",
                        new String[]{String.valueOf(id)},
                        null);

        if (cursor != null) {

            if (cursor.getCount() > 0) {
                Log.i(TAG, "row with " + id + " Exist");
                cursor.close();
                return true;
            } else {
                Log.i(TAG, "row with " + id + " Not Exist");
                cursor.close();
                return false;
            }

        }else {
            Log.e(TAG, "cursor is null");
            return false;
        }

    }

    public Boolean isRowExist(Uri content_uri, String[] projection, String selection, String id) {

        Cursor cursor = mContentResolver
                .query(content_uri,
                        projection,
                        selection + " = ?",
                        new String[]{String.valueOf(id)},
                        null);

        if (cursor != null) {

            if (cursor.getCount() > 0) {
                Log.i(TAG, "row with " + id + " Exist");
                cursor.close();
                return true;
            } else {
                Log.i(TAG, "row with " + id + " Not Exist");
                cursor.close();
                return false;
            }

        } else {
            Log.e(TAG, "cursor is null");
            return false;
        }

    }


    public static void setTimeZone() {
        DBFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    }

    public static String getDateTime() {
        Date date = new Date();
        return DBFormat.format(date);
    }

    public static String getTimeStamp(String timeStamp) {

        String time = null;
        SimpleDateFormat dstFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());

        try {
            time = dstFormat.format(DBFormat.parse(timeStamp));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return time;
    }
}

Step 7: Create a Table


public class UserDAO {

    private static final String TAG = "UserDAO";

    public static final String USER_MASTER_TABLE = "user_master";

    //Common column names
    public static final String KEY_ID = "id";
    private static final String KEY_CREATED_AT = "create_time";
    private static final String KEY_UPDATED_AT = "update_time";

    //userObj_room columns
    public static final String KEY_COMPANY_LOGO = "company_logo";
    public static final String KEY_COMPANY_NAME = "company_name";
    public static final String KEY_COMPANY_SLOGAN = "company_slogan";
    public static final String KEY_NAME = "name";
    public static final String KEY_DESIGNATION = "designation";
    public static final String KEY_PHONE_NO1 = "phone_no1";
    public static final String KEY_PHONE_NO2 = "phone_no2";
    public static final String KEY_FAX = "fax_no";
    public static final String KEY_EMAIL_ID = "email_id";
    public static final String KEY_WEB1 = "website1";
    public static final String KEY_WEB2 = "website2";
    public static final String KEY_ADDRESS = "address";
    public static final String KEY_QR_LIST = "qr_list";


    private ContentResolver mContentResolver;
    private Context context;
    private DatabaseUtils databaseUtils;

    public UserDAO(Context context) {
        this.context = context;
        mContentResolver = context.getContentResolver();
        databaseUtils = new DatabaseUtils(context);

    }

    public static String createContactRoom() {
        String query = "CREATE TABLE " + USER_MASTER_TABLE + "(" +
                KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                KEY_COMPANY_LOGO + " TEXT," +
                KEY_COMPANY_NAME + " TEXT," +
                KEY_COMPANY_SLOGAN + " TEXT," +
                KEY_NAME + " TEXT," +
                KEY_EMAIL_ID + " TEXT," +
                KEY_DESIGNATION + " TEXT," +
                KEY_PHONE_NO1 + " TEXT," +
                KEY_PHONE_NO2 + " TEXT," +
                KEY_FAX + " TEXT," +
                KEY_WEB1 + " TEXT," +
                KEY_WEB2 + " TEXT," +
                KEY_ADDRESS + " TEXT," +
                KEY_QR_LIST + " TEXT," +
                KEY_CREATED_AT + " DATETIME," +
                KEY_UPDATED_AT + " DATETIME)";

        Log.e(TAG, "CREATE USER_MASTER_TABLE => " + query);
        return query;
    }

    public String addUserObj(UserObj userObj) {

        ContentValues values = ContactToValues(userObj);

        /*if (userObj.getIsSetFollowUp() == 1) {
            values.put(KEY_SET_FOLLOW_UP, 1);
            values.put(KEY_FOLLOWUP_MSG, userObj.getFollowUpMsg() != null ? userObj.getFollowUpMsg() : "");
            values.put(KEY_FOLLOWUP_DATE, userObj.getFollowUpDate() != null ? userObj.getFollowUpDate() : "");
            values.put(KEY_FOLLOWUP_TIME, userObj.getFollowUpTime() != null ? userObj.getFollowUpTime() : "");
        }*/

        Uri insert_uri = mContentResolver.insert(BusinessCardContentProvider.CONTACT_ROOM_CONTENT_URI, values);
        Log.e(TAG, "insert userObj @ - " + insert_uri);
        mContentResolver.notifyChange(insert_uri, null);

        return insert_uri.getLastPathSegment();
    }

    public ArrayList<UserObj> getAllUserObj(String search_query) {
        ArrayList<UserObj> allContactList = new ArrayList<>();

        /*String whereClause = KEY_LOGIN_USER_ID + " = ?";
        if (search_query.length() > 0) {
            whereClause = whereClause + " AND (" + KEY_NAME + " like '%" + search_query + "%' OR " + KEY_DESIGNATION + " like '%" + search_query + "%')";
        }*/

        Cursor cursor = mContentResolver.query(BusinessCardContentProvider.CONTACT_ROOM_CONTENT_URI,
                null,
                null,//whereClause,
                null,//new String[]{String.valueOf(user_id)},
                KEY_NAME + " COLLATE NOCASE ASC");

        if (cursor != null) {
            if (cursor.moveToFirst()) {
                do {
                    allContactList.add(cursorToUserObj(cursor));
                } while (cursor.moveToNext());
            }
            cursor.close();
        } else {
            Log.e(TAG, "userObjList cursor is null");
        }
        return allContactList;
    }

    public boolean isAnyUserFound() {

        Cursor cursor = mContentResolver.query(BusinessCardContentProvider.CONTACT_ROOM_CONTENT_URI,
                new String[]{KEY_ID},
                null,//whereClause,
                null,//new String[]{String.valueOf(user_id)},
                KEY_ID + " ASC LIMIT 1");

        if (cursor != null) {
            if (cursor.moveToFirst() && cursor.getCount() > 0) {
                return true;
            }
            cursor.close();
        } else {
            Log.e(TAG, "isAnyUserFound cursor is null");
        }
        return false;
    }

    public void updateUserObj(UserObj userObj) {
        int update_row = mContentResolver.update(BusinessCardContentProvider.CONTACT_ROOM_CONTENT_URI,
                ContactToValues(userObj),
                KEY_ID + " =?",
                new String[]{String.valueOf(userObj.getUserId())});

        Log.e(TAG, "Update userObjs @ - " + userObj.getUserId());
        mContentResolver.notifyChange(BusinessCardContentProvider.CONTACT_ROOM_CONTENT_URI, null);
    }

    public void deleteContact(int userObj_id) {

        int delete_group = mContentResolver.delete(BusinessCardContentProvider.CONTACT_ROOM_CONTENT_URI,
                KEY_ID + " = ?",
                new String[]{String.valueOf(userObj_id)});

        Log.e(TAG, "deleted Contact @ " + delete_group);
    }

    private ContentValues ContactToValues(UserObj userObj) {
        ContentValues values = new ContentValues();

        values.put(KEY_COMPANY_LOGO, userObj.getCompanyLogo());
        values.put(KEY_COMPANY_NAME, userObj.getCompanyName());
        values.put(KEY_COMPANY_SLOGAN, userObj.getCompanySlogan());
        values.put(KEY_NAME, userObj.getUserName());
        values.put(KEY_DESIGNATION, userObj.getDesignation());
        values.put(KEY_PHONE_NO1, userObj.getPhnNo1() != null ? userObj.getPhnNo1() : "");
        values.put(KEY_PHONE_NO2, userObj.getPhnNo2() != null ? userObj.getPhnNo2() : "");
        values.put(KEY_FAX, userObj.getFaxNo() != null ? userObj.getFaxNo() : "");
        values.put(KEY_EMAIL_ID, userObj.getEmail() != null ? userObj.getEmail() : "");
        values.put(KEY_WEB1, userObj.getWebsite1() != null ? userObj.getWebsite1() : "");
        values.put(KEY_WEB2, userObj.getWebsite2() != null ? userObj.getWebsite2() : "");
        values.put(KEY_ADDRESS, userObj.getAddress() != null ? userObj.getAddress() : "");
        values.put(KEY_QR_LIST, userObj.getQrList() != null ? userObj.getQrList().toString() : "");

        Log.i(TAG, "Add QR: " + userObj.getQrList().toString());

        values.put(KEY_CREATED_AT, DatabaseUtils.getDateTime());
        values.put(KEY_UPDATED_AT, DatabaseUtils.getDateTime());
        return values;
    }

    private UserObj cursorToUserObj(Cursor cursor) {
        UserObj userObjs = new UserObj();
        userObjs.setUserId(cursor.getInt(cursor.getColumnIndex(KEY_ID)));
        userObjs.setCompanyLogo(cursor.getString(cursor.getColumnIndex(KEY_COMPANY_LOGO)));
        userObjs.setCompanyName(cursor.getString(cursor.getColumnIndex(KEY_COMPANY_NAME)));
        userObjs.setCompanySlogan(cursor.getString(cursor.getColumnIndex(KEY_COMPANY_SLOGAN)));
        userObjs.setUserName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
        userObjs.setDesignation(cursor.getString(cursor.getColumnIndex(KEY_DESIGNATION)));
        userObjs.setPhnNo1(cursor.getString(cursor.getColumnIndex(KEY_PHONE_NO1)));
        userObjs.setPhnNo2(cursor.getString(cursor.getColumnIndex(KEY_PHONE_NO2)));
        userObjs.setFaxNo(cursor.getString(cursor.getColumnIndex(KEY_FAX)));
        userObjs.setEmail(cursor.getString(cursor.getColumnIndex(KEY_EMAIL_ID)));
        userObjs.setWebsite1(cursor.getString(cursor.getColumnIndex(KEY_WEB1)));
        userObjs.setWebsite2(cursor.getString(cursor.getColumnIndex(KEY_WEB2)));
        userObjs.setAddress(cursor.getString(cursor.getColumnIndex(KEY_ADDRESS)));

        String qrList = cursor.getString(cursor.getColumnIndex(KEY_QR_LIST));
        ArrayList<String> finalList = new ArrayList<>();
        Log.i(TAG, "qrList:" + qrList);
        if (qrList != null && qrList.length() > 0) {

            String[] split = qrList.replace("[", "").replace("]", "").split(",");
            for (String aSplit : split) {

                if (aSplit != null && aSplit.length() > 0) {
                    finalList.add(aSplit.trim());
                }

            }
        }
        Log.i(TAG, "finalList:" + finalList);
        userObjs.setQrList(finalList);

        //userObjs.setCreateTime(cursor.getString(cursor.getColumnIndex(KEY_CREATED_AT)));
        //userObjs.setUpdateTime(cursor.getString(cursor.getColumnIndex(KEY_UPDATED_AT)));

        return userObjs;
    }


public ArrayList<UserObj> getAllUserByCompnyName(String compnyName) {

        ArrayList<UserObj> userList = new ArrayList<>();
        String mSelectionClause = null;
        Cursor cursor = mContentResolver.query(BusinessCardContentProvider.CONTACT_ROOM_CONTENT_URI,
                null,
//KEY_ID + " =? AND " + KEY_IS_READ + " = " + 0 + " AND " + KEY_QUOTE_DATE + ">= //date('" + currantDate + "')",
                KEY_COMPANY_NAME + " = ?",
                new String[]{compnyName},
                KEY_UPDATED_AT + " ASC");  //DESC ,ASC

//Cursor cursor = //mContentResolver.query(BusinessCardContentProvider.SAMPLE_ITEM_CONTENT_URI,
//               null,
//                KEY_IS_CACHE + " = ? AND " + KEY_CATALOG_ID + " = ?",//KEY_HISTORY_ID //+ " = ?",
//               new String[]{String.valueOf(1), String.valueOf(catalog_id)},
//new String[]{String.valueOf(user_id)},
//                KEY_UPDATED_AT + " DESC");  //DESC ,ASC



//Cursor cursor = mContentResolver
//                .query(BusinessCardContentProvider.SYNC_HISTORY_CONTENT_URI,
//                        new String[]{KEY_LAST_SYNC_TIME},
//                        KEY_SYNC_CATALOG_ID + " =?",
//                        new String[]{String.valueOf(catalog_id)},
//                        KEY_LAST_SYNC_TIME + " DESC LIMIT 1");

        if (cursor != null) {
            if (cursor.moveToFirst()) {
                do {
                    UserObj userObj = new UserObj();
                    userObj.setAddress(cursor.getString(cursor.getColumnIndex(KEY_ADDRESS)));
                    userObj.setUserName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
                    userObj.setCompanyLogo(cursor.getString(cursor.getColumnIndex(KEY_COMPANY_LOGO)));
//                    jsonID.add(cursor.getInt(cursor.getColumnIndex(KEY_SAMPLE_ID)));

                } while (cursor.moveToNext());
            }
            cursor.close();
        } else {
            Log.e(TAG, "sample cursor is null");
        }

        Log.i(TAG, " Total Json Id : " + String.valueOf(userList.size()));

        return userList;

    }


//public void updateUser(final UserObj category) {

//        int update_row = //mContentResolver.update(BusinessCardContentProvider.SYNC_HISTORY_CONTENT_URI,
//                updateToValues(category),
//                //KEY_ID + " =? AND " + KEY_IS_READ + " = " + 0 + " AND " + //KEY_QUOTE_DATE + ">= date('" + currantDate + "')",  
//                KEY_SYNC_CATALOG_ID + " =?",
//                new String[]{String.valueOf(category.getCatalogId())});
//        Log.e(TAG, "Update Category @ row - " + update_row);
//        //mContentResolver.notifyChange(BusinessCardContentProvider.SYNC_HISTORY_CONTENT_U////RI, null);
//    }


Step 8 : Add in menifest

<!-- Content Provider -->
        <provider
            android:name="com.core.database.providers.MainContentProvider"
            android:authorities="@string/app_content_provider"
            android:exported="false" />

<string name="app_content_provider">com.demo.database</string>
}