Working on Facebook. Unable to get publish_actions permission. Using this code:
session.requestNewPublishPermissions(new
Session.NewPermissionsRequest(this, PERMISSION));
any solution...
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private boolean pendingPublishReauthorization = false;
in onActivityResult do this
Session session = Session.getActiveSession();
if (session != null) {
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermsnRequest = new Session.NewPermissionsRequest(
this, PERMISSIONS);
session.requestNewPublishPermissions(newPermsnRequest );
return;
}
}
Also implement this in your class.
private boolean isSubsetOf(Collection<String> a,
Collection<String> b) {
for (String string : a) {
if (!b.contains(string)) {
return false;
}
}
return true;
}
By doing this you will be able to get all the public permissions. you have to open the session after getting read permissions and then only request for publish permissions.
Facebook sdk only returns read-permission, but not the write permissions. You can user the "/me" endpoint to get all the permissions.
final Bundle permBundle = new Bundle();
permBundle.putCharSequence("permission", "publish_actions");
GraphRequest request = new GraphRequest(
AccessToken.getCurrentAccessToken(),
"/me/permissions", permBundle, HttpMethod.GET,
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse graphResponse) {
Log.d(TAG, "response2: " + graphResponse.getJSONObject());
try {
JSONArray permList = (JSONArray) graphResponse.getJSONObject().get("data");
if(permList.length() == 0){
// no data for perms, hence asking permission
askForFBPublishPerm();
}else{
JSONObject permData = (JSONObject) permList.get(0);
String permVal = (String) permData.get("status");
if(permVal.equals("granted")){
postToFB();
}else{
askForFBPublishPerm();
}
}
} catch (JSONException e) {
Log.d(TAG, "exception while parsing fb check perm data" + e.toString());
}
}
}
);
request.executeAsync();
Related
I have a confusable situation here. In my android app, I am using Fb login and SDK.Things work fine when fb native app is not present.But when fb app is there and login is done then FB provides info only when I logged on with native FB app and not when somebody else logins. The screen just flashes once and goes away. I have also found that roles that are listed in app on fb including me (admin) & testers are able to fetch information, but not the other normal users. I have tried but I dont know where the fault is happening?
thanks.
public void signInWithFacebook() {
Constant.printKeyHash(MainActivity.this);
mSessionTracker = new SessionTracker(mContext, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
}
}, null, false);
String applicationId = Utility.getMetadataApplicationId(mContext);
Constant.mCurrentSession = mSessionTracker.getSession();
if (Constant.mCurrentSession == null || Constant.mCurrentSession.getState().isClosed()) {
mSessionTracker.setSession(null);
Session session = new Session.Builder(mContext).setApplicationId(applicationId).build();
Session.setActiveSession(session);
Constant.mCurrentSession = session;
} else {
mSessionTracker.setSession(null);
Session session = new Session.Builder(mContext).setApplicationId(applicationId).build();
Session.setActiveSession(session);
Constant.mCurrentSession = session;
}
if (!Constant.mCurrentSession.isOpened()) {
Session.OpenRequest openRequest = null;
openRequest = new Session.OpenRequest((Activity) mContext);
if (openRequest != null) {
openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS);
openRequest.setPermissions(Arrays.asList("user_birthday", "email", "user_location", "user_friends"));
openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
Constant.mCurrentSession.openForRead(openRequest);
try {
// progressfb.show();
// progressfb.setCancelable(false);
}
catch (Exception e)
{
}
accessFacebookUserInfo();
}
} else {
// progressfb.show();
accessFacebookUserInfo();
}
}
public void accessFacebookUserInfo() {
if (Session.getActiveSession() != null || Session.getActiveSession().isOpened()) {
Bundle bundle = new Bundle();
bundle.putString("fields", "picture,email,first_name, last_name, name");
// bundle.putString("fields", "email");
// bundle.putString("fields", "first_name");
final Request request = new Request(Session.getActiveSession(), "me", bundle, HttpMethod.GET, new Request.Callback() {
#SuppressWarnings("unused")
#Override
public void onCompleted(Response response) {
GraphObject graphObject = response.getGraphObject();
if (graphObject != null) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject = graphObject.getInnerJSONObject();
Log.i("", "faacebook response===" + jsonObject.toString());
String facebook_id = jsonObject.getString("id");
JSONObject picture_obj = jsonObject.getJSONObject("picture");
JSONObject picture_data = picture_obj.getJSONObject("data");
// fb_pic_url = picture_data.getString("url");
String first_name = jsonObject.getString("name");
String last_name = jsonObject.getString("last_name");
String socialName = jsonObject.getString("name");
eemail = jsonObject.getString("email");
String fb_pic_url = "https://graph.facebook.com/"
+ facebook_id
+ "/picture?type=large";
new fbSigninActivity().execute(eemail,first_name);
callFacebookLogout(MainActivity.this);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(mContext, "something went wrong", Toast.LENGTH_LONG).show();
}
}
}
});
Request.executeBatchAsync(request);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
// com.facebook.Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
if (Constant.mCurrentSession.isOpened()) {
accessFacebookUserInfo();
} else {
//Utils.showCenterToast(contxt, getResources().getString(R.string.msg_went_wrong));
}
} else {
Constant.mCurrentSession = null;
mSessionTracker.setSession(null);
// progressfb.dismiss();
}
}
The issue is happening because the feature you are trying to use needs to be approved by Facebook first. You must submit an APK for them to test. Anyone listed as an Admin, Developer, or Tester of your app should work fine (you may need to add their debug hash of the device to the list). But until your app gets approved by Facebook to use specific features or Graph Calls normal users will NOT be able to use it.
I want to publish link if the user is logged in facebook and if not make user logged in and then publish link but it shows NullPointerException at jsonobject graphresponse in the publishlink() method.
Following is my code..
public static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
public static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
public boolean pendingPublishReauthorization = false;
private Session.StatusCallback statusCallback = new SessionStatusCallback();
public void ShareOnFacebook(String sharingpath)
{
Session currentSession = Session.getActiveSession();
if (currentSession == null || currentSession.getState().isClosed()) {
Session session = new Session.Builder(getBaseContext()).build();
Session.setActiveSession(session);
currentSession = session;
}
else if (!currentSession.isOpened()) {
// Ask for username and password
OpenRequest op = new Session.OpenRequest(this);
op.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);
op.setCallback(statusCallback);
List<String> permissions = new ArrayList<String>();
permissions.add("publish_stream");
op.setPermissions(permissions);
Session session = new Session(this);
Session.setActiveSession(session);
Log.d("session", "opening sesion for publish action!!");
session.openForPublish(op);
}
}
private class SessionStatusCallback implements Session.StatusCallback
{
#Override
public void call(final Session session, SessionState state, Exception exception)
{
//we have callback here
if (session.isOpened())
{
Log.d("session", "session is already opened ,we are in the callback section...going to publish link!!");
PublishLink();
}
}
}
public void PublishLink()
{
SharedPreferences prefs = getSharedPreferences("shared",MODE_PRIVATE);
String path = prefs.getString("path", "");
Session session = Session.getActiveSession();
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this,PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
}
Bundle postParams = new Bundle();
postParams.putString("link", path);
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
Log.d("graphresponse", response.toString());
JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.d(
"JSON error "+ e.getMessage(), postId);
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(
getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(
getApplicationContext(),
postId,
Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/feed", postParams, HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
public boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
Log.d("data", "data coming to onactivityresult: "+data);
}
The problem here is that the requestNewPublishPermissions() method is an asynchronous request, and when you call it, it returns immediately, but at that point, you don't have the publish permissions yet.
What you're doing is making a "publish" request, regardless of whether you have the publish permissions yet, and so the response is going to have an error rather than a GraphObject result.
If you check the response.getError(), you'll likely see a permission error (you should always check that first, before accessing anything else in the Response).
Have a look at the HelloFacebook sample on how to temporarily cache the information you want to post (while you wait for the requestNewPublishPermissions to finish), and only post when you have all the permissions necessary.
finally figured out there was error in
Request request = new Request(session, "me/feed", postParams, HttpMethod.POST, callback);
so change it to
Request request = Request.newStatusUpdateRequest(session, path, callback);
hope this helps someone who have this problem.
so we donot need to create new Bundle anymore ....
we can remove create Bundle and postparams.putString lines in above code..
I am attempting to publish to facebook with custom opengraph objects. I am not getting any error on running the code, but no posts are published either.
I refered to the following tutorial for the code.
https://developers.facebook.com/docs/android/share-using-the-object-api/
This is my code.
// Check for publish permissions
Log.w("FBShare", "Publish Story not null");
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(
this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
Log.w("FBShare", "has permission");
return;
}
progressDialog = ProgressDialog.show(this, "", "LOADING..", true);
RequestBatch requestBatch = new RequestBatch();
OpenGraphObject match = OpenGraphObject.Factory
.createForPost("cricdecode:match");
match.setTitle("My match");
match.getData().setProperty("my_team", "Team A");
match.getData().setProperty("opponent", "Team B");
match.getData().setProperty("venue", "some plc");
// Set up the object request callback
Request.Callback objectCallback = new Request.Callback() {
#Override
public void onCompleted(Response response) {
// Log any response error
FacebookRequestError error = response.getError();
if (error != null) {
dismissProgressDialog();
Log.w("FBShare", "error");
}
}
};
Request objectRequest = Request.newPostOpenGraphObjectRequest(
Session.getActiveSession(), match, objectCallback);
objectRequest.setBatchEntryName("objectCreate");
requestBatch.add(objectRequest);
requestBatch.executeAsync();
OpenGraphAction playAction = OpenGraphAction.Factory
.createForPost();
playAction.setProperty("match", "{result=objectCreate:$.id}");
// Set up the action request callback
Request.Callback actionCallback = new Request.Callback() {
#Override
public void onCompleted(Response response) {
dismissProgressDialog();
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(
MainActivity.main_context
.getApplicationContext(),
"Error 1: "+error.getErrorMessage(), Toast.LENGTH_LONG)
.show();
} else {
String actionId = null;
try {
JSONObject graphResponse = response
.getGraphObject().getInnerJSONObject();
actionId = graphResponse.getString("id");
} catch (JSONException e) {
}
Toast.makeText(
MainActivity.main_context
.getApplicationContext(),
actionId, Toast.LENGTH_LONG).show();
}
}
};
// Create the publish action request
Request actionRequest = Request.newPostOpenGraphObjectRequest(
Session.getActiveSession(), match, actionCallback);
// Add the request to the batch
requestBatch.add(actionRequest);
I guess FingerPrint and Hash code what you generated might me different. If you still facing the same problem follow the below link to generate a new Hash key from your machine,
Key hash for Android-Facebook app
Place the generated Hash key in your Face book developer account and try again.
I guess the problem is here:
// Create the publish action request
Request actionRequest = Request.newPostOpenGraphObjectRequest(
Session.getActiveSession(), match, actionCallback);
Change it to :
// Create the publish action request
Request actionRequest = Request.newPostOpenGraphActionRequest(
Session.getActiveSession(), playAction, actionCallback);
The problem is that you are calling executeAsync() before adding the actionRequest to the batch. Thus, you just create the object but no action is performed.
Change your code to:
// Add the request to the batch
requestBatch.add(actionRequest);
requestBatch.executeAsync();
I'm trying to give users an option to set/revoke publishing permission via checkbox (Facebook SDK for Android). Code is provided below. Everything works fine except that after revoking the code responsible for checking publishing permissions fails miserably.
I understand that Session has no way of knowing if user has revoked any permissions after loggin in. What is the correct way to handle this kind of situation? Do I have to query available permissions manually, or is there a way to seamlessly recreate session with basic permissions?
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
publishCheckbox = (CheckBox) view.findViewById(R.id.publishCheckbox);
publishCheckbox.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
CheckBox chb = (CheckBox) v;
if (chb.isChecked() && checkForPublishPermission() == false){
requestPublishPermissions();
}
else{
removePublishPermissions();
}
}
});
...
}
private void requestPublishPermissions() {
Session session = Session.getActiveSession();
if ( session!= null && session.isOpened()){
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, PERMISSIONS).setRequestCode(REAUTH_ACTIVITY_CODE);
newPermissionsRequest.setCallback(callback);
session.requestNewPublishPermissions(newPermissionsRequest);
}
}
private void removePublishPermissions() {
Request r = new Request(Session.getActiveSession(), PUBLISH_ACTIONS_PERMISSION_PATH, null, HttpMethod.DELETE);
r.setCallback(new Request.Callback() {
#Override
public void onCompleted(Response response) {
publishCheckbox.setEnabled(true);
}
});
r.executeAsync();
publishCheckbox.setEnabled(false);
}
private boolean checkForPublishPermission(){
boolean result = false;
Session session = Session.getActiveSession();
if (session == null || !session.isOpened()) {
result = false;
}
else{
List<String> permissions = session.getPermissions();
if (permissions.containsAll(PERMISSIONS)) {
result = true;
}
}
return(result);
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
...
publishCheckbox.setChecked(checkForPublishPermission());
...
} else if (state.isClosed()) {
...
}
}
Well I ended up requesting user permissions each time I needed such a check, something along these lines:
private void checkForPublishPermission(){
mPublishCheckbox.setEnabled(false);
Request r = new Request(Session.getActiveSession(), PUBLISH_ACTIONS_PERMISSION_PATH, null, HttpMethod.GET);
r.setCallback(new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (response != null) {
GraphObject o = response.getGraphObject();
if ( o != null){
JSONArray data = o.getInnerJSONObject().optJSONArray("data");
mCanPublish = (data.optJSONObject(0).has("publish_actions"))?true:false;
mPublishCheckbox.setChecked(mCanPublish);
}
}
mPublishCheckbox.setEnabled(true);
}
});
r.executeAsync();
}
I would like to get the friendlist of the facebook using intent.
Please let me know if there is any way to get the friends list of the facebook by using built in application of the device.
Thanks.
You need to integrate the Android SDK into your app, here is the link to download the latest SDK. You then will have to have the user authenticate your app to access their information.
Here is sample code to do this
private SessionTracker mSessionTracker;
private Session mCurrentSession;
private void signInWithFacebook() {
mSessionTracker = new SessionTracker(getBaseContext(), new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
}
}, null, false);
String applicationId = Utility.getMetadataApplicationId(getBaseContext());
mCurrentSession = mSessionTracker.getSession();
if (mCurrentSession == null || mCurrentSession.getState().isClosed()) {
mSessionTracker.setSession(null);
Session session = new Session.Builder(getBaseContext()).setApplicationId(applicationId).build();
Session.setActiveSession(session);
mCurrentSession = session;
}
if (!mCurrentSession.isOpened()) {
Session.OpenRequest openRequest = null;
openRequest = new Session.OpenRequest(SignUpChoices.this);
if (openRequest != null) {
openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS);
openRequest.setPermissions(Arrays.asList("user_birthday", "email", "user_location"));
openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
mCurrentSession.openForRead(openRequest);
Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
Log.w("myConsultant", user.getId() + " " + user.getName() + " " + user.getInnerJSONObject());
}
});
}
}
}
One you have a user that has approved your app you can perform other Request about their information. friends info example
Finally i found a way to get the friendlist of the Facebook using Intent.
Intent m_fb=getOpenFacebookIntent(m_context);
startActivity(m_fb);
public static Intent getOpenFacebookIntent(Context context) {
try {
context.getPackageManager().getPackageInfo("com.facebook.katana", 0);
return new Intent(Intent.ACTION_VIEW,Uri.parse("fb://profile/<user_id>/fans"));
} catch (Exception e) {
return new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/abc.xyz"));
}
}
You can use Official Facebook App with Intent listed HERE.