Can't get location and email using Facebook API
In my Android application I developed this code to login with my account and get user property like name, location and email. The problem is I can get the name, but I can't get the email and the location. When I tried my code without try catch the application crush and my log point in getproperty("email")
and getlocation()
. When I use the try. The application work but there is no email or location.
public class Share extends Fragment {private static final String TAG ="Share";private UiLifecycleHelper uiHelper;
private View otherView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// To maintain FB Login session
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.share, container, false);
// Looks for Login button
LoginButton authButton = (LoginButton) view.findViewById(R.id.authButton);
authButton.setFragment(this);
// Set View that should be visible after log-in invisible initially
otherView = view.findViewById(R.id.other_views);
otherView.setVisibility(View.GONE);
//authButton.setReadPermissions(Arrays.asList("user_likes", "user_status","email","user_birthday"));
return view;
}
// Called when session changes
private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state,Exception exception) {
onSessionStateChange(session, state, exception);
}
};
// When session is changed, this method is called from callback method
private void onSessionStateChange(Session session, SessionState state,Exception exception) {
final TextView name = (TextView) getView().findViewById(R.id.name);
final TextView mail = (TextView) getView().findViewById(R.id.mail);
final TextView location = (TextView) getView().findViewById(R.id.location);
final TextView locale = (TextView) getView().findViewById(R.id.locale);
final TextView info = (TextView)getView().findViewById(R.id.msginfo);
final LinearLayout views= (LinearLayout)getView().findViewById(R.id.other_views);
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
// make request to the /me API to get Graph user
views.setVisibility(View.VISIBLE);
info.setText("You can now share images in facebook ");
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user
// object
@Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
try {
// Set view visibility to true
otherView.setVisibility(View.VISIBLE);
// Set User name
name.setText("Hello " + user.getName());
// Set Email
mail.setText("Your Email: " + user.getProperty("email").toString());
locale.setText("Locale: " + user.getProperty("locale").toString());
location.setText("Your Current Location: " + user.getLocation().getProperty("name").toString());
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}).executeAsync();
} else if (state.isClosed()) {
views.setVisibility(View.INVISIBLE);
info.setText("If you want to share images in Facebook, please Login");
Log.i(TAG, "Logged out...");
otherView.setVisibility(View.GONE);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
Log.i(TAG, "OnActivityResult...");
}
@Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
@Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
}
The issue is that you have not asked for permissions:
authButton.setReadPermissions(Arrays.asList("user_likes", "user_status","email","user_birthday"));
However, you are using an older Facebook SDK, while the newest SDK is 4.0.+. Below, I will give you a full sample code for Facebook login, based on the newest API. Keep in mind that you first have to add your application in developers.facebook
as the documentation mentions out.
public class LoginActivity extends ActionBarActivity{
@Override
protected void onActivityResult(int requestCode, int responseCode, Intent data)
{
super.onActivityResult(requestCode, responseCode, data);
callbackManager.onActivityResult(requestCode, responseCode, data);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(this.getApplicationContext());
setContentView(R.layout.activity_login);
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.loginFaceBook_button);
List<String> permissionNeeds = Arrays.asList("user_photos", "email", "user_birthday", "public_profile");
loginButton.setReadPermissions(permissionNeeds);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>()
{
@Override
public void onSuccess(LoginResult loginResult)
{
System.out.println("onSuccess");
GraphRequest request = GraphRequest.newMeRequest
(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback()
{
@Override
public void onCompleted(JSONObject object, GraphResponse response)
{
// Application code
Log.v("LoginActivity", response.toString());
//System.out.println("Check: " + response.toString());
try
{
String id = object.getString("id");
String name = object.getString("name");
String email = object.getString("email");
String gender = object.getString("gender");
String birthday = object.getString("birthday");
System.out.println(id + ", " + name + ", " + email + ", " + gender + ", " + birthday);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender, birthday");
request.setParameters(parameters);
request.executeAsync();
}
@Override
public void onCancel()
{
System.out.println("onCancel");
}
@Override
public void onError(FacebookException exception)
{
System.out.println("onError");
Log.v("LoginActivity", exception.getCause().toString());
}
});
}
}
If you want to use Fragment
instead of ActionBarActivity
, the just add loginButton.setFragment(this);
right after your permission line.
manifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
<!-- your other attrs..-->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/app_id"/> <!-- Get this one from developers.facebook -->
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:label="@string/app_name"/>
You will need to add to your application a hash key too. Here is a way to do this with code:
try
{
//paste Your package name at the first parameter
PackageInfo info = getPackageManager().getPackageInfo("PUT_YOUR_PACKAGE_NAME_HERE",
PackageManager.GET_SIGNATURES);
for (android.content.pm.Signature signature : info.signatures)
{
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String sign = Base64.encodeToString(md.digest(), Base64.DEFAULT);
Log.e("MY KEY HASH:", sign);
Toast.makeText(getApplicationContext(),sign, Toast.LENGTH_LONG).show();
}
}
catch (PackageManager.NameNotFoundException e)
{
}
catch (NoSuchAlgorithmException e)
{
}
After it prints you out the hash key, you copy paste it to your facebook.developer
account, where your project is located.
In grandle, you should add jcenter
in repositories
and also add compile 'com.facebook.android:facebook-android-sdk:4.0.0'
in dependecies
.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects
{
repositories {
jcenter()
/*more project attrs..*/
}
}
And the other grandle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "YOUR_PACKAGE_NAME"
minSdkVersion 14
targetSdkVersion 21
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:21.0.3'
compile 'com.facebook.android:facebook-android-sdk:4.0.0'
}
Edit:
In order to track the user's location, you will need a GPS Tracker, something like this. "user_location"
permission does not return a lon, lat
, but a Page object, which I think is not what you want. So, your permissions should be List<String> permissionNeeds = Arrays.asList("user_photos", "email", "user_birthday", "public_profile");
and now you should be able to retrieve user's email