20 September, 2014

Could not establish secure channel for SSL/TLS with authority

There is a WCF service in a test machine and it uses https. It has a self signed certificate for the machine dns.

Every time I called the web service it returned an error
Could not establish trust relationship for SSL/TLS secure channel

The binding and endpoint configuration in the client and the server were OK and i could even make the service call successfully through soapUI (a free tool to test web services).

In the end, since the certificate was self signed, and not on my machine, I had to install the certificate in my machine for the call to work.

Install certificate using Windows:
  1. - open Internet explorer
  2. - open the service site
  3. - click on the red "Certificate error" box right next to the address bar
  4. - choose view certificates
  5. - install certificate
  6. - next, select "Place all certificates in the following store"
  7. - Select Trusted Root Certification Authorities
  8. - accept everything and you're done.

12 September, 2014

Sharing a local photo to Facebook on Android using Facebook SDK

Most of the steps depicted here can be found on Facebook Developers page but sharing a photo while showing the share dialog isn't fully documented.

Download SDK

Download the Facebook SDK and extract it.

Setup Workspace

Add the Facebook SDK project to your workspace and link the library to your project.

Register App on Facebook

Follow these steps to create a Facebook app and get the Application Id.

Android Manifest

Add these elements to your app Manifest file inside the application element and replace the 123456789456789 of the provider with the application id you got from the facebook page.
<activity android:name="com.facebook.LoginActivity" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent.NoTitleBar" />

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>

<provider android:authorities="com.facebook.app.NativeAppCallContentProvider123456789456789" android:name="com.facebook.NativeAppCallContentProvider" android:exported="true" />
The provider was what I was missing from my solution resulting on the photo being published without showing any dialog to the user.
Don't forget to add the facebook_app_id string in your string.xml file.

Initialization

I ended up using Android Simple Facebook library to login the user if necessary since it's really easy to use. 
private Permission[] permissions = new Permission[] { Permission.PUBLISH_ACTION };

public initialization(String appId, String appNamespace, Bundle savedInstanceState) {
 // Facebook SDK initialization
 uiHelper = new UiLifecycleHelper(this, null /*statusCallback*/);
 uiHelper.onCreate(savedInstanceState);

 // Simple Facebook Library initialization
 SimpleFacebookConfiguration configuration = new SimpleFacebookConfiguration.Builder().setAppId(appId).setNamespace(appNamespace).setPermissions(permissions).build();
 SimpleFacebook.setConfiguration(configuration);
}
Use the status callback to get Facebook session status
It is also needed to attach some lifecycle events to these libraries.
@Override
protected void onSaveInstanceState(Bundle outState) {
 super.onSaveInstanceState(outState);
 uiHelper.onSaveInstanceState(outState);
}

@Override
protected void onResume() {
 super.onResume();
 uiHelper.onResume();
 mSimpleFacebook = SimpleFacebook.getInstance(activity);
}

@Override
protected void onPause() {
 super.onPause();
 uiHelper.onPause();
}

@Override
protected void onDestroy() {
 uiHelper.onDestroy();
 super.onDestroy();
}

Login user

Before actually posting the user is requested to be logged in and authorize the app. Since we're using the Facebook SDK it requires the Facebook App to be installed on the device. Since the user will already be logged in the Facebook App this post will not request the user to login again. The first post will, however, request permission for your app to post in the user timeline.
As stated above, I've used Simple Facebook library for login.
public void checkFacebookLogin(final File photo) {
 if (facebook.isLoggedIn()) {
  postPhoto(photo);
 } else {
  facebook.logIn(new OnLoginListener() {

   @Override
   public void onFail(String result) {}

   @Override
   public void onException(Throwable exception) {}

   @Override
   public void onThinking() {}

   @Override
   public void onNotAcceptingPermissions(Type type) {}

   @Override
   public void onLogin() {
    postPhoto(photo);
   }
  });
 }
}
On production code you should actually handle the other events.

Post Photo

Actually post the photo.
public void postPhoto(File photo) {
 if (FacebookDialog.canPresentShareDialog(this, FacebookDialog.ShareDialogFeature.PHOTOS)) {
  FacebookDialog shareDialog = new FacebookDialog.PhotoShareDialogBuilder(this).addPhotoFiles(Arrays.asList(photos)).build();
  uiHelper.trackPendingDialogCall(shareDialog.present());
 }
}
Since the WebDialog provided by the Facebook SDK doesn't post photos it looks like we're stuck with this method.