Friday 19 August 2016

Android logcat is flooded with “W/Google Maps Android API: GLHudOverlay deprecated; draw(): no-op”

Actually it is a render time log. No connection with java code. I also have same log. and i feel its cause by : SupportMapFragment in xml file. When i touch Map, GL render layout and prints this log.
It is inside Map Library. So we can't modify it. but i think sometimes it cause memory overload. and so system calls GC to dump memory.
It's just a warning. So ignore it for now. but it should be fix by Google map library maker.

Now it's a known issue and will be solve in next Google Play Library release.
Check out gmaps-api-issues 10201

Saturday 13 August 2016

Android Local SQLite Database Example

Android platform includes the SQLite embedded database and provides out of the box support to use it via Android APIs. In this tutorial we shall see how to get started with SQLitedatabase in Android. SQLiteis nothing but a relational database and our SQLskills will help.

How to Use SQLite with Android? 

To use SQLitein Android, a java class should be created as a sub class of SQLiteOpenHelper. This class will act as a database controller which will have the methods to perform the CRUD operations. This custom java class should override the methods named onCreate()and .onUpgrade()
onCreate() method will be called for the first time when the Android application is run. First the database instance should be created using the method like getReadableDatabase() or getWritableDatabase() based on the type of access required. Android supports this method by providing in-built methods. For that, SQLiteQueryBuilder class should be imported.
Lets have three Android Activity for List, Add and Edit operations and ensure that these are declared in manifest file. And then we need to create subclass of SQLiteHelper to manage SQLite database.


Database & Table Structure : 

 
1
2
3
4
5
6
7
8
+------------+------------+------------------------------+---+--------+--+
| Field Name |  Field Type                   | Sample                    |
+------------+------------+------------------------------+---+--------+--+
| ID         |  PRIMARY KEY [Auto Generated] |  1                        |
| Name       |  TEXT                         | Chintan Khetiya           |
| Number     |  TEXT                         | 787-806-0124              |
| Email      |  TEXT                         | khetiya.chintan@gmail.com |
+------------+------------+------------------------------+---+--------+--+
 
 

+------------+------------+------------------------------+---+--------+--+
| Field Name |  Field Type                   | Sample                    |
+------------+------------+------------------------------+---+--------+--+
| ID         |  PRIMARY KEY [Auto Generated] |  1                        |
| Name       |  TEXT                         | Chintan Khetiya           |
| Number     |  TEXT                         | 787-806-0124              |
| Email      |  TEXT                         | khetiya.chintan@gmail.com |
+------------+------------+------------------------------+---+--------+--+



Create or Setup Database:

DatabaseHandler.java is going to be our custom java class that will manage the SQLite database. We should extend SQLiteOpenHelper and override the essential methods. The constructor is the hook that will be used to setup the database. While running the Android application, the database will be created for the first time.

 
1
2
3
4
public DatabaseHandler(Context applicationcontext) {
    super(applicationcontext, "androidsqlite.db", null, 1);
    Log.d(LOGCAT, "Created");
}
 
 

public DatabaseHandler(Context applicationcontext) {
    super(applicationcontext, "androidsqlite.db", null, 1);
    Log.d(LOGCAT, "Created");
}


Table Creation and Upgrade:

SQLiteOpenHelper provides callback methods and we should override it to get our job done. Those callback methods that we can override are onCreate(), onUpgrade(), onOpen() and onDowngrade(). And onCreate() and onUpgrade() are abstract methods and must be overridden.
onCreate(SQLiteDatabase database) – is the method which is called first time when the database is created and we need to use this method to create the tables and populate it as per the need.

 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "(" +
        KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," +
        KEY_PH_NO + " TEXT," + KEY_EMAIL + " TEXT" + ")";
    db.execSQL(CREATE_CONTACTS_TABLE);
}
 
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)– is the method called when upgrade is done.We can drop the database and reset
if required.
 
// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
 
    // Create tables again
    onCreate(db);
}
 
 

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "(" +
        KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," +
        KEY_PH_NO + " TEXT," + KEY_EMAIL + " TEXT" + ")";
    db.execSQL(CREATE_CONTACTS_TABLE);
}

onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)– is the method called when upgrade is done.We can drop the database and reset
if required.

// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);

    // Create tables again
    onCreate(db);
}



How it looks after all task ? 




New
Add New user



Update
Update Record


Delete
Delete Record



View
View All







Note: The Contact details are fake or random

Do some Task : 

We shall have other user defined methods to handle the sql aobve operations. The <code>Contact table </code> will be created when the onCreate() method is invoked while installing the application. For performing operations like insert, update, the SQLiteDatabase instance should be created using the methods like getReadableDatabase() or getWritableDatabase(). ContentValues() are used to pass values to the query.

Insert, Read, Update and Delete Insert Records :

 
01
02
03
04
05
06
07
08
09
10
11
// Adding new contact
public void Add_Contact(Contact contact) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(KEY_NAME, contact.getName()); // Contact Name
    values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone
    values.put(KEY_EMAIL, contact.getEmail()); // Contact Email
    // Inserting Row
    db.insert(TABLE_CONTACTS, null, values);
    db.close(); // Closing database connection
}
 
 

// Adding new contact
public void Add_Contact(Contact contact) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(KEY_NAME, contact.getName()); // Contact Name
    values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone
    values.put(KEY_EMAIL, contact.getEmail()); // Contact Email
    // Inserting Row
    db.insert(TABLE_CONTACTS, null, values);
    db.close(); // Closing database connection
}



Read Records :

 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Getting single contact
Contact Get_Contact(int id) {
    SQLiteDatabase db = this.getReadableDatabase();
 
    Cursor cursor = db.query(TABLE_CONTACTS, new String[] {
            KEY_ID,
            KEY_NAME,
            KEY_PH_NO,
            KEY_EMAIL
        }, KEY_ID + "=?",
        new String[] {
            String.valueOf(id)
        }, null, null, null, null);
    if (cursor != null)
        cursor.moveToFirst();
 
    Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
        cursor.getString(1), cursor.getString(2), cursor.getString(3));
    // return contact
    cursor.close();
    db.close();
 
    return contact;
}
 
 

// Getting single contact
Contact Get_Contact(int id) {
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.query(TABLE_CONTACTS, new String[] {
            KEY_ID,
            KEY_NAME,
            KEY_PH_NO,
            KEY_EMAIL
        }, KEY_ID + "=?",
        new String[] {
            String.valueOf(id)
        }, null, null, null, null);
    if (cursor != null)
        cursor.moveToFirst();

    Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
        cursor.getString(1), cursor.getString(2), cursor.getString(3));
    // return contact
    cursor.close();
    db.close();

    return contact;
}



Update Records :

 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
// Updating single contact
public int Update_Contact(Contact contact) {
    SQLiteDatabase db = this.getWritableDatabase();
 
    ContentValues values = new ContentValues();
 
    values.put(KEY_NAME, contact.getName());
    values.put(KEY_PH_NO, contact.getPhoneNumber());
    values.put(KEY_EMAIL, contact.getEmail());
 
    // updating row
 
    return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
        new String[] {
            String.valueOf(contact.getID())
        });
 
}
 
 

// Updating single contact
public int Update_Contact(Contact contact) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();

    values.put(KEY_NAME, contact.getName());
    values.put(KEY_PH_NO, contact.getPhoneNumber());
    values.put(KEY_EMAIL, contact.getEmail());

    // updating row

    return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
        new String[] {
            String.valueOf(contact.getID())
        });

}



Delete Records :

 
1
2
3
4
5
6
7
8
9
// Deleting single contact
public void Delete_Contact(int id) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
        new String[] {
            String.valueOf(id)
        });
    db.close();
}
 
 

// Deleting single contact
public void Delete_Contact(int id) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
        new String[] {
            String.valueOf(id)
        });
    db.close();
}



Read All record: 

 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Getting All Contacts
public ArrayList < Contact > Get_Contacts() {
    try {
        contact_list.clear();
 
        // Select All Query
        String selectQuery = "SELECT * FROM " + TABLE_CONTACTS;
 
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
 
        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Contact contact = new Contact();
                contact.setID(Integer.parseInt(cursor.getString(0)));
                contact.setName(cursor.getString(1));
                contact.setPhoneNumber(cursor.getString(2));
                contact.setEmail(cursor.getString(3));
                // Adding contact to list
                contact_list.add(contact);
            } while (cursor.moveToNext());
        }
 
        // return contact list
        cursor.close();
        db.close();
        return contact_list;
    } catch (Exception e) {
        // TODO: handle exception
        Log.e("all_contact", "" + e);
    }
 
    return contact_list;
}
 
 

// Getting All Contacts
public ArrayList < Contact > Get_Contacts() {
    try {
        contact_list.clear();

        // Select All Query
        String selectQuery = "SELECT * FROM " + TABLE_CONTACTS;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Contact contact = new Contact();
                contact.setID(Integer.parseInt(cursor.getString(0)));
                contact.setName(cursor.getString(1));
                contact.setPhoneNumber(cursor.getString(2));
                contact.setEmail(cursor.getString(3));
                // Adding contact to list
                contact_list.add(contact);
            } while (cursor.moveToNext());
        }

        // return contact list
        cursor.close();
        db.close();
        return contact_list;
    } catch (Exception e) {
        // TODO: handle exception
        Log.e("all_contact", "" + e);
    }

    return contact_list;
}





GitHub-download
GitHub-download

Tuesday 5 July 2016

Android Basic Utils Function

Which is the major issue or difficulty developer face during development ? just ask your self and you will find that answer is Utils function which we are using in daily basis. We are doing coding whole day most of the conman things are repeated in all project or module , only some part of the unique code , view and logic which we added. Developer are so lazzy to write same code again and again and make create utils class to make reusable code.

Here i am sharing list of function which we are using in daily basis in android application development which will save your time to find from Google or Stack overflow and write in your utils class or java class. The main objective of this task is Reuse ability of code , Time saving , Easy & Less coding. Let's start.

  • You have two ways to use this Utils function :

    1. JAVA File
    2. Live Template
  • Direct form JAVA file :

    You just need to add my created Utils JAVA file in your <package> and access using class object. You can find 120+ utils function in java file but that is not mandatory to add all in your application you can remove list of function which is not useful for your application so that will not save unnecessary code. see below example to see "How to use this class in your activity class?"

     
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    public class MainActivity extends Activity {
        private CKAndroidUtils objCKUtils;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            objCKUtils = new CKAndroidUtils(this);
            if (objCKUtils.isNetworkAvailable()) {
              ….. //Do your task
            }
        }
     
     
    
    public class MainActivity extends Activity {
        private CKAndroidUtils objCKUtils;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            objCKUtils = new CKAndroidUtils(this);
            if (objCKUtils.isNetworkAvailable()) {
              ….. //Do your task
            }
        }
    
    
  • Live Template : 

    Code completion can improve your productivity by reducing how much you have to type, but there are situations when a more powerful tool is needed. Thanks to Android Studio and IntelliJ, live templates make it much easier to focus on just the things you care about. You can read one of the grate article regarding Live Template . You have to create CKAndroidUtils snippet file (XML)  which contains your code in XML formate and that will be use to access the function using short cut key : Ctrl + Alt + Shift + J  FUNCTION NAME .

  • How to create your share with others :  

    1. Path : File > Settings > Editor > Live Template > .. You can see Add or remove snippet code or template group from “+” or “-“ from right side button.

    2. Now choose Android group or own created template to add snippet code. That will ask you Abbreviation = Function name , Description = What function do, Template text = your code, Type = java , xml ,other. Apply > Ok Done!   Now search it using give short cut key and access function any where in your application.

    3. Now you can share added snippet code to other developer and setup same file to get access.

  • Check out below steps to configure the XML :

    1. Download CKAndroidUtils snippet file 

    2. Go to “/.Android Studio/config /templetes folder (by default is hide folder at user /dir)
      i.e /home/sotsys073/.AndroidStudio/config/templetes

    3. Paste “CKAndroidUtils” file in above /dir.

    4. Restart android studio and check CKAndroidUtils is available in File >> Settings >> Live template >> CKAndroidUtils

    5. Short cut to access function : Ctrl + Alt + Shift + J  FUNCTION NAMENow you  are able to add function in template and know how to use it . Download CKAndroidUtils.java file and create your snippet or use directly. Start it now!!! Hope this will relay helpful for all of you. 

      Note : Please add function which you are using in project and not listed in below list so that will be helpful for other

  • List of Utils Function

    Index

    Function Name
    1
    askToExit()
    2
    showYesNoDialog()
    3
    showOkDialog()
    4
    isNetworkEnable()
    5
    isLocationEnable()
    6
    showProgressDialog()
    7
    hideProgressDialog()
    8
    showToast()
    9
    hideSoftKeyboard()
    11
    openSoftKeyboard()
    12
    dpToPixel()
    13
    pixelToDp()
    14
    getDeviceDensity()
    15
    getScreenHeight()
    16
    getScreenWidth()
    17
    getScreenSize()
    18
    openDialer()
    19
    isPlayServiceExist()
    20
    setDynamicListViewHeight()
    21
    switchActivity()
    22
    callActivityForResult()
    23
    adjustImageOrientation()
    24
    getRotateBitmap()
    25
    getCropBitmapToSquare()
    26
    getRoundedCornerBitmap()
    27
    getResizedBitmap()
    28
    getBitmapFromDrawable()
    29
    getDrawableFromUrl()
    30
    getMaskedBitmap()
    31
    getMaskedImageByColor()
    32
    getStorageDirectory()
    33
    downloadImageFromUrl()
    34
    moveFile()
    35
    copyFile()
    36
    deleteFile()
    37
    createDirectory()
    38
    shareDefaultIntent()
    39
    shareImageviaIntent()
    40
    calculateInSampleSize()
    41
    loadBase64toImageView()
    42
    getFileFromPath()
    43
    getBitmapFromPath()
    44
    getFileFromBitmap()
    45
    sendMailFromGmail()
    46
    showFBUserProfile()
    47
    showTwitterUserProfile()
    48
    showInstagramUserProfile()
    49
    getImagePathFromUri()
    50
    getUriFromBitmap()
    51
    getBitmapFromFile()
    52
    drawableToBitmap()
    53
    saveBmpToJPG()
    54
    resizeImageScale()
    55
    isRemoteFileExists()
    56
    cropCenter()
    57
    getBlurImagFromBitmap()
    58
    getBlurImagUsingRenderScript()
    59
    getThumbnail()
    60
    getBlurImageUsingGaussianBlur()
    61
    isCameraExist()
    62
    getDistanceBetweenLocation()
    63
    getAddressFromLocation()
    64
    getLocationFromAddress()
    65
    getLatitudeFromAddress()
    66
    getLongitudeFromAddress()
    67
    getAddressFromLocationByAPI()
    68
    setDirectionURL()
    69
    getZoomLevelByMarkers()
    70
    getZoomLevelByPolyline()
    71
    getZoomLevelByRadius()
    72
    getRadiusFromMeter()
    73
    getZoomLevelByMeters()
    74
    animateMarker()
    75
    initFragment()
    76
    addFragment()
    77
    replaceFragment()
    78
    removeFragment()
    79
    isFragmentExist()
    80
    showAdmobInterstitial()
    81
    setAdmobBanner()
    82
    setupGA()
    83
    SendDataToGA()
    84
    UncaughtExceptionHandler()
    85
    getCountryZipCode()
    86
    createFackBookHashKey()
    87
    isvalidString()
    88
    isvalidDouble()
    89
    isValidText()
    90
    isValidPassword()
    91
    isValidNumber()
    92
    isValidEmail()
    93
    rateTheApp()
    94
    shareTheApp()
    95
    getCountry()
    96
    callToPerson()
    97
    cancelNotification()
    98
    loadWebpage()
    99
    SetLocale()
    100
    getNetworkType()
    101
    IsServiceRunning()
    102
    getDeviceId()
    103
    getAppVersion()
    104
    getIPAddress()
    105
    getWIFIAddress()
    106
    getIMEI()
    107
    getBluetoothAddress()
    108
    getAccount()
    109
    isAppInstalled()
    110
    getCapcha()
    111
    getRandomInt()
    112
    getUniqueDeviceId()
    113
    printLog()
    114
    encryptToMD5()
    115
    compareDate()
    116
    isValidDate()
    117
    getMonthName()
    118
    getCurrentTime()
    119
    openDatePicker()
    120
    setCurrentDate()
    121
    openTimePicker()
    122
    getTimeStampFromDate()
    123
    getUTCDate()
    124
    getDaysCount()
    125
    getDateDifference()
    126
    showSnackBar()
    127
    NFCUtilsClass

Monday 27 June 2016

How to Zoom & Scale Google map from center position android

  • Objective :
The main objective of this task is to show two markers (customer & driver) base on the distance with appropriate zoom level. Driver position will change base on location update & zoom level update base on the new distance calculated between two markers.
  • What user can do ?
  1. User can zoom in & zoom out map from center position.(customer will be always in center of the map) 
  2. ?
     
    1
    imgMapTransparent.setOnTouchListener(new MyScaleGestures(TrackingActivity.this, googleMap));
     
     
    
    imgMapTransparent.setOnTouchListener(new MyScaleGestures(TrackingActivity.this, googleMap));
    
    
  • What user can’t do ?
    1. User can’t scale map from X,Y position of the map area.
    2. User can’t move map as default behaviors
    3. All gestures event will be deactivate.
    4. ?
       
      1
      mGoogleMap.getUiSettings().setAllGesturesEnabled(false);
       
       
      
      mGoogleMap.getUiSettings().setAllGesturesEnabled(false);
      
      
  • How driver location will update ?
If a driver changes his/her location from the previous location we will get notify in void onLocationChanged(Location location)this location will help us to calculate the distance between customer & driver.
  • How does it work ?
We will get a frequent update of driver location even app will kill from a background as they will move on the path. Now calculate the distance between customer & driver current location and update driver marker. Now calculate Zoom level base on distance and update map view to be more zoom in.

To achieve this we have used transparent image view over the map to zoom in & zoom out and get touch event of the map. So while user scales it from any X,Y position that will call onCameraChangeListner .Now we will calculate zoom level inside onCameraChangeListner and set customer marker to the center of the screen.
  • Calculate distance between two locations:
?
 
01
02
03
04
05
06
07
08
09
10
public float getDistanceInMeter(double startLat, double startLong, double endLat, double endLong) {
    Location sourceLoc = new Location(“”);
    sourceLoc.setLatitude(startLat);
    sourceLoc.setLongitude(startLong);
    Location destLoc = new Location(“”);
    destLoc.setLatitude(endLat);
    destLoc.setLongitude(endLong);
    float distanceInMeters = sourceLoc.distanceTo(destLoc);
    return distanceInMeters;
}
 
 

public float getDistanceInMeter(double startLat, double startLong, double endLat, double endLong) {
    Location sourceLoc = new Location(“”);
    sourceLoc.setLatitude(startLat);
    sourceLoc.setLongitude(startLong);
    Location destLoc = new Location(“”);
    destLoc.setLatitude(endLat);
    destLoc.setLongitude(endLong);
    float distanceInMeters = sourceLoc.distanceTo(destLoc);
    return distanceInMeters;
}

  • Calculate zoom level from distance
?
 
1
2
3
4
5
public double getZoomForMetersWide(double desiredMeters, double latitude) {
    final double latitudinalAdjustment = Math.cos(Math.PI * latitude / 180);
    final double arg = EQUATOR_LENGTH * getScreenWidth() * latitudinalAdjustment / (desiredMeters * 256);
    return Math.log(arg) / Math.log(2);
}
 
 

public double getZoomForMetersWide(double desiredMeters, double latitude) {
    final double latitudinalAdjustment = Math.cos(Math.PI * latitude / 180);
    final double arg = EQUATOR_LENGTH * getScreenWidth() * latitudinalAdjustment / (desiredMeters * 256);
    return Math.log(arg) / Math.log(2);
}

  • Update customer marker position
?
 
1
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CUSTOMER_LOCATION, (float) ZOOM_LEVEL));
 
 

mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CUSTOMER_LOCATION, (float) ZOOM_LEVEL));

  • Update driver marker with animation
?
 
1
2
LatLngInterpolator latLngInterpolator = new LatLngInterpolator.Spherical();
MarkerAnimation.animateMarkerToGB(driverMarker, currentLatLong, latLngInterpolator);
 
 

LatLngInterpolator latLngInterpolator = new LatLngInterpolator.Spherical();
MarkerAnimation.animateMarkerToGB(driverMarker, currentLatLong, latLngInterpolator);

  • Set Zoom level & Update Map view :
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(llTO, mGoogleMap.getCameraPosition().zoom));
mGoogleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
    @Override
    public void onCameraChange(CameraPosition position) {
        if (!isMapChangeRequired) {
            isMapChangeRequired = true;
            return;
        }
        double meterDistance = objUtils.getDistanceInMeter(llSprenter.latitude, llSprenter.longitude, llTO.latitude, llTO.longitude);
        float Zoomlevel = (float)((float) objUtils.getZoomForMetersWide(meterDistance, llTO.latitude)– 0.3);
        if (Zoomlevel != ZOOM_LEVEL) {
            ZOOM_LEVEL = Zoomlevel;
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(llTO, (float) ZOOM_LEVEL));
        } else {
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(llTO, mGoogleMap.getCameraPosition().zoom));
        }
        isMapChangeRequired = false;
    }
});
 
 

mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(llTO, mGoogleMap.getCameraPosition().zoom));
mGoogleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
    @Override
    public void onCameraChange(CameraPosition position) {
        if (!isMapChangeRequired) {
            isMapChangeRequired = true;
            return;
        }
        double meterDistance = objUtils.getDistanceInMeter(llSprenter.latitude, llSprenter.longitude, llTO.latitude, llTO.longitude);
        float Zoomlevel = (float)((float) objUtils.getZoomForMetersWide(meterDistance, llTO.latitude)– 0.3);
        if (Zoomlevel != ZOOM_LEVEL) {
            ZOOM_LEVEL = Zoomlevel;
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(llTO, (float) ZOOM_LEVEL));
        } else {
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(llTO, mGoogleMap.getCameraPosition().zoom));
        }
        isMapChangeRequired = false;
    }
});

  • Handle custom ScaleGesture & TouchListner over Google Map view
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Override
public boolean onTouch(View view, MotionEvent event) {
    this.view = view;
    gestureScale.onTouchEvent(event);
    return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
    double zoom = googleMap.getCameraPosition().zoom;
    zoom = zoom + Math.log(detector.getScaleFactor()) / Math.log(1.5 d);
    CameraUpdate update = CameraUpdateFactory.newLatLngZoom(googleMap.getCameraPosition().target, (float) zoom);
    googleMap.moveCamera(update);
    return true;
}
 
 

@Override
public boolean onTouch(View view, MotionEvent event) {
    this.view = view;
    gestureScale.onTouchEvent(event);
    return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
    double zoom = googleMap.getCameraPosition().zoom;
    zoom = zoom + Math.log(detector.getScaleFactor()) / Math.log(1.5 d);
    CameraUpdate update = CameraUpdateFactory.newLatLngZoom(googleMap.getCameraPosition().target, (float) zoom);
    googleMap.moveCamera(update);
    return true;
}

Full MyScaleGestures.java
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MyScaleGestures implements View.OnTouchListener, ScaleGestureDetector.OnScaleGestureListener {
    private ScaleGestureDetector gestureScale;
    private GoogleMap googleMap;
    public MyScaleGestures(Context c, GoogleMap googleMap) {
        gestureScale = new ScaleGestureDetector(c, this);
        this.googleMap = googleMap;
    }
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        gestureScale.onTouchEvent(event);
        return true;
    }
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        double zoom = googleMap.getCameraPosition().zoom;
        zoom = zoom + Math.log(detector.getScaleFactor()) / Math.log(1.5 d);
        CameraUpdate update = CameraUpdateFactory.newLatLngZoom(googleMap.getCameraPosition().target, (float) zoom);
        googleMap.moveCamera(update);
        return true;
    }
    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        return true;
    }
    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {}
}
public class MyScaleGestures implements View.OnTouchListener, ScaleGestureDetector.OnScaleGestureListener {
    private ScaleGestureDetector gestureScale;
    private GoogleMap googleMap;
    public MyScaleGestures(Context c, GoogleMap googleMap) {
        gestureScale = new ScaleGestureDetector(c, this);
        this.googleMap = googleMap;
    }
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        gestureScale.onTouchEvent(event);
        return true;
    }
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        double zoom = googleMap.getCameraPosition().zoom;
        zoom = zoom + Math.log(detector.getScaleFactor()) / Math.log(1.5 d);
        CameraUpdate update = CameraUpdateFactory.newLatLngZoom(googleMap.getCameraPosition().target, (float) zoom);
        googleMap.moveCamera(update);
        return true;
    }
    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        return true;
    }
    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {}
}

?
1
2
3
4
<RelativeLayout android:id=”@+id/flMap” android:layout_width=”match_parent” android:layout_height=”match_parent” android:clickable=”true” android:focusable=”true” android:focusableInTouchMode=”true”>
    <fragment android:id=”@+id/layMapContainer” android:name=”com.google.android.gms.maps.SupportMapFragment” android:layout_width=”match_parent” android:layout_height=”match_parent” tools:context=”com.googlemapdemo.MapsActivity” />
    <ImageView android:id=”@+id/imgMapTransparent” android:layout_width=”match_parent” android:layout_height=”match_parent” android:src=”@android:color/transparent” />
</RelativeLayout>

<RelativeLayout android:id=”@+id/flMap” android:layout_width=”match_parent” android:layout_height=”match_parent” android:clickable=”true” android:focusable=”true” android:focusableInTouchMode=”true”>
    <fragment android:id=”@+id/layMapContainer” android:name=”com.google.android.gms.maps.SupportMapFragment” android:layout_width=”match_parent” android:layout_height=”match_parent” tools:context=”com.googlemapdemo.MapsActivity” />
    <ImageView android:id=”@+id/imgMapTransparent” android:layout_width=”match_parent” android:layout_height=”match_parent” android:src=”@android:color/transparent” />
</RelativeLayout>


  • Now while driver change is location marker will move with animation and map will zoom out as per location change. Hope this will help you a lot. You can download sample code.