I am working on an android app in which I am sharing content on facebook. I am able to share link, image. But i am unable to send when i only post text on facebook. I did not get any thing. I am using following code for share on facebook.
Bundle bundle = new Bundle();
bundle.putString("name", webPageContent);
bundle.putString("message", webPageContent);
FeedDialogBuilder feedDialog = new WebDialog.FeedDialogBuilder(FacebookShareActivity.this,Session.getActiveSession(),bundle)
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values,
FacebookException error) {
// TODO Auto-generated method stub
if (error == null) {
// When the story is posted, echo the success
// and the post Id.
final String postId = values.getString("post_id");
if (postId != null)
{
Toast.makeText(FacebookShareActivity.this, "Posted story, id: "+postId, Toast.LENGTH_SHORT).show();
}
}
}
});
feedDialog.build().show();
Please see the docs for the feed dialog: https://developers.facebook.com/docs/sharing/reference/feed-dialog/v2.2
As you can see, there's no message property. This is because prefilling the status update for the user is against platform policies.
Related
I'm trying to implement automating player sign in to Google Play games in my Android app. Firstly, as mentioned here, I try to sign in silently:
#Override
protected void onResume() {
super.onResume();
signInSilently();
}
private void signInSilently() {
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this, task -> {
if (task.isSuccessful())
//everything ok
else {
final ApiException exception = (ApiException) task.getException();
if (BuildConfig.DEBUG)
Log.d(TAG, "Silent Sign In failure: ", exception);
if (exception.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED)
startSignInIntent();
}
});
Every time I got an exception with code 4 (CommonStatusCodes.SIGN_IN_REQUIRED). So in this case I try to sign in with ui:
private void startSignInIntent() {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
}
#Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
if (request == RC_SIGN_IN) {
final GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// everything is ok, get account from result
} else if (result.getStatus().hasResolution()) {
resolveManually(result.getStatus());
} else {
String message = result.getStatus().getStatusMessage();
if (BuildConfig.DEBUG)
Log.d(TAG, "status code" + result.getStatus().getStatusCode());
if (message == null || message.isEmpty()) {
message = "other error";
}
new AlertDialog.Builder(this).setMessage(message)
.setNeutralButton(android.R.string.ok, null).show();
}
}
}
And here everytime I get message with other error! The status code is again 4 (CommonStatusCodes.SIGN_IN_REQUIRED). How can I get this code when I try to sign in using intent? So, my app are in infinite loop because onResume is called everytime my activity loads after receiving a result, and everytime the status code is CommonStatusCodes.SIGN_IN_REQUIRED. So, where is the problem?
In Google samples there is no information how can I handle automatic sign in, only manual with sign in buttons. But google recommends to use automating sign in. Please help anybody to understand what is wrong here.
You must not start the login screen from your onResume method. It is a silent login which works if the user wants it (by tapping a button). That's why the examples show it only this way.
There was wrong OAuth 2.0 client ID for the debug version of my app! Don't know why there is SIGN_IN_REQUIRED status code in this situation, it is really confusing!
I am using Parse, where are users are able to login using Facebook, Twitter, and Google+. As of now, only Facebook and Twitter is fully functional.
I have managed to login using Facebook and Twitter in the following way:
private void onLoginButtonClicked() {
LoginActivity.this.progressDialog = ProgressDialog.show(
LoginActivity.this, "", "Logging in...", true);
List<String> permissions = Arrays.asList("public_profile", "user_about_me",
"user_relationships", "user_birthday", "user_location");
ParseFacebookUtils.logIn(permissions, this, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
LoginActivity.this.progressDialog.dismiss();
if (user == null) {
Log.d(IntegratingFacebookTutorialApplication.TAG,
"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
Log.d(IntegratingFacebookTutorialApplication.TAG,
"User signed up and logged in through Facebook!");
showUserDetailsActivity();
} else {
Log.d(IntegratingFacebookTutorialApplication.TAG,
"User logged in through Facebook!");
moodpage();
}
}
});
}
private void onTwitterButtonClicked() {
ParseTwitterUtils.logIn(this, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
if (user == null) {
Log.d("MyApp", "Uh oh. The user cancelled the Twitter login.");
} else if (user.isNew()) {
Log.d("MyApp", "User signed up and logged in through Twitter!");
showUserDetailsActivity();
} else {
Log.d("MyApp", "User logged in through Twitter!");
moodpage(); }
}
});
}
I am trying to figure out to achieve this with Google+ through parse. Someone has suggested for me to look into Parse Rest API, however, I am not familiar with it, and need more guidance.
Any clarification will be appreciated.
as per this:
http://blog.parse.com/announcements/adding-third-party-authentication-to-your-web-app/
and this:
https://parse.com/tutorials/adding-third-party-authentication-to-your-web-app
And my understanding of them
You just need to generate a password using some algorithm in your app or your cloud/backend, after successfully logging in with Google+ / Github / Whatever
a simeple implementation (but it's not secured to have it in your app):
// given Google Plus login (Using their Api) i.e. no Parse yet at this point
int id = 12345; // assume that this is google+ id (After successfully logging in)
ParseUser user = new ParseUser();
user.setUsername("google-plus-" + String.valueOf(id));
user.setPassword(hashMyPassword(id)); // Create password based on the id
user.setEmail("email.from.google.plus.login#gmail.com");
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
// Hooray! Let them use the app now.
} else {
// Sign up didn't succeed. Look at the ParseException
// to figure out what went wrong
}
}
});
One important thing about this solution:
It's not secured to just use the id / password based on the id in your app, a better solution would be to send Google+ Token / UserId to backend/cloud then the Backend/Cloud verifies that this Token/Id are valid, then create the username/password out of it and exchange it with Parse User.
I hope you got the Idea.
I did a mistake that apparently can be solved only by uninstalling and then installing my app again.
I delivered a message to the users, but no-one seems to uninstall it.
AFAIK, if I change the certificate file, the play store won't let me upload the application, and
obviously I don't want to upload a new app.
Is there a way to force uninstall in order to update?
Thanks!
There's no killswitch to remotely force uninstalls (that'd be a security nightmare). What you can do is publish a fixed version on Google Play, and wait for users to upgrade.
I don't know if this can help you but i had the same problem. The solution for me is that i check the app version every time the user opens it and compare it with a version code stored on apache server (in a checkversion.php file).
If versions doesn't match, i show a not cancelable dialog that ask the user to go to market and download the update.
Here is an example (keep in mind that i use Volley library to handle connections):
public class UpdateManager {
private Activity ac;
private HashMap<String,String> params;
public UpdateManager(Activity ac) {
this.ac = ac;
}
public void checkForUpdates() {
Log.d("UpdateManager","checkForUpdates() - Started...");
params = new HashMap<String,String>();
params.put("request","checkforupdates");
try {
params.put("versioncode", String.valueOf(ac.getPackageManager().getPackageInfo(ac.getPackageName(), 0).versionCode));
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (Helper.isInternetAvailable(ac)) { //this is a class i made to check internet connection availability
checkAppVersion();
} else { Log.d("UpdateManager","CheckForUpdates(): Impossible to update version due to lack of connection"); }
}
private void checkAppVersion() {
Log.d("UpdateManager","checkAppVersion() - Request started...");
JsonObjectRequest req = new JsonObjectRequest("http://yourserver/checkappversion.php", new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (response != null && response.has("result")) {
try {
Log.d("UpdateManager","checkAppVersion() - Request finished - Response: "+response.getString("result"));
if (response.getString("result").matches("updaterequested")) { //Update requested. Show the relative dialog
Log.d("UpdateManager","Update requested");
askUserForUpdate();
}
else if (response.getString("result").matches("current")) { //Same version. Do nothing
Log.d("UpdateManager","Version is up to date");
}
else if (response.getString("result").matches("error")) { //You can return an error message if error occurred on server
Log.d("UpdateManager","checkappversion Error - "+response.getString("error"));
}
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("UpdateManager","Volley Error - "+error.getMessage());
}
});
req.setRetryPolicy(new DefaultRetryPolicy(60000,0,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
ConnectionController.getInstance().addToRequestQueue(req);
}
public void askUserForUpdate() {
final Dialog diag = new Dialog(ac);
diag.requestWindowFeature(Window.FEATURE_NO_TITLE);
diag.setContentView(R.layout.updatemanager_requestupdate_dialog);
diag.setCancelable(false);
diag.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
TextView t = (TextView)diag.findViewById(R.id.requestupdate_dialog_main_text);
ImageView im_ok = (ImageView)diag.findViewById(R.id.requestupdate_dialog_ok);
ImageView im_canc = (ImageView)diag.findViewById(R.id.requestupdate_dialog_canc);
t.setText(ac.getResources().getString(R.string.update_manager_askuserforupdate));
im_canc.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
diag.dismiss();
ac.finish();
}
});
im_ok.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id="+ac.getPackageName()));
diag.dismiss();
ac.startActivity(intent);
ac.finish();
}
});
diag.show();
}
}
You can then use it when your main activity (or maybe login activity) starts like this:
UpdateManager updateManager = new UpdateManager(MainActivity.this); //i assume MainActicity as the calling activity
updateManager.checkForUpdates();
Obviously this has to be implemented into the application code so, the first time, you have to rely only on the user to manually upgrade it. But this can help if you have the same problem in the future.
This is an extract from my personal code so you have to rearrange it to your needings. Hope this helps someone.
Users should be able to go to Settings > Applications > Manage Applications and select the application to be removed. I've never seen a case where the application can't be removed this way, except in the case of built-in applications which require a rooted device to remove.
I want to post a predefind message with link on facebook wall without user intervention .I mean user just log into facebook and my predefind message should be post with link on user's facebook wall.
Below is my code.
public class PostOnFacebookWall {
public static void postOnWall(Facebook facebook , final Context context, final String placeName) {
Bundle params = new Bundle();
params.putString("message", placeName);
facebook.dialog(context, "feed", params ,new DialogListener() {
public void onFacebookError(FacebookError e) {
}
public void onError(DialogError e) {
}
public void onComplete(Bundle values) {
Toast.makeText(context, placeName+" for today's hangout has been posted on your facebook wall. ", Toast.LENGTH_LONG).show();
}
public void onCancel() {
}
});
}
}
I've looked so many links about my question like below
http://stackoverflow.com/questions/11316683/adding-content-to-facebook-feed-dialog-with-new-facebook-sdk-for-android
which passed all the parameter like "link","description","image" and much more.
Someone is saying that u have to pass all the parameters.I just want to predefind messages and link over that.
My message is should be "Let's hangout at " and here placeName should be a link.
And this complete msg i want to pass from my code .I don't want that my code opens dialog where user enters it's message.
If you need to post a predefined message to a User's Facebook Wall, you shouldn't be using the facebook.dialog method.
For more on why that shouldn't be used, read my answer posted here: https://stackoverflow.com/a/13507030/450534
That being said, to get the result you want, try this piece of code:
Bundle postStatusMessage = new Bundle();
// ADD THE STATUS MESSAGE TO THE BUNDLE
postStatusMessage.putString("message", "Let's hangout at " + placeName);
postStatusMessage.putString("link", "www.the_example_web_address.com");
Utility.mAsyncRunner.request("me/feed", postStatusMessage, "POST", new StatusUpdateListener(), null);
And this is where you can check the response from the Facebook API by parsing the String response:
private class StatusUpdateListener extends BaseRequestListener {
#Override
public void onComplete(String response, Object state) {
}
A point to note here is, you cannot pass a message with a link in it. To elaborate (as the earlier statement might sound confusing), You cannot pass a link in the message tag with a link that will be parsed by Facebook and show up in a post like links on FB do.
To see the difference clearly, post the status update using the code above and see how it looks on Facebook. Then, after having done that, remove this postStatusMessage.putString("link", "www.the_example_web_address.com"); from the code above and include the link in the message tag, post it and see how it looks on Facebook.
I'm aware to this thread, with same question as my.
but as it says in one of the comments there- API was changed to this one and the "message" attribute is now ignored. is there a way to set the text box content with the new API?
here's my code:
protected void post() {
Bundle params = new Bundle();
params.putString("message", "my message here");
facebook.dialog(this, "feed", params, new DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
}
#Override
public void onError(DialogError e) {
}
#Override
public void onComplete(Bundle values) {
}
#Override
public void onCancel() {
}
});
}
Thx.
I have been looking about this as well and I think I have found the solution. Sadly enough the documentation for this was for iOs and can be found here;
Bundle params = new Bundle();
params.putString("link", "your app url here");
params.putString("picture", "your img url here");
params.putString("name", "your post title");
params.putString("caption", "your subtitle");
params.putString("description", "your message");
facebook.dialog(Your Context, "feed", params, Your DialogListener);
Don't try to use just one parameter, you have to use them all to make it work.
I hope this helps you out.
EDIT
The message tag is ignored as of 12 July 2011 I would advice you to use the "description" tag for what ever message you would like to share.
This is the quote from Facebook about the "message" parameter:
"On July 12, we are ignoring the message parameter in Feed Dialogs. This eliminates the ability to pre-fill stream stories (prohibited by Policy IV.2). This change encourages users to share authentic and relevant content with their friends."
source