Thursday, December 5, 2019

Password Hide and Show Android

Create your XML using EditText with ImageView.
   <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/ten_view_size"
    android:background="@drawable/border_edittext">

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_margin="1dp"
        android:layout_weight="1"
        android:background="@color/white"
        android:inputType="textPassword"
        android:padding="@dimen/ten_view_size"
        android:singleLine="true" />

    <ImageView
        android:id="@+id/visibility"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:paddingLeft="@dimen/margin_10"
        android:paddingRight="@dimen/margin_10"
        android:src="@drawable/hide_password_eye"
        android:tag="1" />

</LinearLayout>
use this code for show and hide the password.
 public static void changeVisibility(EditText mPassword, ImageView mIcon) {
    if (mIcon.getTag().toString().equals("0")) {
        mIcon.setImageResource(R.drawable.hide_password_eye);
        mPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        mIcon.setTag("1");
    } else {
        mIcon.setImageResource(R.drawable.show_password_eye);
        mPassword.setInputType(InputType.TYPE_CLASS_TEXT);
        mIcon.setTag("0");
    }
    mPassword.setSelection(mPassword.getText().length());
  }

That is all. If any help related to this post please comment.

Thank you, guys.

Enjoy coding.

Pass Data Using Parecable and Serizable Android

In Android, we cannot just pass objects to activities. To do this the objects must either implement Serializable or Parcelable interface.
Serializable
Serializable is a standard Java interface. You can just implement Serializable interface and add override methods. The problem with this approach is that reflection is used and it is a slow process. This method creates a lot of temporary objects and causes quite a bit of garbage collection. However, Serializable interface is easier to implement.
Look at the example below (Serializable):
// MyObjects Serializable class

import java.io.Serializable;
import java.util.ArrayList;
import java.util.TreeMap;

import android.os.Parcel;
import android.os.Parcelable;

public class MyObjects implements Serializable {

    private String name;
    private int age;
    public ArrayList<String> address;

    public MyObjects(String name, int age, ArrayList<String> address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public ArrayList<String> getAddress() {
        if (!(address == null))
            return address;
        else
            return new ArrayList<String>();
    }

    public String getName() {
        return name;
    }

    public String getAge() {
        return age;
    }
}
// MyObjects instance
MyObjects mObjects = new MyObjects("name", "age", "Address array here");

// Passing MyObjects instance via intent
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects)    mIntent.getSerializableExtra("UniqueKey");
Parcelable
Parcelable process is much faster than Serializable. One of the reasons for this is that we are being explicit about the serialization process instead of using reflection to infer it. It also stands to reason that the code has been heavily optimized for this purpose.
Look at the example below (Parcelable):
// MyObjects Parcelable class

import java.util.ArrayList;

import android.os.Parcel;
import android.os.Parcelable;

public class MyObjects implements Parcelable {

    private int age;
    private String name;
    private ArrayList<String> address;

    public MyObjects(String name, int age, ArrayList<String> address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public MyObjects(Parcel source) {
        age = source.readInt();
        name = source.readString();
        address = source.createStringArrayList();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(age);
        dest.writeString(name);
        dest.writeStringList(address);
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public ArrayList<String> getAddress() {
        if (!(address == null))
            return address;
        else
            return new ArrayList<String>();
    }

    public static final Creator<MyObjects> CREATOR = new Creator<MyObjects>() {
        @Override
        public MyObjects[] newArray(int size) {
            return new MyObjects[size];
        }

        @Override
        public MyObjects createFromParcel(Parcel source) {
            return new MyObjects(source);
        }
    };
}
// MyObjects instance
MyObjects mObjects = new MyObjects("name", "age", "Address array here");

// Passing MyOjects instance
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
MyObjects workorder = (MyObjects) mIntent.getParcelableExtra("UniqueKey");
You can pass ArrayList of Parcelable objects as below:
// Array of MyObjects
ArrayList<MyObjects> mUsers;

// Passing MyOjects instance
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putParcelableArrayListExtra("UniqueKey", mUsers);
startActivity(mIntent);
// Getting MyObjects instance
Intent mIntent = getIntent();
ArrayList<MyObjects> mUsers = mIntent.getParcelableArrayList("UniqueKey");
Conclusion
  1. Parcelable is faster than Serializable interface
  2. Parcelable interface takes more time to implement compared to Serializable interface
  3. Serializable interface is easier to implement
  4. Serializable interface creates a lot of temporary objects and causes quite a bit of garbage collection
  5. Parcelable array can be passed via Intent in android
Use this for Custom Object
public class ResultData implements Parcelable {

public ResultData(Integer id, String name, String tag, String color, List<Criterium> criteria) {
    this.id = id;
    this.name = name;
    this.tag = tag;
    this.color = color;
    this.criteria = criteria;
}

@NonNull
@PrimaryKey()
@SerializedName(value = "id")
@Expose
private Integer id;

@ColumnInfo(name = "name")
@SerializedName("name")
@Expose
private String name;

@ColumnInfo(name = "tag")
@SerializedName("tag")
@Expose
private String tag;

@ColumnInfo(name = "color")
@SerializedName("color")
@Expose
private String color;

@ColumnInfo(name = "ListData")
@TypeConverters(DataTypeConverter.class)
@SerializedName("criteria")
@Expose
private List<Criterium> criteria = new ArrayList<>();

protected ResultData(Parcel in) {
    if (in.readByte() == 0) {
        id = null;
    } else {
        id = in.readInt();
    }
    name = in.readString();
    tag = in.readString();
    color = in.readString();
    in.readTypedList(criteria, Criterium.CREATOR);
}

public static final Creator<ResultData> CREATOR = new Creator<ResultData>() {
    @Override
    public ResultData createFromParcel(Parcel in) {
        return new ResultData(in);
    }
    
    @Override
    public ResultData[] newArray(int size) {
        return new ResultData[size];
    }
};

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getTag() {
    return tag;
}

public void setTag(String tag) {
    this.tag = tag;
}

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public List<Criterium> getCriteria() {
    return criteria;
}

public void setCriteria(List<Criterium> criteria) {
    this.criteria = criteria;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    
    if (id == null) {
        dest.writeByte((byte) 0);
    } else {
        dest.writeByte((byte) 1);
        dest.writeInt(id);
    }
    dest.writeString(name);
    dest.writeString(tag);
    dest.writeString(color);
    dest.writeTypedList(criteria);
}

public static Creator<ResultData> getCREATOR() {
    return CREATOR;
}
}

Note:- All its Methods and Variable must be Used Parecable

Use this for List<List<String>>
Extending ArrayList and implementing Parcelable on it worked for me.
    public class ParcelableArrayList extends ArrayList<String> implements 
        Parcelable {

    private static final long serialVersionUID = -8516873361351845306L;

    public ParcelableArrayList(){
        super();
    }

    protected ParcelableArrayList(Parcel in) {
        in.readList(this, String.class.getClassLoader());
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(this);
    } 

    public static final Parcelable.Creator<ParcelableArrayList> CREATOR = 
            new Parcelable.Creator<ParcelableArrayList>() {
        public ParcelableArrayList createFromParcel(Parcel in) {
            return new ParcelableArrayList(in);
        }

        public ParcelableArrayList[] newArray(int size) {
            return new ParcelableArrayList[size];
        }
    };

}
and Employee class
class Employee implements Parcelable {

    List<ParcelableArrayList> details;
    //.......

    protected Employee(Parcel in) {
        details = new ArrayList<ParcelableArrayList>();
        in.readTypedList(details,ParcelableArrayList.CREATOR);
        //......
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(details);
        //.....
    }

    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<Employee> CREATOR = 
            new Parcelable.Creator<Employee>() {
        public Employee createFromParcel(Parcel in) {
            return new Employee(in);
        }

        public Employee[] newArray(int size) {
            return new Employee[size];
        }
    };

    }
Use this for List<List<Object>>.....
Based on comments, I extended the ArrayList class with my custom class and implemented parcelable:
    public class TileList extends ArrayList<Tile> implements Parcelable {

    public TileList(){
        super();
    }

    protected TileList(Parcel in) {
        in.readTypedList(this, Tile.CREATOR);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeTypedList(this);
    }

    public static final Parcelable.Creator<TileList> CREATOR = new Parcelable.Creator<TileList>() {
        public TileList createFromParcel(Parcel in) {
            return new TileList(in);
        }

        public TileList[] newArray(int size) {
            return new TileList[size];
        }
    };
    }
and slight changes to my other class:
    public class GameBoard implements Parcelable {
    private String _id;
    public String getId() { return _id; }
    public void setId(String id) { _id = id; }

    private List<TileList> _tiles;
    public List<TileList> getTiles() { return _tiles; }
    public void setTiles(List<TileList> tiles) { _tiles = tiles; }

    public GameBoard(Parcel in) {
        _id = in.readString();
        _tiles = new ArrayList<>();
        in.readTypedList(_tiles, TileList.CREATOR);
    }

    public GameBoard() {

    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(_id);
        parcel.writeTypedList(_tiles);
    }

    public static final Parcelable.Creator<GameBoard> CREATOR = new Parcelable.Creator<GameBoard>() {
        public GameBoard createFromParcel(Parcel in) {
            return new GameBoard(in);
        }

        public GameBoard[] newArray(int size) {
            return new GameBoard[size];
        }
    };
    }

That is all. If any help related to this post please comment.

Thank you, guys.

Enjoy coding.

OverFlow/3 Dots Menu Android

Create an Overflow menu inside Activity and Fragment.
@SuppressLint("RestrictedApi")
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    menu.clear();
    getMenuInflater().inflate(R.menu.all_page_menu, menu);
    if(menu instanceof MenuBuilder) {  
        MenuBuilder m = (MenuBuilder) menu;
        m.setOptionalIconsVisible(true);
    }
    return true;
}
From this Link.
OR
Create a menu like this. Here ic_more_vert is 3 dot image.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <item
        android:id="@+id/none"
        android:icon="@drawable/ic_more_vert"
        android:title=""
        app:showAsAction="always">

        <menu>

            <item
                android:id="@+id/home"
                android:icon="@drawable/home"
                android:title="HOME" />       

        </menu>
    </item>


    <item
        android:id="@+id/add"
        android:icon="@drawable/plus_white"
        android:orderInCategory="100"
        android:title="Add"
        app:showAsAction="always" />

</menu>
That is all. If any help related to this post please comment.

Thank you, guys.

Enjoy coding.

NestedScrollView With RecycleView Problem


When we have multiple Recycle View in NestedScrollView. Most of the times top views hide behind the toolbar and Recycle View Data comes on top. For resolving these problems use Layout like below ....
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">

<LinearLayout
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">

 <TextView/>

 <EditText/>

 <Button />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:nestedScrollingEnabled="false" />

 </LinearLayout>

</android.support.v4.widget.NestedScrollView>
and use this line in your Activity or Fragment.
    RecyclerView  mList = view.findViewById(R.id.recycle);
    ViewCompat.setNestedScrollingEnabled(mList, false);

Hide Keyboard in Android

The following snippet simply hides the keyboard:
public static void hideSoftKeyboard(Activity activity) {
 InputMethodManager inputMethodManager = 
        (InputMethodManager) activity.getSystemService(
            Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(
        activity.getCurrentFocus().getWindowToken(), 0);
}
You can put this up in a utility class, or if you are defining it within an activity, avoid the activity parameter, or call hideSoftKeyboard(this).
The trickiest part is when to call it. You can write a method that iterates through every View in your activity, and check if it is an instanceof EditText if it does not register a setOnTouchListener to that component and everything will fall in place. In case you are wondering how to do that, it is in fact quite simple. Here is what you do, you write a recursive method like the following, in fact, you can use this to do anything, like setup custom typefaces, etc... Here is the method
public void setupUI(View view) {

 // Set up touch listener for non-text box views to hide keyboard.
 if (!(view instanceof EditText)) {
  view.setOnTouchListener(new OnTouchListener() {
   public boolean onTouch(View v, MotionEvent event) {
    hideSoftKeyboard(MyActivity.this);
    return false;
   }
  });
 }

    //If a layout container, iterate over children and seed recursion.
 if (view instanceof ViewGroup) {
  for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
   View innerView = ((ViewGroup) view).getChildAt(i);
   setupUI(innerView);
  }
    }
}
That is all, just call this method after you setContentView in your activity. In case you are wondering what parameter you would pass, it is the id of the parent container. Assign an id to your parent container like
<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>
and call setupUI(findViewById(R.id.parent)), that is all.
If you want to use this effectively, you may create an extended Activity and put this method in, and make all other activities in your application extend this activity and call its setupUI() in the onCreate() method.
Hope it helps.
If you use more than 1 activity define common id to parent layout like <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>
Then extend a class from Activity and define setupUI(findViewById(R.id.main_parent)) Within its OnResume() and extend this class instead of ``Activity in your program
From this Link.

Hide keyboard on Back press.

create class called Util and put this code
public static void hideSoftKeyboard(Activity activity) {
 final InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
 if (inputMethodManager.isActive()) {
  if (activity.getCurrentFocus() != null) {
   inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
  }
 }
}
and call on the onBackPressed() of Activity

That is all. If any help related to this post please comment.

Thank you, guys. 


Enjoy coding.

Internet Dialog in Android


Create XML with one Button(id is retry) and Image View.


<LinearLayout android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_margin="20dp"
    android:layout_height="wrap_content">


    <ImageView
        android:id="@+id/imageview"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_below="@id/title"
        android:src="@drawable/internet"/>

    <Button
        android:id="@+id/retry"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_below="@id/imageview"
        android:theme="@style/Button"
        android:gravity="center"
        android:layout_margin="10dp"
        android:text="Retry"
        android:textColor="@android:color/white"
        android:textStyle="bold"/>

</LinearLayout>


Here is dialog for internet
    public static void showInternetdialog(final Context context, final Fragment fragment) {
    final Dialog dialog;
    dialog = new Dialog(context);
    dialog.setContentView(R.layout.internet);
    final PetHealthTextView refresh = dialog.findViewById(R.id.retry);
    refresh.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isConnected(context)) {
                if (fragment != null) {
                    FragmentTransaction ft = ((AppCompatActivity) context).getSupportFragmentManager().beginTransaction();
                    ft.detach(fragment).attach(fragment).commit();
                } else {
                    ((Activity) context).recreate();
                }
                dialog.cancel();
            } else dialog.show();
            
        }
    });
    dialog.setCancelable(false);
    dialog.show();
    }
isConnected method
    public static boolean isConnected(Context context) {
    if (!ConnectivityReceiver.isConnected(context)) {
        return false;
    }
    return true;
    }
ConnectivityReceiver.class
public class ConnectivityReceiver extends BroadcastReceiver {
public static ConnectivityReceiverListener connectivityReceiverListener;
@Override
public void onReceive(Context context, Intent intent) {
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();

    if (connectivityReceiverListener != null) {
        connectivityReceiverListener.onNetworkConnectionChanged(isConnected);
    }
}

public static boolean isConnected(Context context) {
    ConnectivityManager
            cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();
}    public interface ConnectivityReceiverListener {
    void onNetworkConnectionChanged(boolean isConnected);
}

}

That is all. If any help related to this post please comment.

Thank you, guys.

Enjoy coding.

Google Login in Android

Initialization of GoogleSignInOptions, GoogleSignInClient And Button.
    findViewById(R.id.gmail).setOnClickListener(this);
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

    GoogleSignInClient mGoogleSignInClient = GoogleSignIn.getClient(activity, gso);
use this on Button Click
     Intent signInIntent = mGoogleSignInClient.getSignInIntent();
     startActivityForResult(signInIntent, 101);
You will get your result onActivityResult method
@Override
   public void onActivityResult(int requestCode, int resultCode, Intent data) {
    
    if (requestCode == 101) {
        // The Task returned from this call is always completed, no need to attach
        // a listener.
        Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
        handleSignInResult(task);
    } 
    super.onActivityResult(requestCode, resultCode, data);
  }
All process of getting user Data.
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
    try {
        GoogleSignInAccount account = completedTask.getResult(ApiException.class);
        Log.d("sam",account.getDisplayName()+" "+account.getEmail()+" "+account.getId());
        // Signed in successfully, show authenticated UI.
        // ..updateUI(account);
    } catch (ApiException e) {
        // The ApiException status code indicates the detailed failure reason.
        // Please refer to the GoogleSignInStatusCodes class reference for more information.
        Log.d("sam", "signInResult:failed code=" + e.getStatusCode());
    }
   }
Sign Out from App call these method
private void signOut() {
mGoogleSignInClient.signOut()
        .addOnCompleteListener(this, new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // ...
            }
        });
 }
Gradle config
Project.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {

repositories {
    google()//google login
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle:3.2.1'
    classpath 'com.google.gms:google-services:4.0.1'//google login
    

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
}

allprojects {
repositories {
    google()//google login
    jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
Module gradle
implementation 'com.google.android.gms:play-services-auth:16.0.1'
menifest.xml
//Permisiion
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
Google Developer Link
That is all. If any help related to this post please comment.
Thank you, guys. 
Enjoy coding.

Facebook Login in Android

Integrate the Facebook SDK

The Facebook Login SDK for Android is a component of the Facebook SDK for Android. To use the Facebook Login SDK in your project, make it a dependency in Maven, or download it. Choose the method you prefer with the following button.
  1. Go to Android Studio | New Project | Minimum SDK
  2. Select "API 15: Android 4.0.3" or higher and create your new project.
  3. In your project, open your_app | Gradle Scripts | build.gradle
  4. Add the Maven Central Repository to build.gradle before dependencies:
    repositories { mavenCentral() }
  5. Add compile 'com.facebook.android:facebook-android-sdk:[4,5)' to your build.gradle dependencies.

Using Maven

  1. In your project, open your_app > Gradle Scripts > build.gradle (Project) make sure the following repository is listed in the buildscript { repositories {}}:
    jcenter() 
  2. In your project, open your_app > Gradle Scripts > build.gradle (Module: app) and add the following implementation statement to the dependencies{} section to depend on the latest version of the Facebook Login SDK:
     implementation 'com.facebook.android:facebook-login:[5,6)'
  3. Build your project.

string.xml
       <string name="facebook_app_id">XXXXXXXXXXXXX</string>
       <string name="fb_login_protocol_scheme">fb22XXXXXX60580447282</string>
menifest.xml
//permission
<uses-permission android:name="android.permission.INTERNET"/>
//applicaltion tag
<activity android:name="com.facebook.FacebookActivity"
    android:configChanges=
            "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
    android:label="@string/app_name" />
<activity
    android:name="com.facebook.CustomTabActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="@string/fb_login_protocol_scheme" />
    </intent-filter>
</activity>

Initialization of CallBackManager And Button.
    CallbackManager  callbackManager = CallbackManager.Factory.create();
    Button loginButton = (Button) findViewById(R.id.facebook);
    loginButton.setOnClickListener(this);
And use this facebookIntegration() method in your onClick method.
  private void facebookIntegration() {
    
    LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"));
    //  LoginButton.setLoginBehavior(LoginBehavior.WEB_ONLY);
    LoginManager.getInstance().registerCallback(callbackManager,
            new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    // App code
                    
                    Bundle facebookBundle = getFacebookData(loginResult.getAccessToken());
                    
                }
                
                @Override
                public void onCancel() {
                    //  Log.d("sam", "cancel");
                    // App code
                }
                
                @Override
                public void onError(FacebookException exception) {
                    // Log.d("sam", new Gson().toJson(exception));
                    // App code
                }
            });
}

private Bundle getFacebookData(final AccessToken token) {
    final Bundle facebookBundle = new Bundle();
    facebookBundle.putString("fields", "id,name,email");
    
    GraphRequest request = GraphRequest.newMeRequest(token,
            new GraphRequest.GraphJSONObjectCallback() {
                
                @Override
                public void onCompleted(JSONObject object, GraphResponse response) {
                    String name = "", email = "", id = "";
                    try {
                        name = object.getString("name");
                    } catch (JSONException e) {
                        name = "";
                        e.printStackTrace();
                        
                    }
                    
                    try {
                        email = object.getString("email");
                    } catch (JSONException e) {
                        email = "";
                        e.printStackTrace();
                        
                    }
                    
                    try {
                        id = object.getString("id");
                    } catch (JSONException e) {
                        id = "";
                        e.printStackTrace();
                        
                    }
                    
                    Log.d("sam", name + " " + email + " "+ id);
                    
                    Log.d("sam", "Object = " + object.toString());
                    
                }
            });
    request.setParameters(facebookBundle);
    request.executeAsync();
    
    
    return facebookBundle;
 }
And use your callbackManager.onActivityResult() method of your activity or fragment onActivityResult method.
@Override
   public void onActivityResult(int requestCode, int resultCode, Intent data) {
     callbackManager.onActivityResult(requestCode, resultCode, data);
     super.onActivityResult(requestCode, resultCode, data);
  }
Note: Please Config your manifest and Gradle before using this code.

That is all. If any help related to this post please comment.

Thank you, guys. 

Enjoy coding.