mirror of https://github.com/axmolengine/axmol.git
Merge pull request #1 from lihex/master
Add twitter social share plugin
This commit is contained in:
commit
d657524859
|
@ -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__ */
|
|
@ -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 {
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1 @@
|
|||
db46ceaf2554c8d9e48cdaec3a4cdf5519bb8896
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
62d02b6f0d450b3b64d061280594018742ddcd27
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef __CXX_PROTOCOL_SOCIAL_H__
|
||||
#define __CXX_PROTOCOL_SOCIAL_H__
|
||||
|
||||
#include "PluginProtocol.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace cocos2d { namespace plugin {
|
||||
|
||||
typedef std::map<std::string, std::string> TDeveloperInfo;
|
||||
typedef std::map<std::string, std::string> TShareInfo;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eShareSuccess = 0,
|
||||
eShareFail,
|
||||
eShareCancel,
|
||||
eShareTimeOut,
|
||||
} EShareResult;
|
||||
|
||||
class ShareResultListener
|
||||
{
|
||||
public:
|
||||
virtual void shareResult(EShareResult ret, const char* msg, TShareInfo info) = 0;
|
||||
};
|
||||
|
||||
class ProtocolSocial : public PluginProtocol
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
@brief plugin initialization
|
||||
*/
|
||||
virtual bool init();
|
||||
|
||||
/**
|
||||
@brief initialize the developer info
|
||||
@param devInfo This parameter is the info of developer,
|
||||
different plugin have different format
|
||||
@warning Must invoke this interface before other interfaces.
|
||||
And invoked only once.
|
||||
*/
|
||||
virtual void initDeveloperInfo(TDeveloperInfo devInfo);
|
||||
|
||||
/**
|
||||
@brief share information
|
||||
@param info The info of share, must contains key:
|
||||
text The text of share
|
||||
@warning For different plugin, the parameter should have other keys to share.
|
||||
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);
|
||||
|
||||
/**
|
||||
@breif set the result listener
|
||||
@param pListener The callback object for share result
|
||||
@wraning Must invoke this interface before share
|
||||
*/
|
||||
static void setResultListener(ShareResultListener* pListener);
|
||||
|
||||
/**
|
||||
@brief share result callback
|
||||
*/
|
||||
static void shareResult(EShareResult ret, const char* msg);
|
||||
|
||||
virtual const char* getPluginVersion() { return "ProtocolSocial, v0.1.00 , subclass should override this interface!"; };
|
||||
virtual const char* getSDKVersion();
|
||||
virtual const char* getPluginName() = 0;
|
||||
|
||||
protected:
|
||||
ProtocolSocial();
|
||||
public:
|
||||
virtual ~ProtocolSocial();
|
||||
|
||||
protected:
|
||||
static bool m_bSharing;
|
||||
static ShareResultListener* m_pListener;
|
||||
static TShareInfo m_curInfo;
|
||||
};
|
||||
|
||||
}} // namespace cocos2d { namespace plugin {
|
||||
|
||||
#endif /* ----- #ifndef __CXX_PROTOCOL_SOCIAL_H__ ----- */
|
|
@ -0,0 +1,151 @@
|
|||
#include "ProtocolSocial.h"
|
||||
#include "PluginJniHelper.h"
|
||||
#include <android/log.h>
|
||||
#include "PluginUtils.h"
|
||||
#include "PluginJavaData.h"
|
||||
|
||||
#if 1
|
||||
#define LOG_TAG "ProtocolSocial"
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||
#else
|
||||
#define LOGD(...)
|
||||
#endif
|
||||
|
||||
namespace cocos2d { namespace plugin {
|
||||
|
||||
extern "C" {
|
||||
JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceSocial_nativeShareResult(JNIEnv* env, jobject thiz, jint ret, jstring msg)
|
||||
{
|
||||
std::string strMsg = PluginJniHelper::jstring2string(msg);
|
||||
ProtocolSocial::shareResult((EShareResult) ret, strMsg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool ProtocolSocial::m_bSharing = false;
|
||||
ShareResultListener* ProtocolSocial::m_pListener = NULL;
|
||||
TShareInfo ProtocolSocial::m_curInfo;
|
||||
|
||||
ProtocolSocial::ProtocolSocial()
|
||||
{
|
||||
}
|
||||
|
||||
ProtocolSocial::~ProtocolSocial()
|
||||
{
|
||||
PluginUtils::erasePluginJavaData(this);
|
||||
}
|
||||
|
||||
bool ProtocolSocial::init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProtocolSocial::initDeveloperInfo(TDeveloperInfo devInfo)
|
||||
{
|
||||
if (devInfo.empty())
|
||||
{
|
||||
LOGD("The developer info is empty!");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
|
||||
PluginJniMethodInfo t;
|
||||
if (PluginJniHelper::getMethodInfo(t
|
||||
, pData->jclassName.c_str()
|
||||
, "initDeveloperInfo"
|
||||
, "(Ljava/util/Hashtable;)V"))
|
||||
{
|
||||
// generate the hashtable from map
|
||||
jobject obj_Map = PluginUtils::createJavaMapObject(t, &devInfo);
|
||||
|
||||
// invoke java method
|
||||
t.env->CallVoidMethod(pData->jobj, t.methodID, obj_Map);
|
||||
t.env->DeleteLocalRef(obj_Map);
|
||||
t.env->DeleteLocalRef(t.classID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolSocial::share(TShareInfo info)
|
||||
{
|
||||
if (m_bSharing)
|
||||
{
|
||||
LOGD("Now is sharing");
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.empty())
|
||||
{
|
||||
if (NULL != m_pListener)
|
||||
{
|
||||
shareResult(eShareFail, "Share info error");
|
||||
}
|
||||
LOGD("The Share info is empty!");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bSharing = true;
|
||||
m_curInfo = info;
|
||||
|
||||
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
|
||||
PluginJniMethodInfo t;
|
||||
if (PluginJniHelper::getMethodInfo(t
|
||||
, pData->jclassName.c_str()
|
||||
, "share"
|
||||
, "(Ljava/util/Hashtable;)V"))
|
||||
{
|
||||
// generate the hashtable from map
|
||||
jobject obj_Map = PluginUtils::createJavaMapObject(t, &info);
|
||||
|
||||
// invoke java method
|
||||
t.env->CallVoidMethod(pData->jobj, t.methodID, obj_Map);
|
||||
t.env->DeleteLocalRef(obj_Map);
|
||||
t.env->DeleteLocalRef(t.classID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolSocial::setResultListener(ShareResultListener* pListener)
|
||||
{
|
||||
m_pListener = pListener;
|
||||
}
|
||||
|
||||
void ProtocolSocial::shareResult(EShareResult ret, const char* msg)
|
||||
{
|
||||
m_bSharing = false;
|
||||
if (m_pListener)
|
||||
{
|
||||
m_pListener->shareResult(ret, msg, m_curInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGD("Result listener is null!");
|
||||
}
|
||||
m_curInfo.clear();
|
||||
LOGD("Share result is : %d(%s)", (int) ret, msg);
|
||||
}
|
||||
|
||||
const char* ProtocolSocial::getSDKVersion()
|
||||
{
|
||||
std::string verName;
|
||||
|
||||
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
|
||||
PluginJniMethodInfo t;
|
||||
if (PluginJniHelper::getMethodInfo(t
|
||||
, pData->jclassName.c_str()
|
||||
, "getSDKVersion"
|
||||
, "()Ljava/lang/String;"))
|
||||
{
|
||||
jstring ret = (jstring)(t.env->CallObjectMethod(pData->jobj, t.methodID));
|
||||
verName = PluginJniHelper::jstring2string(ret);
|
||||
}
|
||||
return verName.c_str();
|
||||
}
|
||||
|
||||
void ProtocolSocial::setDebugMode(bool debug)
|
||||
{
|
||||
PluginUtils::callJavaFunctionWithName_oneBaseType(this, "setDebugMode", "(Z)V", debug);
|
||||
}
|
||||
|
||||
}} // namespace cocos2d { namespace plugin {
|
|
@ -13,6 +13,7 @@ $(addprefix ../../platform/android/, \
|
|||
ProtocolAnalytics.cpp \
|
||||
ProtocolIAP.cpp \
|
||||
ProtocolAds.cpp \
|
||||
ProtocolSocial.cpp \
|
||||
) \
|
||||
../../PluginManager.cpp \
|
||||
../../RegisterPlugin.cpp \
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package org.cocos2dx.plugin;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class InterfaceSocial {
|
||||
public static final int SHARERESULT_SUCCESS = 0;
|
||||
public static final int SHARERESULT_FAIL = 1;
|
||||
public static final int SHARERESULT_CANCEL = 2;
|
||||
public static final int SHARERESULT_TIMEOUT = 3;
|
||||
|
||||
public interface ShareAdapter {
|
||||
public void initDeveloperInfo(Hashtable<String, String> cpInfo);
|
||||
public void share(Hashtable<String, String> cpInfo);
|
||||
public void setDebugMode(boolean debug);
|
||||
public String getSDKVersion();
|
||||
}
|
||||
|
||||
public static void shareResult(int ret, String msg) {
|
||||
final int curRet = ret;
|
||||
final String curMsg = msg;
|
||||
PluginWrapper.runOnGLThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeShareResult(curRet, curMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
private static native void nativeShareResult(int ret, String msg);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
#include "AppDelegate.h"
|
||||
#include "cocos2d.h"
|
||||
#include "HelloWorldScene.h"
|
||||
#include "PluginManager.h"
|
||||
#include "MyShareManager.h"
|
||||
|
||||
using namespace cocos2d::plugin;
|
||||
USING_NS_CC;
|
||||
|
||||
AppDelegate::AppDelegate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AppDelegate::~AppDelegate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool AppDelegate::applicationDidFinishLaunching()
|
||||
{
|
||||
MyShareManager::sharedManager()->loadSocialPlugin();
|
||||
|
||||
// initialize director
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
|
||||
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
|
||||
pEGLView->setDesignResolutionSize(960.0f, 640.0f, kResolutionNoBorder);
|
||||
// turn on display FPS
|
||||
pDirector->setDisplayStats(true);
|
||||
|
||||
// set FPS. the default value is 1.0/60 if you don't call this
|
||||
pDirector->setAnimationInterval(1.0 / 60);
|
||||
|
||||
// create a scene. it's an autorelease object
|
||||
CCScene *pScene = HelloWorld::scene();
|
||||
|
||||
// run
|
||||
pDirector->runWithScene(pScene);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
|
||||
void AppDelegate::applicationDidEnterBackground()
|
||||
{
|
||||
CCDirector::sharedDirector()->pause();
|
||||
|
||||
// if you use SimpleAudioEngine, it must be pause
|
||||
// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
|
||||
}
|
||||
|
||||
// this function will be called when the app is active again
|
||||
void AppDelegate::applicationWillEnterForeground()
|
||||
{
|
||||
CCDirector::sharedDirector()->resume();
|
||||
|
||||
// if you use SimpleAudioEngine, it must resume here
|
||||
// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef _APP_DELEGATE_H_
|
||||
#define _APP_DELEGATE_H_
|
||||
|
||||
#include "CCApplication.h"
|
||||
|
||||
/**
|
||||
@brief The cocos2d Application.
|
||||
|
||||
The reason for implement as private inheritance is to hide some interface call by CCDirector.
|
||||
*/
|
||||
class AppDelegate : private cocos2d::CCApplication
|
||||
{
|
||||
public:
|
||||
AppDelegate();
|
||||
virtual ~AppDelegate();
|
||||
|
||||
/**
|
||||
@brief Implement CCDirector and CCScene init code here.
|
||||
@return true Initialize success, app continue.
|
||||
@return false Initialize failed, app terminate.
|
||||
*/
|
||||
virtual bool applicationDidFinishLaunching();
|
||||
|
||||
/**
|
||||
@brief The function be called when the application enter background
|
||||
@param the pointer of the application
|
||||
*/
|
||||
virtual void applicationDidEnterBackground();
|
||||
|
||||
/**
|
||||
@brief The function be called when the application enter foreground
|
||||
@param the pointer of the application
|
||||
*/
|
||||
virtual void applicationWillEnterForeground();
|
||||
|
||||
static void loadAnalyticsPlugin();
|
||||
};
|
||||
|
||||
#endif // _APP_DELEGATE_H_
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
#include "HelloWorldScene.h"
|
||||
#include "PluginManager.h"
|
||||
#include "AppDelegate.h"
|
||||
#include "MyShareManager.h"
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace cocos2d::plugin;
|
||||
|
||||
enum {
|
||||
TAG_PAY_BY_ALIPAY = 100,
|
||||
TAG_PAY_BY_ND91,
|
||||
};
|
||||
|
||||
typedef struct tagEventMenuItem {
|
||||
std::string id;
|
||||
int tag;
|
||||
}EventMenuItem;
|
||||
|
||||
static EventMenuItem s_EventMenuItem[] = {
|
||||
{"twitter.jpeg", TAG_PAY_BY_ALIPAY}
|
||||
};
|
||||
|
||||
CCScene* HelloWorld::scene()
|
||||
{
|
||||
// 'scene' is an autorelease object
|
||||
CCScene *scene = CCScene::create();
|
||||
|
||||
// 'layer' is an autorelease object
|
||||
HelloWorld *layer = HelloWorld::create();
|
||||
|
||||
// add layer as a child to scene
|
||||
scene->addChild(layer);
|
||||
|
||||
// return the scene
|
||||
return scene;
|
||||
}
|
||||
|
||||
// on "init" you need to initialize your instance
|
||||
bool HelloWorld::init()
|
||||
{
|
||||
//////////////////////////////
|
||||
// 1. super init first
|
||||
if ( !CCLayer::init() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CCSize size = CCDirector::sharedDirector()->getVisibleSize();
|
||||
|
||||
CCSprite* pBackground = CCSprite::create("background.png");
|
||||
pBackground->setPosition(ccp(size.width / 2, size.height / 2));
|
||||
addChild(pBackground);
|
||||
/////////////////////////////
|
||||
// 2. add a menu item with "X" image, which is clicked to quit the program
|
||||
// you may modify it.
|
||||
|
||||
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
|
||||
CCPoint posBR = ccp(pEGLView->getVisibleOrigin().x + pEGLView->getVisibleSize().width, pEGLView->getVisibleOrigin().y);
|
||||
CCPoint posBC = ccp(pEGLView->getVisibleOrigin().x + pEGLView->getVisibleSize().width/2, pEGLView->getVisibleOrigin().y);
|
||||
CCPoint posTL = ccp(pEGLView->getVisibleOrigin().x, pEGLView->getVisibleOrigin().y + pEGLView->getVisibleSize().height);
|
||||
|
||||
// add a "close" icon to exit the progress. it's an autorelease object
|
||||
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
|
||||
"CloseNormal.png",
|
||||
"CloseSelected.png",
|
||||
this,
|
||||
menu_selector(HelloWorld::menuCloseCallback) );
|
||||
pCloseItem->setPosition( ccp(posBR.x - 20, posBR.y + 20) );
|
||||
|
||||
// create menu, it's an autorelease object
|
||||
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
|
||||
pMenu->setPosition( CCPointZero );
|
||||
this->addChild(pMenu, 1);
|
||||
|
||||
CCPoint posStep = ccp(220, -150);
|
||||
CCPoint beginPos = ccpAdd(posTL, ccpMult(posStep, 0.5f));
|
||||
int line = 0;
|
||||
int row = 0;
|
||||
for (int i = 0; i < sizeof(s_EventMenuItem)/sizeof(s_EventMenuItem[0]); i++) {
|
||||
CCMenuItemImage* pMenuItem = CCMenuItemImage::create(s_EventMenuItem[i].id.c_str(), s_EventMenuItem[i].id.c_str(),
|
||||
this, menu_selector(HelloWorld::eventMenuCallback));
|
||||
pMenu->addChild(pMenuItem, 0, s_EventMenuItem[i].tag);
|
||||
|
||||
CCPoint pos = ccpAdd(beginPos, ccp(posStep.x * row, posStep.y * line));
|
||||
CCSize itemSize = pMenuItem->getContentSize();
|
||||
if ((pos.x + itemSize.width / 2) > posBR.x)
|
||||
{
|
||||
line += 1;
|
||||
row = 0;
|
||||
pos = ccpAdd(beginPos, ccp(posStep.x * row, posStep.y * line));
|
||||
}
|
||||
row += 1;
|
||||
pMenuItem->setPosition(pos);
|
||||
}
|
||||
|
||||
CCLabelTTF* label = CCLabelTTF::create("Reload all plugins", "Arial", 24);
|
||||
CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(HelloWorld::reloadPluginMenuCallback));
|
||||
pMenuItem->setAnchorPoint(ccp(0.5f, 0));
|
||||
pMenu->addChild(pMenuItem, 0);
|
||||
pMenuItem->setPosition(posBC);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HelloWorld::reloadPluginMenuCallback(CCObject* pSender)
|
||||
{
|
||||
MyShareManager::sharedManager()->unloadSocialPlugin();
|
||||
MyShareManager::sharedManager()->loadSocialPlugin();
|
||||
}
|
||||
|
||||
void HelloWorld::eventMenuCallback(CCObject* pSender)
|
||||
{
|
||||
TShareInfo pInfo;
|
||||
pInfo["text"] = "MyFirst tweet!";
|
||||
// pInfo["imagePath"] = "Full/path/to/image";
|
||||
MyShareManager::sharedManager()->shareByMode(pInfo, MyShareManager::eTwitter);
|
||||
}
|
||||
|
||||
void HelloWorld::menuCloseCallback(CCObject* pSender)
|
||||
{
|
||||
MyShareManager::purgeManager();
|
||||
CCDirector::sharedDirector()->end();
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __HELLOWORLD_SCENE_H__
|
||||
#define __HELLOWORLD_SCENE_H__
|
||||
|
||||
#include "cocos2d.h"
|
||||
|
||||
class HelloWorld : public cocos2d::CCLayer
|
||||
{
|
||||
public:
|
||||
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
|
||||
virtual bool init();
|
||||
|
||||
// there's no 'id' in cpp, so we recommand to return the exactly class pointer
|
||||
static cocos2d::CCScene* scene();
|
||||
|
||||
// a selector callback
|
||||
void menuCloseCallback(CCObject* pSender);
|
||||
void eventMenuCallback(CCObject* pSender);
|
||||
void reloadPluginMenuCallback(CCObject* pSender);
|
||||
|
||||
// implement the "static node()" method manually
|
||||
CREATE_FUNC(HelloWorld);
|
||||
};
|
||||
|
||||
#endif // __HELLOWORLD_SCENE_H__
|
|
@ -0,0 +1,106 @@
|
|||
#include "MyShareManager.h"
|
||||
#include "PluginManager.h"
|
||||
#include "cocos2d.h"
|
||||
|
||||
using namespace cocos2d::plugin;
|
||||
using namespace cocos2d;
|
||||
|
||||
MyShareManager* MyShareManager::s_pManager = NULL;
|
||||
|
||||
MyShareManager::MyShareManager()
|
||||
: s_pRetListener(NULL)
|
||||
, s_pTwitter(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MyShareManager::~MyShareManager()
|
||||
{
|
||||
unloadSocialPlugin();
|
||||
if (s_pRetListener)
|
||||
{
|
||||
delete s_pRetListener;
|
||||
}
|
||||
}
|
||||
|
||||
MyShareManager* MyShareManager::sharedManager()
|
||||
{
|
||||
if (s_pManager == NULL) {
|
||||
s_pManager = new MyShareManager();
|
||||
}
|
||||
return s_pManager;
|
||||
}
|
||||
|
||||
void MyShareManager::purgeManager()
|
||||
{
|
||||
if (s_pManager)
|
||||
{
|
||||
delete s_pManager;
|
||||
}
|
||||
}
|
||||
|
||||
void MyShareManager::loadSocialPlugin()
|
||||
{
|
||||
{
|
||||
// init twitter plugin
|
||||
s_pTwitter = dynamic_cast<SocialTwitter*>(PluginManager::getInstance()->loadPlugin("SocialTwitter"));
|
||||
TDeveloperInfo pTwitterInfo;
|
||||
|
||||
/* Warning: must set your twiiter dev info here */
|
||||
// pTwitterInfo["consumerkey"] = "your consumerkey";
|
||||
// pTwitterInfo["consumersecret"] = "your consumersecret";
|
||||
|
||||
if (pTwitterInfo.empty())
|
||||
{
|
||||
char msg[256] = { 0 };
|
||||
sprintf(msg, "Developer info is empty. PLZ fill your twitter info in %s(nearby line %d)", __FILE__, __LINE__);
|
||||
CCMessageBox(msg, "Twitter Warning");
|
||||
}
|
||||
s_pTwitter->setDebugMode(true);
|
||||
s_pTwitter->initDeveloperInfo(pTwitterInfo);
|
||||
}
|
||||
|
||||
if (s_pRetListener == NULL)
|
||||
{
|
||||
s_pRetListener = new MyShareResult();
|
||||
ProtocolSocial::setResultListener(s_pRetListener);
|
||||
}
|
||||
}
|
||||
|
||||
void MyShareManager::unloadSocialPlugin()
|
||||
{
|
||||
if (s_pTwitter)
|
||||
{
|
||||
PluginManager::getInstance()->unloadPlugin("SocialTwitter");
|
||||
s_pTwitter = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MyShareManager::shareByMode(TShareInfo info, MyShareMode mode)
|
||||
{
|
||||
ProtocolSocial* pShare = NULL;
|
||||
switch(mode)
|
||||
{
|
||||
case eTwitter:
|
||||
pShare = s_pTwitter;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pShare) {
|
||||
pShare->share(info);
|
||||
}
|
||||
}
|
||||
|
||||
void MyShareResult::shareResult(EShareResult ret, const char* msg, TShareInfo info)
|
||||
{
|
||||
char shareInfo[1024] = { 0 };
|
||||
char shareStatus[1024] = { 0 };
|
||||
sprintf(shareStatus, "Share info:%s", (ret == eShareSuccess)? "Successed" : "Failed");
|
||||
sprintf(shareInfo, " %s\ntext:%s",
|
||||
shareStatus,
|
||||
info.find("text")->second.c_str()
|
||||
);
|
||||
CCMessageBox(shareInfo , msg);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef __MY_SHARE_MANAGER_H__
|
||||
#define __MY_SHARE_MANAGER_H__
|
||||
|
||||
#include "SocialTwitter.h"
|
||||
|
||||
class MyShareResult : public cocos2d::plugin::ShareResultListener
|
||||
{
|
||||
public:
|
||||
virtual void shareResult(cocos2d::plugin::EShareResult ret, const char* msg, cocos2d::plugin::TShareInfo info);
|
||||
};
|
||||
|
||||
class MyShareManager
|
||||
{
|
||||
public:
|
||||
static MyShareManager* sharedManager();
|
||||
static void purgeManager();
|
||||
|
||||
typedef enum {
|
||||
eNoneMode = 0,
|
||||
eTwitter,
|
||||
} MyShareMode;
|
||||
|
||||
void unloadSocialPlugin();
|
||||
void loadSocialPlugin();
|
||||
void shareByMode(cocos2d::plugin::TShareInfo info, MyShareMode mode);
|
||||
|
||||
private:
|
||||
MyShareManager();
|
||||
virtual ~MyShareManager();
|
||||
|
||||
static MyShareManager* s_pManager;
|
||||
|
||||
cocos2d::plugin::SocialTwitter* s_pTwitter;
|
||||
MyShareResult* s_pRetListener;
|
||||
};
|
||||
|
||||
#endif // __MY_SHARE_MANAGER_H__
|
|
@ -0,0 +1 @@
|
|||
b2e4ae6ce873ef4a74cf0230693ef26e939d2778
|
|
@ -0,0 +1,14 @@
|
|||
<?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="publish/protocols/android/libPluginProtocol.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="/Users/lihex/cocos2d-x/plugin/publish/plugins/twitter/android/libPluginSocialTwitter.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="publish/plugins/twitter/android/signpost-commonshttp4-1.2.1.1.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="publish/plugins/twitter/android/signpost-core-1.2.1.1.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="publish/plugins/twitter/android/signpost-jetty6-1.2.1.1.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="publish/plugins/twitter/android/twitter4j-core-android-3.0.1.jar"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>HelloSocial</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>Classes</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-1-PROJECT_LOC/Classes</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>publish</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-3-PROJECT_LOC/publish</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.cocos2dx.helloSocial"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-sdk android:minSdkVersion="8"/>
|
||||
|
||||
<application android:label="@string/app_name"
|
||||
android:debuggable="true"
|
||||
android:icon="@drawable/icon">
|
||||
|
||||
<activity android:name=".HelloSocial"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:configChanges="orientation">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<!-- Twitter permission -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
|
@ -0,0 +1,17 @@
|
|||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked into Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# This file is only used by the Ant script.
|
||||
|
||||
# You can use this to override default values such as
|
||||
# 'source.dir' for the location of your java source folder and
|
||||
# 'out.dir' for the location of your output folder.
|
||||
|
||||
# You can also use it define how the release builds are signed by declaring
|
||||
# the following properties:
|
||||
# 'key.store' for the location of your keystore and
|
||||
# 'key.alias' for the name of the key to use.
|
||||
# The password will be asked during the build when you use the 'release' target.
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="HelloAnalytics" default="help">
|
||||
|
||||
<!-- 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="${sdk.dir}/tools/ant/build.xml" />
|
||||
|
||||
</project>
|
|
@ -0,0 +1,81 @@
|
|||
APPNAME="HelloAnalytics"
|
||||
|
||||
# options
|
||||
|
||||
buildexternalsfromsource=
|
||||
|
||||
usage(){
|
||||
cat << EOF
|
||||
usage: $0 [options]
|
||||
|
||||
Build C/C++ code for $APPNAME using Android NDK
|
||||
|
||||
OPTIONS:
|
||||
-s Build externals from source
|
||||
-h this help
|
||||
EOF
|
||||
}
|
||||
|
||||
while getopts "sh" OPTION; do
|
||||
case "$OPTION" in
|
||||
s)
|
||||
buildexternalsfromsource=1
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# paths
|
||||
|
||||
if [ -z "${NDK_ROOT+aaa}" ];then
|
||||
echo "please define NDK_ROOT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
# ... use paths relative to current directory
|
||||
PLUGIN_ROOT="$DIR/../../.."
|
||||
COCOS2DX_ROOT="$DIR/../../../.."
|
||||
APP_ROOT="$DIR/.."
|
||||
APP_ANDROID_ROOT="$DIR"
|
||||
|
||||
echo "PLUGIN_ROOT = $PLUGIN_ROOT"
|
||||
echo "NDK_ROOT = $NDK_ROOT"
|
||||
echo "COCOS2DX_ROOT = $COCOS2DX_ROOT"
|
||||
echo "APP_ROOT = $APP_ROOT"
|
||||
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT"
|
||||
echo "---------------------------------------------------------"
|
||||
|
||||
# make sure assets is exist
|
||||
if [ -d "$APP_ANDROID_ROOT"/assets ]; then
|
||||
rm -rf "$APP_ANDROID_ROOT"/assets
|
||||
fi
|
||||
|
||||
mkdir "$APP_ANDROID_ROOT"/assets
|
||||
|
||||
# copy resources
|
||||
for file in "$APP_ROOT"/Resources/*
|
||||
do
|
||||
if [ -d "$file" ]; then
|
||||
cp -rf "$file" "$APP_ANDROID_ROOT"/assets
|
||||
fi
|
||||
|
||||
if [ -f "$file" ]; then
|
||||
cp "$file" "$APP_ANDROID_ROOT"/assets
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$buildexternalsfromsource" ]]; then
|
||||
echo "Building external dependencies from source"
|
||||
set -x
|
||||
"$NDK_ROOT"/ndk-build -j 4 -C "$APP_ANDROID_ROOT" $* \
|
||||
"NDK_MODULE_PATH=${PLUGIN_ROOT}/publish:${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/source"
|
||||
else
|
||||
echo "Using prebuilt externals"
|
||||
set -x
|
||||
"$NDK_ROOT"/ndk-build -j 4 -C "$APP_ANDROID_ROOT" $* \
|
||||
"NDK_MODULE_PATH=${PLUGIN_ROOT}/publish:${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt"
|
||||
fi
|
|
@ -0,0 +1,24 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := game_shared
|
||||
|
||||
LOCAL_MODULE_FILENAME := libgame
|
||||
|
||||
LOCAL_SRC_FILES := hellocpp/main.cpp \
|
||||
../../Classes/AppDelegate.cpp \
|
||||
../../Classes/HelloWorldScene.cpp \
|
||||
../../Classes/MyShareManager.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
|
||||
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static \
|
||||
PluginTwitterStatic \
|
||||
PluginProtocolStatic
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
$(call import-module,cocos2dx) \
|
||||
$(call import-module,plugins/twitter/android) \
|
||||
$(call import-module,protocols/android)
|
|
@ -0,0 +1,2 @@
|
|||
APP_STL := gnustl_static
|
||||
APP_CPPFLAGS += -frtti
|
|
@ -0,0 +1,47 @@
|
|||
#include "AppDelegate.h"
|
||||
#include "platform/android/jni/JniHelper.h"
|
||||
#include "PluginJniHelper.h"
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#include "HelloWorldScene.h"
|
||||
|
||||
#define LOG_TAG "main"
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||
|
||||
using namespace cocos2d;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
{
|
||||
JniHelper::setJavaVM(vm);
|
||||
PluginJniHelper::setJavaVM(vm);
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
|
||||
{
|
||||
if (!CCDirector::sharedDirector()->getOpenGLView())
|
||||
{
|
||||
CCEGLView *view = CCEGLView::sharedOpenGLView();
|
||||
view->setFrameSize(w, h);
|
||||
|
||||
AppDelegate *pAppDelegate = new AppDelegate();
|
||||
CCApplication::sharedApplication()->run();
|
||||
}
|
||||
else
|
||||
{
|
||||
ccDrawInit();
|
||||
ccGLInvalidateStateCache();
|
||||
|
||||
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
|
||||
CCTextureCache::reloadAllTextures();
|
||||
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
|
||||
CCDirector::sharedDirector()->setGLDefaultValues();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
|
@ -0,0 +1,15 @@
|
|||
# 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-8
|
||||
android.library.reference.1=../../../../cocos2dx/platform/android/java
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">HelloSocial</string>
|
||||
</resources>
|
|
@ -0,0 +1,43 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
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 org.cocos2dx.helloSocial;
|
||||
|
||||
import org.cocos2dx.lib.Cocos2dxActivity;
|
||||
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
|
||||
import org.cocos2dx.plugin.PluginWrapper;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
public class HelloSocial extends Cocos2dxActivity{
|
||||
|
||||
protected void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
PluginWrapper.init(this);
|
||||
PluginWrapper.setGLSurfaceView(Cocos2dxGLSurfaceView.getInstance());
|
||||
}
|
||||
|
||||
static {
|
||||
System.loadLibrary("game");
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue