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>
}


Thursday, January 5, 2017

Animated transition Between Activity


MainActivity.java (MIN API LEVEL 21)
**************

    @Override
    protected void onCreate(Bundle savedInstanceState)
   {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations()
   {
        Slide slide = new Slide();
        slide.setDuration(1000);
        getWindow().setExitTransition(slide);
    }


NextActivity.java
**************
    @Override
    protected void onCreate(Bundle savedInstanceState)
   {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations()
   {
        Fade fade = new Fade();
        fade.setDuration(1000);
        getWindow().setEnterTransition(fade);
    }


NextActivity.java
**************
    @Override
    protected void onCreate(Bundle savedInstanceState)
   {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
    }

    private void setupWindowAnimations()
   {
        Fade fade = new Fade();
        fade.setDuration(1000);
        getWindow().setEnterTransition(fade);
    }



FirstActivity.java
**************
    @Override
    protected void onCreate(Bundle savedInstanceState)
   {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transition);
        setupWindowAnimations();
   
    }

    private void setupWindowAnimations()
   {
        Fade fade = new Fade();
        fade.setDuration(1000);
        getWindow().setEnterTransition(fade);


        Slide slide = new Slide();
        slide.setDuration(1000);
        getWindow().setReturnTransition(slide);    
    } 

GIF file Load in Android Application





Add Dependencies in Gradle :

dependencies {
    compile 'com.roger.gifloadinglibrary:gifloadinglibrary:1.0.0'
}

Layout File:-

<pl.droidsonroids.gif.GifImageView
        android:layout_width="80dp"
        android:layout_height="50dp"
        android:id="@+id/loading"
        android:src="@drawable/mygif"   <!-- here select your GIF file -->
        android:layout_marginBottom="30dp"
        android:scaleType="centerCrop"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true" />

Material Ripple Layout(Ripple Effect)


Dependency include in your Gradle:-

compile 'com.balysv:material-ripple:1.0.2'

Layout File:-

<com.balysv.materialripple.MaterialRippleLayout
    android:id="@+id/ripple"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Button inside a ripple"/>

</com.balysv.materialripple.MaterialRippleLayout>


Configure using xml attributes or setters in code:
..................................................................................................................................................................................

app:mrl_rippleOverlay="true"              // if true, ripple is drawn in foreground; false - background
app:mrl_rippleColor="#ff0000"             // color of ripple
app:mrl_rippleAlpha="0.1"                 // alpha of ripple
app:mrl_rippleDimension="10dp"            // radius of hover and starting ripple
app:mrl_rippleHover="true"                // if true, a hover effect is drawn when view is touched
app:mrl_rippleRoundedCorners="10dp"       // radius of corners of ripples. Note: it uses software rendering pipeline for API 17 and below
app:mrl_rippleInAdapter="true"            // if true, MaterialRippleLayout will optimize for use in AdapterViews
app:mrl_rippleDuration="350"              // duration of ripple animation
app:mrl_rippleFadeDuration="75"           // duration of fade out effect on ripple
app:mrl_rippleDelayClick="true"           // if true, delays calls to OnClickListeners until ripple effect ends
app:mrl_rippleBackground="#FFFFFF"        // background under ripple drawable; used with rippleOverlay="false"
app:mrl_ripplePersistent="true"           // if true, ripple background color persists after animation, until setRadius(0) is called

3D button Design in Android


res/drawable/button.xml

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

  <!-- Outside border/shadow -->
  <item>
    <shape android:shape="oval">
      <size android:width="200dp" android:height="200dp" />
      <gradient android:angle="90" android:startColor="#f4f4f4" android:endColor="#b9b9b9" />
    </shape>
  </item>

  <!-- Inset -->
  <item android:top="1dp" android:left="1dp" android:right="1dp" android:bottom="1dp">
      <shape android:shape="oval">
        <gradient android:angle="90" android:startColor="#dcdcdc" android:endColor="#c9c9c9" />
      </shape>
  </item>

  <!-- Inside border/shadow -->
  <item android:top="15dp" android:left="15dp" android:right="15dp" android:bottom="15dp">
    <shape android:shape="oval">
      <gradient android:angle="90" android:startColor="#8c8c8c" android:endColor="#cbcbcb" />
    </shape>
  </item>

  <!-- Main button -->
  <item android:top="16dp" android:left="16dp" android:right="16dp" android:bottom="16dp">
    <shape android:shape="oval">
      <solid android:color="#ffffff" />
    </shape>
  </item>

  <!-- Button image -->
  <item android:top="70dp" android:left="70dp" android:right="70dp" android:bottom="70dp">
    <shape android:shape="rectangle">
      <solid android:color="#3b88c2" />
      <corners android:radius="20dp" />
    </shape>
  </item>

  <item android:top="75dp" android:left="75dp" android:right="75dp" android:bottom="75dp">
    <shape android:shape="rectangle">
      <solid android:color="#ffffff" />
      <corners android:radius="20dp" />
    </shape>
  </item>

  <item android:top="80dp" android:left="80dp" android:right="80dp" android:bottom="80dp">
    <shape android:shape="rectangle">
      <solid android:color="#3b88c2" />
      <corners android:radius="20dp" />
    </shape>
  </item>

</layer-list>

Thursday, September 22, 2016

why Google Allo will kill Whatsapp

Google Assistant


The reason why this app is like having your own personal assistant is because it is one, albeit virtual of course. Although What'sapp has unique features of sending across a location, file, picture, audio recording and so on- these are all saved files that are being shared via the app, which makes communication so much closer. However, where Allo differs is that you could be wondering about the travel time to a certain place, or the best available flights to a certain destination or discounts on hotels and all you have to do is type in @google followed your question or order. Next thing you know, it will be providing you with all the details, accompanied by a series of pictures wherever available.

Automatic Responses

The app can provide automatic responses to messages on behalf of the user. It does this through a software that contains machine-learning technology, which gets better at picking up the user’s most frequently used responses with increased usage of the app. For instance if someone sends you a ‘How are you?’, the app will offer you the automatic response of ‘Good, how about you’ that you can send across. It may seem impersonal at first but it builds up with greater use and is definitely convenient for those who are on the run and are too busy to type out a response.

Image recognition

Google has incorporated ‘photo recognition’ in this app, making it possible for it to recognize a received picture and suggest an automatic response. For example, if someone sends you a picture of a sunset, it will suggest ‘beautiful’ or ‘wow’ as a response, depending on your maximum usage of either, from which you can choose the more applicable one and send it across.

Selective end to end encryption

While both What'sapp and Allo offer end to end encryption for chats, the latter allows for ‘selective end to end encryption’, which means that you can select the contact you want to chat with in incognito mode, through its ‘Incognito Chat’ option. Along with this, the chat history will disappear after you have finished the talk, depending on the expiration period you have set. In case, you have switched off your expiration period, the chats won't disappear.

Bigger font size

Google has also introduced a better way for users to express themselves in conversations.
It has incorporated two slider buttons -‘Whisper’ and ‘Shout’. Users can increase or decrease the font size using these slider buttons.

Gmail account sync

Google Allo takes your phone number for primary identification, but if required then your Google account can also be synced with the app.
This will further enable you to get all important updates. For example, if you have a flight to catch, then the app will notify you about the same in advance.

Set timer to auto delete messages

An interesting feature in the app is its ability to help you set a timer for your messages to be deleted.
You can set a timer starting from 5 seconds, and once read the message gets deleted automatically.