Sunday, 11 October 2015

What is 65K Method limit in Android? How 65k Method limit handled by different build Systems of Android.

65k Method limit, well i recently faced this problem in one my android application. Trust me this is one of the worst problem you want to get into while development of your application.

So what is 65k method limit in Android? Firstly we should know this then only we can solve this.

65k Method Limit:

Apk i.e  Android Application contains DEX (dalvik executables i.e executable bytecode) as we know. So app contains a Single DEX i.e One Dex per app.

Single DEX file refers to 65,536 methods(including Android framework methods, library methods, and methods in your own code). So keep this thing in mind if your application is going to be big.

That's how error looks in Console =>
Earlier build versions :

Conversion to Dalvik format failed:
Unable to execute dex: method ID not in [0, 0xffff]: 65536

Recent build versions :

trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.

So first thing we never want to get into this stitution. And if we're into this stitution then how can we get rid of this is as follows:

We need to generate more then One Dex file for our app which is known as a multidex configuration. In order to achieve this we need to configure our Build app.

This problem mostly occurs on version prior to 5.0. Beacuse earlier versions uses Dalvik runtime for executing code, where as 5+ uses ART(Android runtime).

So how these android runtime works when this 65k problem occurs.ART is present in 5+ versions which supports loading multi dex files from an apk. So we need to configure our build system for earlier version in order to implement multi dex concept for handling 65k error.
Solution to this problem is "Multidex Support Library".

We need to modify our gradle file firstly as follows :

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"
    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 21

    // Enabling multidex support.
        multiDexEnabled true
 
}

}


dependencies {
  compile 'com.android.support:multidex:1.0.0'
}


In your manifest add the MultiDexApplication class from the multidex support library .

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        android:name="android.support.multidex.MultiDexApplication">
    </application>
</manifest>

So when These things are done Android build Tools will generate :

1.  Primary dex (classes.dex)
2.  Supporting (classes2.dex, classes3.dex) as needed.

The build system will then package them into an APK file for distribution.

So this how you can overcome 65k method problem. But best practice would be reducing code. you can try following things that i would recommend :

1. Remove large libs if included in your project. Beacuse you will be using few methods for your purpose rather then whole lib. So try avoid such things if you're facing such an issue.

2.Remove unused code via proguard.


References : https://developer.android.com/


Happy coding!!

Saturday, 10 October 2015

Toolbar Widget as Action Bar

Hi guys, Recently in my android projects i used toolbar alot. And most common use i found was showing a title with a back button at the top in the toolbar. Well i used both in Fragments and Activities. So how we can create a simple toolbar is as follows :



1. MainActivity
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private TextView tvTitle;

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

    private void setToolBar() {
        toolbar=(Toolbar)findViewById(R.id.toolbar);
        tvTitle=(TextView)findViewById(R.id.tv_title);
        tvTitle.setText("Toolbar Title");
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()){
            case android.R.id.home:
                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}
2. activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <include
        layout="@layout/toolbar"/>

    <TextView android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>
3. toolbar.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
 android:minHeight="?attr/actionBarSize"
 app:theme="@style/ToolBarTheme">


        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
          android:minHeight="?attr/actionBarSize"
            android:layout_marginRight="?attr/actionBarSize"
            android:textAppearance="?android:textAppearanceMedium"
            android:textColor="@android:color/black" />

    </android.support.v7.widget.Toolbar>

</LinearLayout>

4. style.xml


<resources>

    <!-- Base application theme. --> 
   <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>
    <style name="ToolBarTheme" parent="Base.ThemeOverlay.AppCompat.Dark.ActionBar">
        <item name="android:textColorPrimary">#000000</item>
        <item name="android:textColorSecondary">#ffffff</item>
    </style>

</resources>

Github Link :- https://github.com/CammyKamal/BlogTutorials/tree/master/AddingToolbar

Google Map integration

In this post we will be having a look on how to integrate Google Maps in android. Here in this post, Google Map is integrating using dynamic fragment.


First Create project on https://console.developers.google.com/ and create a Android key using your SHA1 and Keystore (whether debug or release).

See Below Screenshots as reference for creating a Google web console project. And get your Map API key.










1. MapActivity

import android.location.Geocoder;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;

public class MapActivity extends FragmentActivity {
    private GoogleMap googleMap;
    private SupportMapFragment fragment;

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

    private void setupDynamicMapFragment() {
        FragmentManager fm = this.getSupportFragmentManager();
        fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
        if (fragment == null) {
            fragment = SupportMapFragment.newInstance();
            fm.beginTransaction().replace(R.id.map_container, fragment).commit();
        }
    }

    /*** function to load map. If map is not created it will create it for you     */   
 private void initializeMap() {
        LatLng location = null;
        if (googleMap == null) {
            googleMap = fragment.getMap();
            if (googleMap != null) {
                    location = new LatLng(30.7500,76.7800);
                if (location != null) {
                    CameraPosition cameraPosition = new CameraPosition.Builder().target(
                            location).zoom(12).build();
                    googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
                }
            }
        }
    }

//initializing Google Maps on resume in order to let the SupportMapfragment get initialized 
 @Override    protected void onResume() {
        super.onResume();
        initializeMap();
    }
}

2. activity_map.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/map_container"
    tools:context=".MapActivity">

    <!-- The map fragments will go here -->
</RelativeLayout>


3. AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest 
  xmlns:android="http://schemas.android.com/apk/res/android"    
  package="com.Googlemapdemo" >
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!--  The ACCESS_COARSE/FINE_LOCATION permissions are not required to use  Google Maps Android API v2, but are recommended.     -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- Required OpenGL ES 2.0. for Maps V2 -->    
<uses-feature        
 android:glEsVersion="0x00020000"
 android:required="true" />

  <application
    android:allowBackup="true"  
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" >
     <activity        
     android:name=".MapActivity"
     android:label="@string/app_name" >
       <intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
       </intent-filter>
      </activity>
      <meta-data
       android:name="com.google.android.gms.version"
       android:value="@integer/google_play_services_version" />
     <meta-data
      android:name="com.google.android.maps.v2.API_KEY"
      android:value="@string/google_maps_key" />

 </application>

</manifest>


4. strings.xml


<resources>
    <string name="app_name">MapDemo</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="google_maps_key">YOUR MAP KEY</string>
</resources>

5. build.gradle
apply plugin: 'com.android.application'
android {
    compileSdkVersion 23 
    buildToolsVersion "23.0.0 rc2"
    defaultConfig {
        applicationId "com.mapdemo"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.google.android.gms:play-services:7.5.0'}


Output

Wednesday, 5 August 2015

Maps in Android Wear

We can show maps in Android wear we display user current location recived from the phone.
Currently we can update user current location from phone only. So this maps on android wear will be helpful for user to see the locations near by when riding.


What is DismissOverlayView? Need to know this first.

In Android wear we Dismiss a screen or view by swiping from left to right. But When we are dealing with Maps in android wear then gestures are overiden by the map gestures so we are not able to perform the normal left to right swipe dismiss action in android wear in maps.

So in order to overcome there is DismissOverlayView which lets you dismiss the map screen view by just long press on the map screen and you will get a alert to quit with cross icon which allows you to dismiss the current screen in view.



And how can we show maps in android wear programmactically is shown below.


Project Structure will be as shown





1. MainActivity.java

public class MainActivity extends FragmentActivity implements OnMapReadyCallback,

        GoogleMap.OnMapLongClickListener,GoogleMap.OnMarkerDragListener {



    private GoogleApiClient mGoogleApiClient;

    private static final LatLng CHANDIGARH = new LatLng(30.7500, 76.7800);

    ArrayList<LatLng> points;

    float distance;

    private DismissOverlayView mDismissOverlay;

    private GoogleMap mMap;



    public void onCreate(Bundle savedState) {

        super.onCreate(savedState);

        setContentView(R.layout.activity_main);

        final FrameLayout topFrameLayout = (FrameLayout) findViewById(R.id.root_container);

        final FrameLayout mapFrameLayout = (FrameLayout) findViewById(R.id.map_container);

        topFrameLayout.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {

            @Override

            public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {

                insets = topFrameLayout.onApplyWindowInsets(insets);

                FrameLayout.LayoutParams params =

                        (FrameLayout.LayoutParams) mapFrameLayout.getLayoutParams();

                params.setMargins(

                        insets.getSystemWindowInsetLeft(),

                        insets.getSystemWindowInsetTop(),

                        insets.getSystemWindowInsetRight(),

                        insets.getSystemWindowInsetBottom());

                mapFrameLayout.setLayoutParams(params);



                return insets;

            }

        });



        mDismissOverlay = (DismissOverlayView) findViewById(R.id.dismiss_overlay);

        mDismissOverlay.setIntroText(R.string.intro_text);

        mDismissOverlay.showIntroIfNecessary();

        SupportMapFragment mapFragment =

                (SupportMapFragment) getSupportFragmentManager()

                        .findFragmentById(R.id.map);

        mapFragment.getMapAsync(this);

    }



    @Override

    public void onMapReady(GoogleMap googleMap) {

        mMap = googleMap;

        mMap.setOnMapLongClickListener(this);

        MarkerOptions marker = new MarkerOptions()

                .position(CHANDIGARH)

                .title("Wear Maps")

                .snippet("" + CHANDIGARH)

                .icon(BitmapDescriptorFactory

                        .defaultMarker(BitmapDescriptorFactory.HUE_GREEN));

        mMap.addMarker(marker);

        mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {

            @Override

            public void onInfoWindowClick(Marker marker) {



            }

        });

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CHANDIGARH, 14));



    }



    @Override

    public void onMapLongClick(LatLng latLng) {

        mDismissOverlay.show();

    }



    @Override

    public void onMarkerDragEnd(Marker arg0) {

        LatLng dragPosition = arg0.getPosition();

        double dragLat = dragPosition.latitude;

        double dragLong = dragPosition.longitude;

        Log.i("info", "on drag end :" + dragLat + " dragLong :" + dragLong);

        PolylineOptions polylineOptions = new PolylineOptions();

        polylineOptions.color(Color.RED);

        polylineOptions.width(3);

        points.add(dragPosition);

        polylineOptions.addAll(points);

        mMap.addPolyline(polylineOptions);

        Toast.makeText(getApplicationContext(), "Distance ="+distance, Toast.LENGTH_LONG).show();

    }



    @Override

    public void onMarkerDragStart(Marker arg0) {

    }



    @Override

    public void onMarkerDrag(Marker marker) {

    }

}





2. activity_main.xml

<FrameLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:map="http://schemas.android.com/apk/res-auto"

    android:id="@+id/root_container"

    android:layout_height="match_parent"

    android:layout_width="match_parent">





    <FrameLayout

        android:id="@+id/map_container"

        android:layout_width="match_parent"

        android:layout_height="match_parent">



        <fragment

            android:id="@+id/map"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:name="com.google.android.gms.maps.SupportMapFragment"/>



    </FrameLayout>



    <android.support.wearable.view.DismissOverlayView

        android:id="@+id/dismiss_overlay"

        android:layout_height="match_parent"

        android:layout_width="match_parent"/>



</FrameLayout>





3.AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.watchmaps.androidsmartwatchmaps" >



    <!-- Permissions and features required for the Android Maps API v2 -->

    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    <uses-feature

        android:glEsVersion="0x00020000"

        android:required="true"/>



    <application

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:theme="@android:style/Theme.DeviceDefault" >

        <!-- API key for the Android Maps API v2. The value is defined as a string resource. -->

        <meta-data android:name="com.google.android.geo.API_KEY"

            android:value="@string/google_maps_key"/>

        <!-- Meta data required for Google Play Services -->

        <meta-data

            android:name="com.google.android.gms.version"

            android:value="@integer/google_play_services_version" />

        <activity

            android:name=".MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>



</manifest>





4. build.gradle

apply plugin: 'com.android.application'



android {

    compileSdkVersion 22

    buildToolsVersion "22.0.1"



    defaultConfig {

        applicationId "com.watchmaps.androidsmartwatchmaps"

        minSdkVersion 20

        targetSdkVersion 22

        versionCode 1

        versionName "1.0"

    }

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }

    }

}



dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile 'com.google.android.support:wearable:1.2.0'

    compile 'com.google.android.gms:play-services-wearable:7.5.0'

    compile 'com.google.android.gms:play-services-maps:7.5.0'

}



Happy coding
Cheers!!!


References : https://developers.google.com/maps/documentation/android/wear?hl=en

Wednesday, 27 May 2015

Designing Layouts for Wearables Android


So while designing layouts for wearable we need to keep both above types in mind so that our layout design looks perfectly fine on both round and square screens.

Android wearable fall's into two categories :

1. Round Shape
2. Square Shape

Now, question is how should we achieve this.Well i encountered some issues on round screen.My screen layout included text and image.So whenever text was large it was cutting in round edges from left side.

So after sometime,i camed to know about BoxInsetLayout which comes under android.support.wearable.view.BoxInsetLayout included in Wearable UI Library .
This helps us define a single layout that works both in round and square screens for wearbles.

Round Shape View


 Square Shape View


Now how to Make use of this lets have a look :




<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:padding="20dp">

    <android.support.v4.view.ViewPager
        android:id="@+id/myviewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.wearable.view.BoxInsetLayout>


1. android:padding="20dp" : Now this gives the padding to the BoxInsetLayout from all directions which creates a kind of rectangle for us and we've to work inside it.And this paddingapplies only to square screen of wearable as window insets on round devices are larger than 15 dp.

Note :BoxInsetLayout act as a parent and we have to create our layout inside this parent(like we do inside linear layout etc).

 2. android:padding="5dp" for our child view in this case view pager is our child : This padding applies on both round and square screens.
 
    For Square screen : this makes 20+5 = 25 dp padding
    For Round  screen :this makes 5    = 5 dp padding
 
 3. app:layout_box="all" :This line ensures that the ViewPager element and its children are boxed inside the area defined by the window insets on round screens. This line has no effect on square screens.



References : https://developer.android.com/training/wearables/ui/layouts.html#add-library


happy coding!!
Cheers !!

Monday, 25 May 2015

Android Wear Host Disconnected even after running connecting commands

A issue normally that we faced when we try to connect android wear(smartwatch) via android wear companion app

Host   : Disconnected.
Target : Connected.

This normally happens if you've connected with an emulator previously, Then it will cause an issue with the connection.

To solve this just follow below steps :

1. open android wear companion app
2. Go to settings
3. click on Emulator.
4. click on FORGET WATCH

That did the trick for me :-)

Posting by keeping in mind that you guys already know how to connect any wearable by running commands :-)

Cheers!!

Thursday, 14 May 2015

Duplicate ID binary XML error in fragments

When dealing Google V2 maps in android tabs and Fragments which generally come across with a issue i.e Duplicate ID binary XML error.

To be more specific Error faced is below :
android.view.InflateException: Binary XML file line #7: Error inflating class fragment

Now why this happens :

Because you already have the fragment added in the FragmentManager, you can't add the same fragment twice which will cause duplication of ID i.e two fragments with same ID.

Now this generally happens when we are adding a fragment that contains a fragment in its layout as well, mostly in case of map fragments.

Our tendency is to add Mapfragment in XML layout like this :

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

    <fragment

        android:id="@+id/map"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        class="com.google.android.gms.maps.SupportMapFragment" />



</LinearLayout>


And our Fragment inflate this layout like this :

public class LocationFragment extends Fragment {



View mView;

private static GoogleMap map;

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

mView = inflater.inflate(R.layout.locationfragment, container, false);

return mView;

}

}


Now if we see closely what happening here. We will add this fragment in a tab, which contains a fragment in its layout as well.This is the reason of problem here.

Note: You cannot inflate a layout into a fragment when that layout includes a <fragment>.Nested fragments are only supported when added to a fragment dynamically.

As per Andorid Documentation this approach is not recommended.We need to add map fragments Dynamically in order to accomplish nested fragments as per android guidelines.Check Nested fragments from below link :

http://developer.android.com/about/versions/android-4.2.html#NestedFragments

So Android-supported way is to add a fragment to another fragment is via a transaction from the child fragment manager as shown below :

XML Layout :

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:map="http://schemas.android.com/apk/res-auto"

   android:layout_width="match_parent"

   android:layout_height="match_parent" >

<!-- Lots of fancy layout -->  
<RelativeLayout
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </RelativeLayout>
</RelativeLayout>


Java Code Snippet :

public class MyFragment extends Fragment {

private SupportMapFragment fragment;
private GoogleMap map;

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.layout_with_map, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
    if (fragment == null) {
        fragment = SupportMapFragment.newInstance();
       fm.beginTransaction().replace(R.id.map, fragment).commit();
    }
}



@Override
public void onResume() {
    super.onResume();
    if (map == null) {
        map = fragment.getMap();
        map.addMarker(new MarkerOptions().position(new LatLng(0, 0)));
    }
}
}

There are other ways to resolve the errors as well if you are willing to you map fragment inside a XML layout.Below are the ways to solve the error :

1. Remove fragment on onDestroyView() :

@Override
public void onDestroyView() {
    super.onDestroyView();
    MapFragment f = (MapFragment) getFragmentManager()
                                         .findFragmentById(R.id.map);

    if (f != null)
        getFragmentManager().beginTransaction().remove(f).commit();
}



2. Remove the parent view if it exists in onCreateView() :

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (view != null) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
            parent.removeView(view);
    }
    try {
        view = inflater.inflate(R.layout.map, container, false);
    } catch (InflateException e) {
    }
    return view;
}
The above two methods will resolve our issue of duplicate ID in map fragment when dealing with fragments and tabs, but its kind of "Jugaad"(tricky way) as we say in HINDI.So this might be working now but might not working in upcoming versions of android.So better way to go is as Android Recommends.


References : http://developer.android.com/about/versions/android-4.2.html#NestedFragments , www.stackoverflow.com.

Happy Coding!!
Cheers.