I have integrated sdk in my application but when i am going to sharedialog and press back button sdk gives "success" even not post click.
For more details SDK v 3.5 and it's code which given success while i am trying to test using real Facebook account and pressing cancel.but while using test account and when i check with this "getNativeDialogCompletionGesture" method it's working but not in real account.
My requirement is while pressing cancel it should not show success on backpressed.
public static boolean handleActivityResult(Context context, PendingCall appCall, int requestCode, Intent data,
Callback callback) {
if (requestCode != appCall.getRequestCode()) {
return false;
}
if (attachmentStore != null) {
attachmentStore.cleanupAttachmentsForCall(context, appCall.getCallId());
}
if (callback != null) {
if (NativeProtocol.isErrorResult(data)) {
Exception error = NativeProtocol.getErrorFromResult(data);
callback.onError(appCall, error, data.getExtras());
} else {
callback.onComplete(appCall, data.getExtras());
}
}
return true;
}
Related
I have created a custom document provider for Android using this code as a base.
https://learn.microsoft.com/en-us/samples/xamarin/monodroid-samples/storageprovider/
This allows for a new drive to be mapped onto the documents folder when browsing/saving documents.
If there is an exception due to a password timeout for example, I would like to pop back up the existing app so the users can entered their credentials again to log in.
Is this possible? As an example of what I am looking for, if the QueryRoots failed with a particular exception, could I run something to pop back up the app interface here?
public override ICursor QueryRoots(string[] projection)
{
Log.Verbose(TAG, "queryRoots");
var result = new MatrixCursor(ResolveRootProjection(projection));
try
{
if (!IsUserLoggedIn())
{
return result;
}
MatrixCursor.RowBuilder row = result.NewRow();
... other init code here
}
catch (Exception ex)
{
if (ex.Message == "NoSessionException")
{
// LOGIC TO BRING BACK APP TO LOG IN AGAIN HERE...
}
}
return result;
}
I make a sample code about how to lauch the app again for your reference. You could put Launch method in catch statement.
In Xamarin.Forms, you could use Dependency service to start the app with package name.
Create a interface:
public interface IDpendencyService
{
Task<bool> Launch(string stringUri);
}
Implemention of Android:
public class DependencyImplementation : Activity, IDpendencyService
{
public Task<bool> Launch(string stringUri)
{
Intent intent = Android.App.Application.Context.PackageManager.GetLaunchIntentForPackage(stringUri);
if (intent != null)
{
intent.AddFlags(ActivityFlags.NewTask);
Forms.Context.StartActivity(intent);
return Task.FromResult(true);
}
else
{
return Task.FromResult(true);
}
}
}
Register in MainActivity:
DependencyService.Register<IDpendencyService, DependencyImplementation>();
I use a Button event to invoke. You could try to invoke in catch.
DependencyService.Get<IDpendencyService>().Launch("com.companyname.xamarindemo");
Screenshot: I have a button on Page21. When i click the button, it would reload the app and pop back up the existing app.
When the leader board is shown in the screen there is a option called "setting". Inside that there is a option "Signout". When I clicked signout the leaderboard is closed,
Issue.
If I checked the sign in status the the below function always returns true. Means that the mGoogleApiClient is connected. and hence when I tried to click the icon which shows the leaderboard it always has the responseCode RESULT_RECONNECT_REQUIRED.
This issue goes away if i restart my App
public boolean isSignedIn() {
return mGoogleApiClient != null && mGoogleApiClient.isConnected();
}
Question.
How do the program knows that the user has signed-out in the leaderboard screen.
You have to catch the signout in onActivityResult and call GoogleApiClient.disconnect() yourself since the connection is in an inconsistent state (source).
So, when you open the leaderboard using the following code:
activity.startActivityForResult(Games.Leaderboards.getLeaderboardIntent(googleApiClient, leaderboardId), MY_CUSTOM_LEADERBOARD_RESULT_CODE);
You should handle the signout event as follows:
public void onActivityResult(int requestCode, int responseCode, Intent intent) {
boolean userLoggedOut = (responseCode == GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED) && (requestCode == MY_CUSTOM_LEADERBOARD_RESULT_CODE);
if (userLoggedOut) {
googleApiClient.disconnect();
}
}
You should handle the RESULT_RECONNECT_REQUIRED by calling reconnect().
If there was a transient error with the connection, this will silently reconnect the player. If they did actually signout, onConnectionFailed() will be called, and you can reset the UI/game to be appropriate for the not logged in state.
if (resultCode == GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED) {
mGoogleApiClient.reconnect();
}
I'm trying to implement Facebook sharing in my game using Unity 3D + Facebook Unity SDK. But when I tried testing to post to my wall, this error shows up: "We are Sorry, this post is no longer available. It may have been removed." Can anybody help me? Thanks in advance.
BTW, here's my code:
using UnityEngine;
using System.Collections;
public class FacebookController : MonoBehaviour {
public bool isUsingFacebook = true; //Are we using Facebook SDK? This variable is only
//Feed parameters.
private string link = "market://details?id=com.LaserCookie.Queue"; //The link that will show the user the game's google play store address
private string linkName = "Queue"; //The link name
private string linkCaption = "Wow this game is great! 10/10 must play!"; // The caption of the link
private string linkDescription = "I achieved the score of " + PlayerController.instance.score.ToString() + "! Try to beat me if you can!"; //The description of the link
private string picture = "http://www.drycreekequestriancenter.com/testImage.jpeg"; //This is the image / game icon for the link. For now, it's shamelessly got from a random source. Thank you, random citizen...
void Awake()
{
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
//Init FB
private void Init()
{
if (!FB.IsInitialized)
{
FB.Init(OnInitComplete, OnHideUnity);
}
}
//Callback that will be called when the initialization is completed
private void OnInitComplete()
{
Debug.Log("FB.Init completed: Is user logged in? " + FB.IsLoggedIn);
//Check if we are logged in.
//If not, we will log in.
//If we are, post status.
if (!FB.IsLoggedIn)
{
LoginWithPublish();
}
else
{
PostImpl();
}
}
//Callback that will be called when the game is shown / not
private void OnHideUnity(bool isGameShown)
{
Debug.Log("Is game showing? " + isGameShown);
}
//Post to Facebook. This is the only exposed method because we only use this to post to Facebook.
//The initialization and login will be called when needed.
//It will first detect whether or not we have been initialized. And will init if we haven't.
//Then it will check whether or not we have been logged in with publish. And will log in if not.
public void PostToFacebook()
{
//Are we using facebook SDK?
if (isUsingFacebook)
{
if (!FB.IsInitialized) //Check for initialization
{
Init();
}
else if (!FB.IsLoggedIn) //Check for login
{
LoginWithPublish();
}
else //Post if we are already initia;ized and logged in
{
PostImpl();
}
}
}
//The true implementation of the posting
private void PostImpl()
{
FB.Feed("",link, linkName,linkCaption,linkDescription,picture);
}
//Login to Facebook with publish
private void LoginWithPublish()
{
// It is generally good behavior to split asking for read and publish
// permissions rather than ask for them all at once.
//
// In your own game, consider postponing this call until the moment
// you actually need it.
FB.Login("publish_actions", LoginCallback);
}
//Login callback
void LoginCallback(FBResult result)
{
if (result.Error != null)
{
Debug.Log( "Error Response:\n" + result.Error );
//TODO: Retry login if we have error? Or do we display a pop up?
}
else if (!FB.IsLoggedIn)
{
Debug.Log( "Login cancelled by Player" );
//TODO: Do we display a pop up?
}
else
{
Debug.Log( "Login was successful!" );
PostImpl();
}
}
}
You need to add Key Hash for FB application.
Go to My Apps, select you application, open Setting tab, add platform for android, and add you key hash.
check this link out
Setting a Release Key Hash
I've fixed the issue. It turns out it's because I used my still in development google store address as the link. I thought it would be automatically recognized regardless of my app is live or not. Thank you anyway. :)
I am basing my app off the foursquare-oAuth-sample app posted at Foursquare oAuth sample
Have made changes to MyActivity pretty much similar to the sample code but still getting this, can someone point out what I need to change, the code is as below
public class MyActivity extends FragmentActivity {
private static final int REQUEST_CODE_FSQ_CONNECT = 200;
private static final int REQUEST_CODE_FSQ_TOKEN_EXCHANGE = 201;
/**
* Obtain your client id and secret from:
* https://foursquare.com/developers/apps
*/
private static final String CLIENT_ID = "";
private static final String CLIENT_SECRET = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
ensureUi();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Update the UI. If we already fetched a token, we'll just show a success
* message.
*/
private void ensureUi() {
boolean isAuthorized = !TextUtils.isEmpty(ExampleTokenStore.get().getToken());
TextView tvMessage = (TextView) findViewById(R.id.tvMessage);
tvMessage.setVisibility(isAuthorized ? View.VISIBLE : View.GONE);
Button btnLogin = (Button) findViewById(R.id.btnLogin);
btnLogin.setVisibility(isAuthorized ? View.GONE : View.VISIBLE);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Start the native auth flow.
Intent intent = FoursquareOAuth.getConnectIntent(MyActivity.this, CLIENT_ID);
// If the device does not have the Foursquare app installed, we'd
// get an intent back that would open the Play Store for download.
// Otherwise we start the auth flow.
if (FoursquareOAuth.isPlayStoreIntent(intent)) {
toastMessage(MyActivity.this, getString(R.string.app_not_installed_message));
startActivity(intent);
} else {
startActivityForResult(intent, REQUEST_CODE_FSQ_CONNECT);
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_FSQ_CONNECT:
onCompleteConnect(resultCode, data);
break;
case REQUEST_CODE_FSQ_TOKEN_EXCHANGE:
onCompleteTokenExchange(resultCode, data);
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
private void onCompleteConnect(int resultCode, Intent data) {
AuthCodeResponse codeResponse = FoursquareOAuth.getAuthCodeFromResult(resultCode, data);
Exception exception = codeResponse.getException();
if (exception == null) {
// Success.
String code = codeResponse.getCode();
performTokenExchange(code);
} else {
if (exception instanceof FoursquareCancelException) {
// Cancel.
toastMessage(this, "Canceled");
} else if (exception instanceof FoursquareDenyException) {
// Deny.
toastMessage(this, "Denied");
} else if (exception instanceof FoursquareOAuthException) {
// OAuth error.
String errorMessage = exception.getMessage();
String errorCode = ((FoursquareOAuthException) exception).getErrorCode();
toastMessage(this, errorMessage + " [" + errorCode + "]");
} else if (exception instanceof FoursquareUnsupportedVersionException) {
// Unsupported Fourquare app version on the device.
toastError(this, exception);
} else if (exception instanceof FoursquareInvalidRequestException) {
// Invalid request.
toastError(this, exception);
} else {
// Error.
toastError(this, exception);
}
}
}
private void onCompleteTokenExchange(int resultCode, Intent data) {
AccessTokenResponse tokenResponse = FoursquareOAuth.getTokenFromResult(resultCode, data);
Exception exception = tokenResponse.getException();
if (exception == null) {
String accessToken = tokenResponse.getAccessToken();
// Success.
toastMessage(this, "Access token: " + accessToken);
// Persist the token for later use. In this example, we save
// it to shared prefs.
ExampleTokenStore.get().setToken(accessToken);
// Refresh UI.
ensureUi();
} else {
if (exception instanceof FoursquareOAuthException) {
// OAuth error.
String errorMessage = ((FoursquareOAuthException) exception).getMessage();
String errorCode = ((FoursquareOAuthException) exception).getErrorCode();
toastMessage(this, errorMessage + " [" + errorCode + "]");
} else {
// Other exception type.
toastError(this, exception);
}
}
}
/**
* Exchange a code for an OAuth Token. Note that we do not recommend you
* do this in your app, rather do the exchange on your server. Added here
* for demo purposes.
*
* #param code
* The auth code returned from the native auth flow.
*/
private void performTokenExchange(String code) {
Intent intent = FoursquareOAuth.getTokenExchangeIntent(this, CLIENT_ID, CLIENT_SECRET, code);
startActivityForResult(intent, REQUEST_CODE_FSQ_TOKEN_EXCHANGE);
}
public static void toastMessage(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
public static void toastError(Context context, Throwable t) {
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}
Error Log
Here is the exception i am getting, can someone please point out why is it not able to find the activity to handle intent? Thank you
08-13 23:15:23.137 2754-2754/com.example.panaceatechnologysolutions.farhansfoursquareapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.panaceatechnologysolutions.farhansfoursquareapp, PID: 2754
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=market://details?id=com.example.panaceatechnologysolutions.farhansfoursquareapp&referrer=utm_source=foursquare-android-oauth&utm_term=CLIENT_ID }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1691)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1482)
at android.app.Activity.startActivityForResult(Activity.java:3711)
at android.app.Activity.startActivityForResult(Activity.java:3669)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:840)
at android.app.Activity.startActivity(Activity.java:3914)
at android.app.Activity.startActivity(Activity.java:3882)
at com.example.panaceatechnologysolutions.farhansfoursquareapp.MyActivity$1.onClick(MyActivity.java:90)
at android.view.View.performClick(View.java:4598)
at android.view.View$PerformClick.run(View.java:19268)
at android.os.Handler.handleCallback(Handler.java:738)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5070)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
08-13 23:15:30.157 2754-2765/com.example.panaceatechnologysolutions.farhansfoursquareapp I/art﹕ Heap transition to ProcessStateJankImperceptible took 7.253732ms saved at least 72KB
Ok so based on Rohans reply I checked, since I was doing this on the Emulator, this snippet from the Foursquare oAuth library I have in my project cannot create the intent based on the context and client Id. I am not sure why it returns null and as a result redirects me to the Google play store to install foursquare on my emulator. I have registered my app with foursquare and am using the registered client Id and the rest of the parameters used by this function are the ones in Foursquare oAuth Java class. If someone has worked with this library or can point out why it can't find the intent please let me know as I have been stuck on this for a couple of days.
This is the line of code like Rohan pointed out calling the Foursquare oAuth Java class in MyActivity class
Intent intent = FoursquareOAuth.getConnectIntent(MyActivity.this, CLIENT_ID);
And this is the getConnectIntent method in the Foursquare oAuth Java Class
public static Intent getConnectIntent(Context context, String clientId) {
Uri.Builder builder = new Uri.Builder();
builder.scheme(URI_SCHEME);
builder.authority(URI_AUTHORITY);
builder.appendQueryParameter(PARAM_CLIENT_ID, clientId);
builder.appendQueryParameter(PARAM_VERSION, String.valueOf(LIB_VERSION));
builder.appendQueryParameter(PARAM_SIGNATURE, getSignatureFingerprint(context));
Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
if (isIntentAvailable(context, intent)) {
return intent;
}
return getPlayStoreIntent(clientId);
}
it redirects you to play store becuase "isIntentAvailable is false" and it calls "getPlayStoreIntent" which redirects you to play store.
inside isIntentAvailable method
private static boolean isIntentAvailable(Context context, Intent intent) {
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(
intent, PackageManager.MATCH_DEFAULT_ONLY);
return resolveInfo.size() > 0;
}
this method return true if a suitable package is found.
also check your client id is not null and is correct
Yes Rohan...you are right it is false because the intent wasnt returning anything from isIntentAvailable, but the real reason why that was not returning an intent back was because since I am using the emulator, the package manager is apparently looking for a foursquare.apk package installed which it didnt find. I didnt Foursquare anywhere indicate that their apk has to be installed which is not included as part of the oAuth Library which they provide in the link above on the sample project. I guess they assume you are using an Android device for testing and not the emulator. These are the steps to use oAuth from Foursquare on Android emulator from Android studio or Eclipse im guessing as well.
1) Download the Foursquare APK http://www.apk4fun.com/apk/6395/
2) As a pre-requisite open Android SDK Manager in Android studio and make sure Google API's are downloaded and installed, these are needed by Foursquare
3) copy the foursquare.apk file in the /Applications/sdk/platform-tools folder
4) install the apk using the adb tool in the folder like shown in this link How to install an apk on the emulator in Android Studio?
5) and now your app can use the emulator to contact foursquare and you will not be redirected to install the app on the emulator!
-Note, I noticed I had to reinstall the "foursquare.apk" when i closed down Android studio and the emulator the next day. But was easy since i knew what to do, Hopefully this saves someone else the frustration as it took me a couple of days to figure this out :)
I'm trying to call FB autorize dialog with this code:
//return true if is autologged
//return false if facebook login dialog is called
public boolean LoginAsync(Activity act)
{
m_strLastError="";
boolean bTryLogin= true;
if ((m_fbkey != null) && (m_fbkey.length() > 0))
{
facebook.setAccessToken(m_fbkey);
bTryLogin = !facebook.isSessionValid();
}
if (bTryLogin)
{
facebook.authorize(act, new String[] { "email", "offline_access", "publish_stream", "read_stream"}, new LoginDialogListener());
return false;
}
//"succesfull 'autologin'
return true;
}
It worked fine in test app when click button, but stopped working when moved it to OnCreate.
Dialog doesn't appear anymore. Only empty screen.
Is it possible to fajl because of use in OnCreate?
If you call login and have a valid token then you will skip the login form and go straight to the onComplete callback.
http://facebook.stackoverflow.com/questions/9130133/authorize-method-called-twice-for-facebook-on-android
Thanks to mcnicholls.