Android Open Source - singly-android Singly Client






From Project

Back to project page singly-android.

License

The source code is released under:

MIT License

If you think the Android project singly-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.singly.android.client;
// ww w .  ja  va2s.c o m
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.http.entity.ByteArrayEntity;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.singly.android.util.SinglyUtils;

/**
 * A client that handles authentication and requests to the Singly API.
 * 
 * The SinglyClient requires the following permissions and activities be defined
 * in the AndroidManifest.xml file of the application.
 * 
 * <pre>
 * // permissions needed  
 * <uses-permission android:name="android.permission.INTERNET" />
 * <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 * <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
 * 
 * // activities needed
 * <activity android:name="com.singly.android.client.AuthenticationActivity" />    
 * <activity android:name="com.singly.android.client.FacebookAuthenticationActivity" />
 * </pre>
 * 
 * The internet and network state permissions are used when calling Singly APIs
 * and during authentication.  The internal storage permission is used when 
 * saving shared preferences.
 * 
 * The AuthenticationActivity is used during authentication to various services.
 * The FacebookAuthenticationActivity is used when doing native authentication
 * if the user has the Facebook Android app installed.
 * 
 * @see https://singly.com/docs/api
 */
public class SinglyClient {

  private static SinglyClient instance = null;

  private String clientId;
  private String clientSecret;
  private Class authenticationActivity = AuthenticationActivity.class;

  // authentication information
  public static final String ACCESS_TOKEN = "accessToken";
  public static final String ACCOUNT = "account";

  // device owner information
  public static final String OWNER_NAME = "ownerName";
  public static final String OWNER_PHONE_NUMBER = "ownerPhoneNumber";
  public static final String OWNER_EMAIL_ADDRESS = "ownerEmailAddress";
  
  /**
   * Class that holds Singly authentication including account and access token.
   */
  public static class Authentication {
    public String account;
    public String accessToken;
  }

  private SinglyClient() {
    this.clientId = "your_client_id";
    this.clientSecret = "you_client_secret";
  }

  /**
   * Returns an instance of the SinglyClient singleton.  It creates an instance
   * of the SinglyClient if one did not previously exist.
   */
  public static SinglyClient getInstance() {
    if (instance == null) {
      instance = new SinglyClient();
    }
    return instance;
  }

  /**
   * Returns true if the application has been previously authenticated and 
   * has a Singly access token.
   * 
   * @param context The context from which isAuthenticated is called.
   * 
   * @return True if the app has a Singly access token.  False otherwise.
   */
  public boolean isAuthenticated(Context context) {
    SharedPreferences prefs = context.getSharedPreferences("singly",
      Context.MODE_PRIVATE);
    String accessToken = prefs.getString("accessToken", null);
    return accessToken != null;
  }

  /**
   * Called to authenticate a user through Singly for a specific service.
   * 
   * An application needs to be authenticated with at least one service prior
   * to making api calls.
   * 
   * Authenticate will open a new AuthenticationActivity to authenticate the
   * user with the service. If the user successfully authenticates with the 
   * service then the Singly access token will be placed into the shared 
   * preferences under the key accessToken.  This access token will then be
   * used when making api calls.
   * 
   * Expert: The Activity class that handles the authentication process can be
   * changed by calling the {@link #setAuthenticationActivity(Class)} method. 
   * The assumption is that the new Activity will store the Singly access token 
   * by using {@link SinglyUtils#saveAccessToken(Context, String)} method upon a
   * successful authentication with the service.
   * 
   * @param context The context from which authenticate is called.
   * @param service The service to authenticate the user against.
   * @param params Any optional extra parameters used in oauth of services.
   * This includes scope and flag parameters.
   * @param useNativeAuth Use native authentication where available.  For
   * example when the user has the Android Facebook app installed.
   */
  public void authenticate(Context context, String service,
    Map<String, String> params, boolean useNativeAuth) {

    // convert any extra authentication parameters into a bundle
    Bundle paramsBundle = null;
    if (params != null && !params.isEmpty()) {
      paramsBundle = new Bundle();
      for (Map.Entry<String, String> entry : params.entrySet()) {
        paramsBundle.putString(entry.getKey(), entry.getValue());
      }
    }

    // should we use native authenticaion where available
    if (useNativeAuth) {

      // open facebook authentication if the service is authenticating against
      // is facebook and the facebook app is installed
      if (StringUtils.equals(service, "facebook")) {
        try {

          // no error ensures app is installed
          String facebookApp = "com.facebook.katana";
          context.getPackageManager().getApplicationInfo(facebookApp, 0);

          // launch the activity for native authentication
          Intent facebookIntent = new Intent(context,
            FacebookAuthenticationActivity.class);
          if (paramsBundle != null) {
            facebookIntent.putExtra("params", paramsBundle);
          }
          context.startActivity(facebookIntent);

          // don't fall through
          return;
        }
        catch (PackageManager.NameNotFoundException e) {
          // do nothing, fall back to web
        }
        catch (ActivityNotFoundException anfe) {
          // app hasn't registered the facebook auth activity, fall back to web
        }
      }
    }

    // by default everything else goes through web authentication
    Intent authIntent = new Intent(context, authenticationActivity);
    authIntent.putExtra("service", service);
    if (paramsBundle != null) {
      authIntent.putExtra("params", paramsBundle);
    }
    context.startActivity(authIntent);
  }

  /**
   * Performs a GET request to the Singly API.
   * 
   * All network communication is performed in a separate thread.  As such it 
   * is fine to call this method from the main UI thread.  
   * 
   * The AsyncApiResponseHandler parameter is an asynchronous callback handler
   * that is used to retrieve the result of the network request to the API.  On
   * success the response from the API is returned.  On failure a Throwable 
   * error object will be returned.
   * 
   * If an API call requires an access token it must be added to the queryParams
   * passed into the method.
   * 
   * @param context The current android context.
   * @param apiEndpoint The Singly API endpoint to call.
   * @param queryParams Any query parameters to send along with the request.
   * @param responseHandler An asynchronous callback handler for the request.
   * 
   * @see https://singly.com/docs/api For documentation on Singly api calls.
   * @see SinglyUtils#getAccessToken(Context)
   */
  public void doGetApiRequest(Context context, String apiEndpoint,
    Map<String, String> queryParams,
    final AsyncApiResponseHandler responseHandler) {

    // get the http client and add api url
    AsyncHttpClient client = SinglyUtils.getHttpClient();
    Map<String, String> params = new LinkedHashMap<String, String>();
    if (queryParams != null) {
      params.putAll(queryParams);
    }
    String getApiCallUrl = SinglyUtils.createSinglyURL(apiEndpoint);
    RequestParams rparms = params.isEmpty() ? null : new RequestParams(params);

    // do an async get request
    client.get(getApiCallUrl, rparms, new AsyncHttpResponseHandler() {

      @Override
      public void onSuccess(String response) {
        responseHandler.onSuccess(response);
      }

      @Override
      public void onFailure(Throwable error, String message) {
        responseHandler.onFailure(error, message);
      }
    });
  }

  /**
   * Performs a POST request to the Singly API.
   * 
   * All network communication is performed in a separate thread.  As such it 
   * is fine to call this method from the main UI thread.  
   * 
   * The AsyncApiResponseHandler parameter is an asynchronous callback handler
   * that is used to retrieve the result of the network request to the API.  On
   * success the response from the API is returned.  On failure a Throwable 
   * error object will be returned.
   * 
   * If an API call requires an access token it must be added to the queryParams
   * passed into the method.
   * 
   * The postParams can contain String, InputStream, byte[] and File values.
   * Any request with InputStream, byte[] or File values will be posted as a
   * multipart request.  Post params are sent in the body of the post request.
   * If you wish to send parameters in the url of the request, instead of or
   * along with the post body, they will need to be passed in queryParams.
   * 
   * @param context The current android context.
   * @param apiEndpoint The Singly API endpoint to call.
   * @param queryParams Any parameters to send in the url of the request.
   * @param postParams Any parameters to send in the post body of the request.
   * @param responseHandler An asynchronous callback handler for the request.
   * 
   * @see https://singly.com/docs/api For documentation on Singly api calls.
   * @see SinglyUtils#getAccessToken(Context)
   */
  public void doPostApiRequest(Context context, String apiEndpoint,
    Map<String, String> queryParams, Map<String, Object> postParams,
    final AsyncApiResponseHandler responseHandler) {

    // get the http client and add api url
    AsyncHttpClient client = SinglyUtils.getHttpClient();

    // convert request parameters if needed
    boolean hasPostParams = false;
    RequestParams rparams = new RequestParams();
    if (postParams != null && !postParams.isEmpty()) {
      for (Map.Entry<String, Object> postParam : postParams.entrySet()) {
        String key = postParam.getKey();
        Object objValue = postParam.getValue();
        if (objValue instanceof String) {
          rparams.put(key, (String)objValue);
          hasPostParams = true;
        }
        else if (objValue instanceof InputStream) {
          rparams.put(key, (InputStream)objValue);
          hasPostParams = true;
        }
        else if (objValue instanceof byte[]) {
          rparams.put(key, new ByteArrayInputStream((byte[])objValue));
          hasPostParams = true;
        }
        else if (objValue instanceof File) {
          try {
            rparams.put(key, (File)objValue);
            hasPostParams = true;
          }
          catch (FileNotFoundException e) {
            // do nothing, ignore and continue
          }
        }
      }
    }

    // do an async post request
    boolean hasQueryParams = queryParams != null && !queryParams.isEmpty();
    String postApiCallUrl = SinglyUtils.createSinglyURL(apiEndpoint,
      hasQueryParams ? queryParams : null);
    client.post(postApiCallUrl, hasPostParams ? rparams : null,
      new AsyncHttpResponseHandler() {

        @Override
        public void onSuccess(String response) {
          responseHandler.onSuccess(response);
        }

        @Override
        public void onFailure(Throwable error, String message) {
          responseHandler.onFailure(error, message);
        }
      });
  }

  /**
   * Performs a POST request to the Singly API that allows specifying the body
   * content of the request.  This is used when you need to POST raw content,
   * such as text or images, to the API.
   * 
   * Any query parameters passed are appended to the URL versus being passed
   * in the body of the POST request.
   * 
   * All network communication is performed in a separate thread.  As such it 
   * is fine to call this method from the main UI thread.  
   * 
   * The AsyncApiResponseHandler parameter is an asynchronous callback handler
   * that is used to retrieve the result of the network request to the API.  On
   * success the response from the API is returned.  On failure a Throwable 
   * error object will be returned.
   * 
   * If an API call requires an access token it must be added to the queryParams
   * passed into the method.
   * 
   * @param context The current android context.
   * @param apiEndpoint The Singly API endpoint to call.
   * @param queryParams Any query parameters to send along with the request.
   * @param body The content to use as the body of the request.
   * @param contentType The MIME content type being sent.
   * @param responseHandler An asynchronous callback handler for the request.
   * 
   * @see https://singly.com/docs/api For documentation on Singly api calls.
   * @see SinglyUtils#getAccessToken(Context)
   */
  public void doBodyApiRequest(Context context, String apiEndpoint,
    Map<String, String> queryParams, byte[] body, String contentType,
    final AsyncApiResponseHandler responseHandler) {

    // get the http client and add api url
    AsyncHttpClient client = SinglyUtils.getHttpClient();
    Map<String, String> params = new LinkedHashMap<String, String>();
    if (queryParams != null) {
      params.putAll(queryParams);
    }
    String postApiCallUrl = SinglyUtils.createSinglyURL(apiEndpoint, params);

    // do an async post request with the raw body content
    client.post(context, postApiCallUrl, new ByteArrayEntity(body),
      contentType, new AsyncHttpResponseHandler() {

        @Override
        public void onSuccess(String response) {
          responseHandler.onSuccess(response);
        }

        @Override
        public void onFailure(Throwable error, String message) {
          responseHandler.onFailure(error, message);
        }

      });
  }

  /**
   * Returns the Authentication for the current user.
   * 
   * @param context The current Android context.
   * 
   * @return The Authentication object containing the accound and the Singly
   * access token.
   */
  public Authentication getAuthentication(Context context) {

    SharedPreferences prefs = context.getSharedPreferences("singly",
      Context.MODE_PRIVATE);

    String account = prefs.getString(ACCOUNT, null);
    String accessToken = prefs.getString(ACCESS_TOKEN, null);

    Authentication auth = new Authentication();
    auth.account = account;
    auth.accessToken = accessToken;

    return auth;
  }

  /**
   * Removes the Authentication for the current user.
   * 
   * @param context The current Android context.
   */
  public static void clearAccount(Context context) {

    SharedPreferences prefs = context.getSharedPreferences("singly",
      Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();
    editor.remove(ACCESS_TOKEN);
    editor.remove(ACCOUNT);
    editor.commit();
  }

  public String getClientId() {
    return clientId;
  }

  public void setClientId(String clientId) {
    this.clientId = clientId;
  }

  public String getClientSecret() {
    return clientSecret;
  }

  public void setClientSecret(String clientSecret) {
    this.clientSecret = clientSecret;
  }

  public Class getAuthenticationActivity() {
    return authenticationActivity;
  }

  public void setAuthenticationActivity(Class authenticationActivity) {
    this.authenticationActivity = authenticationActivity;
  }

}




Java Source Code List

com.singly.android.client.AsyncApiResponseHandler.java
com.singly.android.client.AuthenticationActivity.java
com.singly.android.client.AuthenticationWebViewListener.java
com.singly.android.client.BaseAuthenticationWebViewClient.java
com.singly.android.client.FacebookAuthenticationActivity.java
com.singly.android.client.SinglyClient.java
com.singly.android.component.AbstractCachingBlockLoadedListAdapter.java
com.singly.android.component.AuthenticatedServicesActivity.java
com.singly.android.component.AuthenticatedServicesAdapter.java
com.singly.android.component.AuthenticatedServicesFragment.java
com.singly.android.component.DeviceOwnerActivity.java
com.singly.android.component.Friend.java
com.singly.android.component.FriendsListActivity.java
com.singly.android.component.FriendsListAdapter.java
com.singly.android.component.FriendsListFragment.java
com.singly.android.component.FriendsListRowClickListener.java
com.singly.android.component.SinglyService.java
com.singly.android.component.TableOfContentsFragment.java
com.singly.android.component.TableOfContentsTouchListener.java
com.singly.android.examples.MainActivity.java
com.singly.android.util.BitmapUtils.java
com.singly.android.util.ImageCacheListener.java
com.singly.android.util.ImageInfo.java
com.singly.android.util.JSON.java
com.singly.android.util.RemoteImageCache.java
com.singly.android.util.SinglyUtils.java
com.singly.android.util.URLUtils.java