Java tutorial
/** * The MIT License (MIT) * * Copyright (c) 2015 Coloreight LLC * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.coloreight.plugin.socialAuth; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerFuture; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import com.facebook.AccessToken; import com.facebook.CallbackManager; import com.facebook.FacebookAuthorizationException; import com.facebook.FacebookCallback; import com.facebook.FacebookException; import com.facebook.FacebookSdk; import com.facebook.login.LoginManager; import com.facebook.login.LoginResult; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; public class SocialAuth extends CordovaPlugin { private AccountManager accountManager; private String requestedTwitterAccountName; private CallbackManager fbCallbackManager; private CallbackContext callbackContext; public static final String TAG = "SocialAuth"; public static final int TWITTER_OAUTH_REQUEST = 1; @Override protected void pluginInitialize() { super.pluginInitialize(); FacebookSdk.sdkInitialize(this.cordova.getActivity().getApplicationContext()); fbCallbackManager = CallbackManager.Factory.create(); LoginManager.getInstance().registerCallback(fbCallbackManager, new FacebookCallback<LoginResult>() { @Override public void onSuccess(LoginResult loginResult) { try { JSONObject json = new JSONObject(); json.put("userId", loginResult.getAccessToken().getUserId()); json.put("accessToken", loginResult.getAccessToken().getToken()); json.put("hasWritePermissions", loginResult.getAccessToken().getPermissions().contains("publish_actions")); PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, json); Log.v(TAG, "Facebook SDK auth success -> sended data: " + json.toString()); callbackContext.sendPluginResult(pluginResult); } catch (JSONException e) { PluginResult pluginResult = new PluginResult(PluginResult.Status.ERROR, e.getLocalizedMessage()); callbackContext.sendPluginResult(pluginResult); } } @Override public void onCancel() { Log.v(TAG, "Facebook auth canceled"); callbackContext.error("Facebook auth cancelled"); } @Override public void onError(FacebookException exception) { if (exception instanceof FacebookAuthorizationException) { if (AccessToken.getCurrentAccessToken() != null) { LoginManager.getInstance().logOut(); } } Log.v(TAG, "Facebook auth error -> message:" + exception.getLocalizedMessage()); callbackContext.error("Facebook auth error -> message:" + exception.getLocalizedMessage()); } }); } @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { this.callbackContext = callbackContext; accountManager = AccountManager.get(this.cordova.getActivity().getApplicationContext()); if (action.equals("canUseTwitterSystemAccount")) { this.canUseTwitterSystemAccount(callbackContext); } else if (action.equals("getTwitterSystemAccounts")) { this.getTwitterSystemAccounts(callbackContext); } else if (action.equals("getTwitterSystemAccount")) { this.getTwitterSystemAccount(args.getString(0), callbackContext); } else if (action.equals("setFacebookApp")) { this.setFacebookApp(args.getJSONObject(0), callbackContext); } else if (action.equals("getFacebookAccount")) { this.getFacebookAccount(args.getJSONObject(0), args.getString(1), callbackContext); } else { Log.d(TAG, "invalid/na social auth method: " + action); callbackContext.error("invalid/na social auth method: " + action); return false; } return true; } public void setFacebookApp(final JSONObject app, final CallbackContext callbackContext) { try { String displayName = app.getString("name"); String appId = app.getString("id"); FacebookSdk.setApplicationName(displayName); FacebookSdk.setApplicationId(appId); callbackContext.success(); } catch (Exception e) { // do nothing } } public void getFacebookAccount(final JSONObject permissions, final String permissionsType, final CallbackContext callbackContext) { final SocialAuth me = this; cordova.getThreadPool().execute(new Runnable() { public void run() { try { ArrayList<String> fbPermissions = new ArrayList<String>(); JSONArray jsonArray = (JSONArray) permissions.get("permissions"); if (jsonArray != null) { int len = jsonArray.length(); for (int i = 0; i < len; i++) { fbPermissions.add(jsonArray.get(i).toString()); } } LoginManager loginManager = LoginManager.getInstance(); cordova.setActivityResultCallback(me); if (permissionsType.equals("write")) { loginManager.logInWithPublishPermissions(cordova.getActivity(), fbPermissions); } else { loginManager.logInWithReadPermissions(cordova.getActivity(), fbPermissions); } } catch (Exception e) { callbackContext.error(e.getMessage()); } } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); fbCallbackManager.onActivityResult(requestCode, resultCode, intent); if (requestCode == SocialAuth.TWITTER_OAUTH_REQUEST) { if (resultCode == Activity.RESULT_OK) { Log.v(TAG, "On activity result with authtoken: " + intent.getExtras().keySet()); for (String key : intent.getExtras().keySet()) { Object value = intent.getExtras().get(key); try { String valueStr = value.toString(); Log.v("AUTH", String.format("%s %s (%s)", key, valueStr, value.getClass().getName())); } catch (NullPointerException e) { Log.v(TAG, e.getMessage()); } } this.getTwitterSystemAccount(this.requestedTwitterAccountName, callbackContext); } else if (resultCode == Activity.RESULT_CANCELED) { callbackContext.error("Twitter auth activity canceled"); } } } public void canUseTwitterSystemAccount(final CallbackContext callbackContext) { cordova.getThreadPool().execute(new Runnable() { public void run() { PluginResult pluginResult; Account[] twitterAccounts = accountManager.getAccountsByType("com.twitter.android.auth.login"); // Twitter doesn't allow to get user's tokens from native account which signed by custom app // therefore the method returns false //pluginResult = new PluginResult(PluginResult.Status.OK, (twitterAccounts.length > 0)); pluginResult = new PluginResult(PluginResult.Status.OK, false); pluginResult.setKeepCallback(true); callbackContext.sendPluginResult(pluginResult); } }); } public void getTwitterSystemAccounts(final CallbackContext callbackContext) { cordova.getThreadPool().execute(new Runnable() { public void run() { PluginResult pluginResult; JSONObject json = new JSONObject(); JSONArray accounts = new JSONArray(); Account[] twitterAccounts = accountManager.getAccountsByType("com.twitter.android.auth.login"); try { if (twitterAccounts.length > 0) { json.put("granted", true); for (int i = 0; i < twitterAccounts.length; i++) { JSONObject account = new JSONObject(); account.put("userName", twitterAccounts[i].name); accounts.put(account); json.put("accounts", accounts); } pluginResult = new PluginResult(PluginResult.Status.OK, json); } else { json.put("code", "0"); json.put("message", "no have twitter accounts"); pluginResult = new PluginResult(PluginResult.Status.ERROR, json); } } catch (JSONException e) { pluginResult = new PluginResult(PluginResult.Status.ERROR, e.getLocalizedMessage()); } pluginResult.setKeepCallback(true); callbackContext.sendPluginResult(pluginResult); } }); } public void getTwitterSystemAccount(final String networkUserName, final CallbackContext callbackContext) { cordova.getThreadPool().execute(new Runnable() { public void run() { PluginResult pluginResult; final JSONObject json = new JSONObject(); final JSONObject account = new JSONObject(); final Account[] twitterAccounts = accountManager .getAccountsByType("com.twitter.android.auth.login"); try { if (twitterAccounts.length > 0) { json.put("granted", true); for (int i = 0; i < twitterAccounts.length; i++) { if (twitterAccounts[i].name.equals(networkUserName)) { account.put("userName", twitterAccounts[i].name); final Account twitterAccount = twitterAccounts[i]; accountManager.getAuthToken(twitterAccount, "com.twitter.android.oauth.token", null, false, new AccountManagerCallback<Bundle>() { @Override public void run(AccountManagerFuture<Bundle> accountManagerFuture) { try { Bundle bundle = accountManagerFuture.getResult(); if (bundle.containsKey(AccountManager.KEY_INTENT)) { Intent intent = bundle .getParcelable(AccountManager.KEY_INTENT); //clear the new task flag just in case, since a result is expected int flags = intent.getFlags(); flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK; intent.setFlags(flags); requestedTwitterAccountName = networkUserName; cordova.getActivity().startActivityForResult(intent, TWITTER_OAUTH_REQUEST); } else { account.put("oauth_token", bundle.getString(AccountManager.KEY_AUTHTOKEN)); accountManager.getAuthToken(twitterAccount, "com.twitter.android.oauth.token.secret", null, false, new AccountManagerCallback<Bundle>() { @Override public void run( AccountManagerFuture<Bundle> accountManagerFuture) { try { Bundle bundle = accountManagerFuture .getResult(); if (bundle.containsKey( AccountManager.KEY_INTENT)) { Intent intent = bundle .getParcelable( AccountManager.KEY_INTENT); //clear the new task flag just in case, since a result is expected int flags = intent.getFlags(); flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK; intent.setFlags(flags); requestedTwitterAccountName = networkUserName; cordova.getActivity() .startActivityForResult( intent, TWITTER_OAUTH_REQUEST); } else { account.put("oauth_token_secret", bundle.getString( AccountManager.KEY_AUTHTOKEN)); json.put("data", account); Log.v(TAG, "Account data: " + json.toString()); PluginResult pluginResult = new PluginResult( PluginResult.Status.OK, json); pluginResult.setKeepCallback(true); callbackContext.sendPluginResult( pluginResult); } } catch (Exception e) { PluginResult pluginResult = new PluginResult( PluginResult.Status.ERROR, e.getLocalizedMessage()); pluginResult.setKeepCallback(true); callbackContext .sendPluginResult(pluginResult); } } }, null); } } catch (Exception e) { PluginResult pluginResult = new PluginResult( PluginResult.Status.ERROR, e.getLocalizedMessage()); pluginResult.setKeepCallback(true); callbackContext.sendPluginResult(pluginResult); } } }, null); } } } else { json.put("code", "0"); json.put("message", "no have twitter accounts"); pluginResult = new PluginResult(PluginResult.Status.ERROR, json); pluginResult.setKeepCallback(true); callbackContext.sendPluginResult(pluginResult); } } catch (JSONException e) { pluginResult = new PluginResult(PluginResult.Status.ERROR, e.getLocalizedMessage()); pluginResult.setKeepCallback(true); callbackContext.sendPluginResult(pluginResult); } } }); } }