Submit twitter share plugin implement

This commit is contained in:
lihex 2013-04-24 15:59:54 +08:00
parent 4e24ce40ea
commit ae7dab15b6
23 changed files with 1009 additions and 1 deletions

View File

@ -0,0 +1,58 @@
#ifndef __CCX_SOCIAL_TWITTER_H__
#define __CCX_SOCIAL_TWITTER_H__
#include "ProtocolSocial.h"
#include <map>
#include <string>
namespace cocos2d { namespace plugin {
class SocialTwitter : public ProtocolSocial
{
PLUGIN_REGISTER_DECL(SocialTwitter)
public:
/**
@brief plugin initialization
*/
virtual bool init();
/**
@brief initialize the developer info
@param devInfo This parameter is the info of developer, must contains key:
AlipayPartner The partner id of alipay account
AlipaySeller The seller id of alipay account
AlipayRsaPrivate The RSA private key of alipay account
AlipayPublic The public key of alipay account
AlipayNotifyUrl The notify url of developer (must not be empty)
AlipayPluginName The apk file name of Alipay (must not be empty)
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
virtual void initDeveloperInfo(TDeveloperInfo devInfo);
/**
@brief pay for product
@param info The info of product, must contains key:
productName The name of product
productPrice The price of product(must can be parse to float)
productDesc The description of product
@warning For different plugin, the parameter should have other keys to pay.
Look at the manual of plugins.
*/
virtual void share(TShareInfo info);
/**
@brief Set whether needs to output logs to console.
@param debug if true debug mode enabled, or debug mode disabled.
*/
virtual void setDebugMode(bool debug);
virtual const char* getPluginVersion() { return "v0.1.01"; };
virtual const char* getSDKVersion();
virtual ~SocialTwitter();
};
}} // namespace cocos2d { namespace plugin {
#endif /* __CCX_SOCIAL_TWITTER_H__ */

View File

@ -0,0 +1,55 @@
#include "SocialTwitter.h"
#include "PluginUtils.h"
namespace cocos2d { namespace plugin {
PLUGIN_REGISTER_IMPL(SocialTwitter)
SocialTwitter::~SocialTwitter()
{
}
/**
@brief plugin initialization
*/
bool SocialTwitter::init()
{
return PluginUtils::initJavaPlugin(this, "org.cocos2dx.plugin.SocialTwitter");
}
/**
@brief initialize the developer info
@param devInfo This parameter is the info of developer, must contains key:
consumerkey The consumerkey of twitter account
consumersecret The consumersecret of twitter account
More: https://dev.twitter.com
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
void SocialTwitter::initDeveloperInfo(TDeveloperInfo devInfo)
{
ProtocolSocial::initDeveloperInfo(devInfo);
}
/**
@brief pay for product
@param info The info of product, must contains key:
text The text to share
imagePath The full path of image to share
*/
void SocialTwitter::share(TShareInfo info)
{
ProtocolSocial::share(info);
}
const char* SocialTwitter::getSDKVersion()
{
return ProtocolSocial::getSDKVersion();
}
void SocialTwitter::setDebugMode(bool debug)
{
ProtocolSocial::setDebugMode(debug);
}
}} // namespace cocos2d { namespace plugin {

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="lib" path="/Users/lihex/cocos2d-x/plugin/plugins/twitter/proj.android/sdk/signpost-commonshttp4-1.2.1.1.jar"/>
<classpathentry exported="true" kind="lib" path="/Users/lihex/cocos2d-x/plugin/plugins/twitter/proj.android/sdk/signpost-core-1.2.1.1.jar"/>
<classpathentry exported="true" kind="lib" path="/Users/lihex/cocos2d-x/plugin/plugins/twitter/proj.android/sdk/signpost-jetty6-1.2.1.1.jar"/>
<classpathentry exported="true" kind="lib" path="/Users/lihex/cocos2d-x/plugin/plugins/twitter/proj.android/sdk/twitter4j-core-android-3.0.1.jar"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>libPluginTwitter</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>android</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/platform/android</locationURI>
</link>
<link>
<name>include</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/include</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -0,0 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.cocos2dx.libSocialTwitter"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />
</manifest>

View File

@ -0,0 +1 @@
db46ceaf2554c8d9e48cdaec3a4cdf5519bb8896

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifestConfig xmlns:android="http://schemas.android.com/apk/res/android">
<permissionCfg>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</permissionCfg>
</manifestConfig>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="libPluginSocialTwitter" default="plugin-publish">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${plugin.dir}/tools/android/build_common.xml" />
</project>

View File

@ -0,0 +1,20 @@
# set params
PLUGIN_ANDROID_ROOT=$(cd "$(dirname "$0")"; pwd)
if [ ! "${PLUGIN_ROOT}" ]; then
PLUGIN_ROOT="$PLUGIN_ANDROID_ROOT"/../..
fi
# build
"$ANDROID_NDK_ROOT"/ndk-build -C "$PLUGIN_ANDROID_ROOT" \
NDK_MODULE_PATH="$PLUGIN_ROOT"
echo
if [ "0" != "$?" ]; then
echo "Build error occoured!!!"
exit 1
fi
echo
echo "Native build action success."
exit 0

View File

@ -0,0 +1,29 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := PluginTwitterStatic
LOCAL_MODULE_FILENAME := libPluginTwitterStatic
LOCAL_SRC_FILES := \
$(addprefix ../../platform/android/, \
SocialTwitter.cpp \
) \
LOCAL_CFLAGS :=
LOCAL_EXPORT_CFLAGS :=
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_WHOLE_STATIC_LIBRARIES := PluginProtocolStatic
LOCAL_LDLIBS := -landroid
LOCAL_LDLIBS += -llog
include $(BUILD_STATIC_LIBRARY)
$(call import-module, protocols/proj.android/jni)

View File

@ -0,0 +1,7 @@
# it is needed for ndk-r5
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_MODULES := PluginTwitterStatic
APP_ABI :=armeabi
#APP_ABI :=x86
#APP_ABI :=mips mips-r2 mips-r2-sf armeabi

View File

@ -0,0 +1,16 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-7
android.library=true
android.library.reference.1=../../../protocols/proj.android

View File

View File

@ -0,0 +1 @@
62d02b6f0d450b3b64d061280594018742ddcd27

View File

@ -0,0 +1,9 @@
package org.cocos2dx.plugin;
public interface Consts {
public static int EGETTING_ACCESS_TOKEN =0;
public static int EUSER_CANCELED = 1;
public static int EGETTING_REQUEST_TOKEN=2;
public static int EFAILED_OPENING_AUTHORIZATION_PAGE=3;
public static int EPAGE_ERROR =4;
}

View File

@ -0,0 +1,172 @@
package org.cocos2dx.plugin;
import java.util.Hashtable;
import org.cocos2dx.plugin.InterfaceSocial.ShareAdapter;
import org.cocos2dx.plugin.TwitterApp.TwDialogListener;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
public class SocialTwitter implements ShareAdapter {
private static final String LOG_TAG = "SocialTwitter";
private static Activity mContext = null;
protected static boolean bDebug = false;
private static String CONSUMER_KEY="";
private static String CONSUMER_SECRET="";
private static TwitterApp mTwitter = null;
private static boolean isInitialized = false;
private static Hashtable<String, String> mShareInfo = null;
public static String KEY_TEXT="text";
public static String KEY_IMAGE_PATH = "imagePath";
protected static void LogE(String msg, Exception e) {
Log.e(LOG_TAG, msg, e);
e.printStackTrace();
}
protected static void LogD(String msg) {
if (bDebug) {
Log.d(LOG_TAG, msg);
}
}
public SocialTwitter(Context context) {
mContext = (Activity) context;
}
@Override
public void initDeveloperInfo(Hashtable<String, String> cpInfo) {
LogD("initDeveloperInfo invoked " + cpInfo.toString());
mShareInfo = cpInfo;
mShareInfo = cpInfo;
try {
SocialTwitter.CONSUMER_KEY = cpInfo.get("consumerkey");
SocialTwitter.CONSUMER_SECRET = cpInfo.get("consumersecret");
if(isInitialized){
return;
}
isInitialized = true;
PluginWrapper.runOnMainThread(new Runnable() {
@Override
public void run() {
mTwitter = new TwitterApp(PluginWrapper.getContext(), SocialTwitter.CONSUMER_KEY, SocialTwitter.CONSUMER_SECRET);
mTwitter.setListener(mTwLoginDialogListener);
}
});
} catch (Exception e) {
LogE("Developer info is wrong!", e);
}
}
@Override
public void share(Hashtable<String, String> info) {
LogD("share invoked " + info.toString());
mShareInfo = info;
if (! networkReachable()) {
shareResult(InterfaceSocial.SHARERESULT_FAIL, "网络不可用");
return;
}
// need login
if(!mTwitter.hasAccessToken()){
PluginWrapper.runOnMainThread(new Runnable() {
@Override
public void run() {
mTwitter.authorize();
}
});
return;
}
PluginWrapper.runOnMainThread(new Runnable() {
@Override
public void run() {
String text = mShareInfo.get(KEY_TEXT);
String imagePath = mShareInfo.get(KEY_IMAGE_PATH);
try {
if(imagePath != null && imagePath.length() > 0){
mTwitter.updateStatus(text, imagePath);
}else{
mTwitter.updateStatus(text);
}
LogD("Posted to Twitter!");
shareResult(InterfaceSocial.SHARERESULT_SUCCESS, "user lihex");
} catch (Exception e) {
LogD("Post to Twitter failed!");
shareResult(InterfaceSocial.SHARERESULT_FAIL, "user lihex");
e.printStackTrace();
}
}
});
}
@Override
public void setDebugMode(boolean debug) {
bDebug = debug;
}
@Override
public String getSDKVersion() {
return "Unknown version";
}
private boolean networkReachable() {
boolean bRet = false;
try {
ConnectivityManager conn = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conn.getActiveNetworkInfo();
bRet = (null == netInfo) ? false : netInfo.isAvailable();
} catch (Exception e) {
LogE("Fail to check network status", e);
}
LogD("NetWork reachable : " + bRet);
return bRet;
}
private static void shareResult(int ret, String msg) {
InterfaceSocial.shareResult(ret, msg);
LogD("SocialTwitter result : " + ret + " msg : " + msg);
}
private static final TwDialogListener mTwLoginDialogListener = new TwDialogListener() {
@Override
public void onError(int flag, String value) {
LogD("Twitter connection failed!");
shareResult(InterfaceSocial.SHARERESULT_FAIL, value);
}
@Override
public void onComplete(String value) {
String username = mTwitter.getUsername();
LogD("Connected to Twitter as" + username);
String text = mShareInfo.get(KEY_TEXT);
String imagePath = mShareInfo.get(KEY_IMAGE_PATH);
try {
if(imagePath != null && imagePath.length() > 0){
mTwitter.updateStatus(text, imagePath);
}else{
mTwitter.updateStatus(text);
}
LogD("Posted to Twitter!");
shareResult(InterfaceSocial.SHARERESULT_SUCCESS, username);
} catch (Exception e) {
LogD("Post to Twitter failed!");
shareResult(InterfaceSocial.SHARERESULT_FAIL, username);
e.printStackTrace();
}
}
};
}

View File

@ -0,0 +1,237 @@
/**
* @author Lorensius W. L. T <lorenz@londatiga.net>
*
* http://www.londatiga.net
*/
package org.cocos2dx.plugin;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import twitter4j.StatusUpdate;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.auth.AccessToken;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Window;
public class TwitterApp {
private Twitter mTwitter;
private TwitterSession mSession;
private AccessToken mAccessToken;
private CommonsHttpOAuthConsumer mHttpOauthConsumer;
private OAuthProvider mHttpOauthprovider;
private String mConsumerKey;
private String mSecretKey;
private ProgressDialog mProgressDlg;
private TwDialogListener mListener;
private Context context;
private boolean mInit = true;
private static final String LOG_TAG = "TwitterApp";
public static final String CALLBACK_URL = "twitterapp://connect";
protected static void LogE(String msg, Exception e) {
Log.e(LOG_TAG, msg, e);
e.printStackTrace();
}
protected static void LogD(String msg) {
if (SocialTwitter.bDebug) {
Log.d(LOG_TAG, msg);
}
}
public TwitterApp(Context context, String consumerKey, String secretKey) {
this.context = context;
mTwitter = new TwitterFactory().getInstance();
mSession = new TwitterSession(context);
mProgressDlg = new ProgressDialog(context);
mProgressDlg.setCancelable(false);
mProgressDlg.requestWindowFeature(Window.FEATURE_NO_TITLE);
mConsumerKey = consumerKey;
mSecretKey = secretKey;
mHttpOauthConsumer = new CommonsHttpOAuthConsumer(mConsumerKey, mSecretKey);
mHttpOauthprovider = new DefaultOAuthProvider("https://twitter.com/oauth/request_token",
"https://twitter.com/oauth/access_token",
"https://twitter.com/oauth/authorize");
mAccessToken = mSession.getAccessToken();
configureToken();
}
public void setListener(TwDialogListener listener) {
mListener = listener;
}
private void configureToken() {
if (mAccessToken != null) {
if (mInit) {
mTwitter.setOAuthConsumer(mConsumerKey, mSecretKey);
mInit = false;
}
mTwitter.setOAuthAccessToken(mAccessToken);
}
}
public boolean hasAccessToken() {
return (mAccessToken == null) ? false : true;
}
public void resetAccessToken() {
if (mAccessToken != null) {
mSession.resetAccessToken();
mAccessToken = null;
}
}
public String getUsername() {
return mSession.getUsername();
}
public void updateStatus(String status) throws Exception {
try {
mTwitter.updateStatus(status);
} catch (TwitterException e) {
throw e;
}
}
public void updateStatus(String status, String imagePath) throws Exception {
StatusUpdate update = new StatusUpdate(status);
update.setMedia(new File(imagePath));
try {
mTwitter.updateStatus(update);
} catch (TwitterException e) {
throw e;
}
}
public void authorize() {
mProgressDlg.setMessage("Initializing ...");
mProgressDlg.show();
new Thread() {
@Override
public void run() {
String authUrl = "";
int what = 1;
try {
authUrl = mHttpOauthprovider.retrieveRequestToken(mHttpOauthConsumer, CALLBACK_URL);
what = 0;
LogD("Request token url " + authUrl);
} catch (Exception e) {
LogD("Failed to get request token");
e.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage(what, 1, 0, authUrl));
}
}.start();
}
public void processToken(String callbackUrl) {
mProgressDlg.setMessage("Finalizing ...");
mProgressDlg.show();
final String verifier = getVerifier(callbackUrl);
new Thread() {
@Override
public void run() {
int what = 1;
try {
mHttpOauthprovider.retrieveAccessToken(mHttpOauthConsumer, verifier);
mAccessToken = new AccessToken(mHttpOauthConsumer.getToken(), mHttpOauthConsumer.getTokenSecret());
configureToken();
User user = mTwitter.verifyCredentials();
mSession.storeAccessToken(mAccessToken, user.getName());
what = 0;
} catch (Exception e){
LogD("Error getting access token");
e.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage(what, 2, 0));
}
}.start();
}
private String getVerifier(String callbackUrl) {
String verifier = "";
try {
callbackUrl = callbackUrl.replace("twitterapp", "http");
URL url = new URL(callbackUrl);
String query = url.getQuery();
String array[] = query.split("&");
for (String parameter : array) {
String v[] = parameter.split("=");
if (URLDecoder.decode(v[0]).equals(oauth.signpost.OAuth.OAUTH_VERIFIER)) {
verifier = URLDecoder.decode(v[1]);
break;
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
return verifier;
}
private void showLoginDialog(String url) {
final TwDialogListener listener = new TwDialogListener() {
@Override
public void onComplete(String value) {
processToken(value);
}
@Override
public void onError(int flag, String value) {
mListener.onError(Consts.EFAILED_OPENING_AUTHORIZATION_PAGE, "Failed opening authorization page");
}
};
new TwitterDialog(context, url, listener).show();
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mProgressDlg.dismiss();
if (msg.what == 1) {
if (msg.arg1 == 1)
mListener.onError(Consts.EGETTING_REQUEST_TOKEN, "Error getting request token");
else
mListener.onError(Consts.EGETTING_ACCESS_TOKEN, "Error getting access token");
}else {
if (msg.arg1 == 1)
showLoginDialog((String) msg.obj);
else
mListener.onComplete("");
}
}
};
public interface TwDialogListener {
public void onComplete(String value);
public void onError(int flag, String value);
}
}

View File

@ -0,0 +1,182 @@
/**
* Modified from FbDialog from Facebook SDK
*
* Lorensius W. L. T <lorenz@londatiga.net>
*/
package org.cocos2dx.plugin;
import org.cocos2dx.plugin.TwitterApp.TwDialogListener;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
public class TwitterDialog extends Dialog {
static final FrameLayout.LayoutParams FILL = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
static final int MARGIN = 4;
static final int PADDING = 2;
private String mUrl;
private TwDialogListener mListener;
private ProgressDialog mSpinner;
private WebView mWebView;
private LinearLayout mContent;
private TextView mTitle;
private static final String LOG_TAG = "Twitter-WebView";
protected static void LogD(String msg) {
if (SocialTwitter.bDebug) {
Log.d(LOG_TAG, msg);
}
}
public TwitterDialog(Context context, String url, TwDialogListener listener) {
super(context);
mUrl = url;
mListener = listener;
setOnCancelListener(mCancelListener);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSpinner = new ProgressDialog(getContext());
mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
mSpinner.setMessage("Loading...");
mSpinner.setCancelable(false);
mContent = new LinearLayout(getContext());
mContent.setOrientation(LinearLayout.VERTICAL);
setUpTitle();
setUpWebView();
Display display = getWindow().getWindowManager().getDefaultDisplay();
double[] dimensions = new double[2];
if (display.getWidth() < display.getHeight()) {
dimensions[0] = 0.87 * display.getWidth();
dimensions[1] = 0.82 * display.getHeight();
} else {
dimensions[0] = 0.75 * display.getWidth();
dimensions[1] = 0.75 * display.getHeight();
}
addContentView(mContent, new FrameLayout.LayoutParams((int) dimensions[0], (int) dimensions[1]));
}
private void setUpTitle() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Drawable icon = getContext().getResources().getDrawable(R.drawable.twitter_icon);
mTitle = new TextView(getContext());
mTitle.setText("Twitter");
mTitle.setTextColor(Color.WHITE);
mTitle.setTypeface(Typeface.DEFAULT_BOLD);
mTitle.setBackgroundColor(0xFFbbd7e9);
mTitle.setPadding(MARGIN + PADDING, MARGIN, MARGIN, MARGIN);
mTitle.setCompoundDrawablePadding(MARGIN + PADDING);
// mTitle.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
mTitle.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
mContent.addView(mTitle);
}
private void setUpWebView() {
CookieSyncManager.createInstance(getContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
mWebView = new WebView(getContext());
mWebView.setVerticalScrollBarEnabled(false);
mWebView.setHorizontalScrollBarEnabled(false);
mWebView.setWebViewClient(new TwitterWebViewClient());
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl(mUrl);
mWebView.setLayoutParams(FILL);
mContent.addView(mWebView);
}
private class TwitterWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
LogD("Redirecting URL " + url);
if (url.startsWith(TwitterApp.CALLBACK_URL)) {
mListener.onComplete(url);
TwitterDialog.this.dismiss();
return true;
} else if (url.startsWith("authorize")) {
return false;
}
return true;
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
LogD("Page error: " + description);
super.onReceivedError(view, errorCode, description, failingUrl);
mListener.onError(Consts.EPAGE_ERROR, description);
TwitterDialog.this.dismiss();
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
LogD("Loading URL: " + url);
super.onPageStarted(view, url, favicon);
mSpinner.show();
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String title = mWebView.getTitle();
if (title != null && title.length() > 0) {
mTitle.setText(title);
}
mSpinner.dismiss();
}
}
private DialogInterface.OnCancelListener mCancelListener = new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mSpinner.dismiss();
mListener.onError(Consts.EUSER_CANCELED, "User canceled!");
}
};
}

View File

@ -0,0 +1,56 @@
/**
* @author Lorensius W. L. T <lorenz@londatiga.net>
*
* http://www.londatiga.net
*/
package org.cocos2dx.plugin;
import twitter4j.auth.AccessToken;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class TwitterSession {
private SharedPreferences sharedPref;
private Editor editor;
private static final String TWEET_AUTH_KEY = "auth_key";
private static final String TWEET_AUTH_SECRET_KEY = "auth_secret_key";
private static final String TWEET_USER_NAME = "user_name";
private static final String SHARED = "Twitter_Preferences";
public TwitterSession(Context context) {
sharedPref = context.getSharedPreferences(SHARED, Context.MODE_PRIVATE);
editor = sharedPref.edit();
}
public void storeAccessToken(AccessToken accessToken, String username) {
editor.putString(TWEET_AUTH_KEY, accessToken.getToken());
editor.putString(TWEET_AUTH_SECRET_KEY, accessToken.getTokenSecret());
editor.putString(TWEET_USER_NAME, username);
editor.commit();
}
public void resetAccessToken() {
editor.putString(TWEET_AUTH_KEY, null);
editor.putString(TWEET_AUTH_SECRET_KEY, null);
editor.putString(TWEET_USER_NAME, null);
editor.commit();
}
public String getUsername() {
return sharedPref.getString(TWEET_USER_NAME, "");
}
public AccessToken getAccessToken() {
String token = sharedPref.getString(TWEET_AUTH_KEY, null);
String tokenSecret = sharedPref.getString(TWEET_AUTH_SECRET_KEY, null);
if (token != null && tokenSecret != null)
return new AccessToken(token, tokenSecret);
else
return null;
}
}

View File

@ -1,7 +1,8 @@
#define plugins array
export ALL_PLUGINS=("flurry" "umeng" \
"alipay" "nd91" \
"admob")
"admob" \
"twitter")
# define the plugin root directory & publish target directory
export TARGET_DIR_NAME="publish"