Cocos2d-x上からTwitterにツイートする

ゲームのスコアなどをツイートする機能が欲しかったので、試してみました。

iOSはTWTweetComposeViewControllerを表示(許可されていない場合はブラウザを起動してWebのツイート画面を表示)、
AndroidはURLを指定してIntentから起動するようにします。

今回使用したバージョン

  • cocos2d-2.0-x-2.0.4

tks2.net - このウェブサイトは販売用です! - 講演 依頼 開発 イラスト ウェブ 作成 ソフトウェア デザイン リソースおよび情報を参考にさせていただきました。(ほとんど真似です。。。)

  • NativeCodeLauncherという名前に変えていますが、BrowserLauncherという名前でも問題なく動きます。
  • Android側のJavaコードはCocos2dxActivityを継承したOkahiroCocos2dXクラスに置いています。

実装
NativeCodeLauncher.h

namespace Cocos2dExt {
    class NativeCodeLauncher
    {
    public:
		static void openTweetDialog(char const *tweet);
    };
}

NativeCodeLauncher.mm

static void static_openTweetDialog(const char* tweet)
{
	[NativeCodeLauncher openTweetDialog:[NSString stringWithUTF8String:tweet]];
}

namespace Cocos2dExt
{
	void NativeCodeLauncher::openTweetDialog(const char *tweet)
	{
		static_openTweetDialog(tweet);
	}
}

NativeCodeLauncher_objc.h

@interface NativeCodeLauncher : NSObject

+(void)openTweetDialog:(NSString *)tweet;

@end

NativeCodeLauncher_objc.m

@implementation NativeCodeLauncher

+(void)openTweetDialog:(NSString *)tweet
{
	if([TWTweetComposeViewController canSendTweet])
	{
		AppController *appController = (AppController *)[UIApplication sharedApplication].delegate;
		TWTweetComposeViewController *tweetController = [[TWTweetComposeViewController alloc]init];
		[tweetController setInitialText:tweet];
		
		[appController.viewController presentModalViewController:tweetController animated:YES];
	}
	else
	{
		tweet = [NSString stringWithFormat:@"http://twitter.com/home?status=%@",tweet];
		tweet = [tweet stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
		NSURL *url = [NSURL URLWithString:tweet];
		[[UIApplication sharedApplication] openURL:url];
	}
}

@end

NativeCodeLauncher.cpp

namespace Cocos2dExt
{
	void NativeCodeLauncher::openTweetDialog(char const* tweet)
	{
		openTweetDialogJNI(tweet);
	}
}

NativeCodeLauncherJni.h

extern "C"
{
	extern void openTweetDialogJNI(char const* tweet);
}

NativeCodeLauncherJni.cpp

...

//#define  CLASS_NAME "org/cocos2dx/lib/Cocos2dxActivity"
#define CLASS_NAME "jp/milt/okahiro/OkahiroCocos2dX"

...

extern "C"
{

...

	void openTweetDialogJNI(char const* tweet)
	{
		JniMethodInfo methodInfo;
        
		if (!getStaticMethodInfo(methodInfo, "openTweetDialog", "(Ljava/lang/String;)V"))
		{
			return;
		}
        
		jstring stringArg = methodInfo.env->NewStringUTF(tweet);
		methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg);
		methodInfo.env->DeleteLocalRef(stringArg);
		methodInfo.env->DeleteLocalRef(methodInfo.classID);
	}
}

OkahiroCocos2dX.java

public class OkahiroCocos2dX extends Cocos2dxActivity{

	private static Activity me = null; // 追加
	
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		
		me = this; // 追加
	}
	
    static {
         System.loadLibrary("game");
    }
    
    // JNIから呼び出すメソッド
    public static void openTweetDialog(String tweet)
    {
    	String url = String.format("http://twitter.com/home?status=%s", tweet);
    	url = url.replaceAll("#", "%23");
    	
    	Intent i = new Intent(Intent.ACTION_VIEW,Uri.parse(url));
        me.startActivity(i);
    }
}

ここまででOKです。
最後のJavaで"#"を"%23"に置き換えていますが、これがないとハッシュタグがうまく渡りませんでした。


呼び出し
Cocos2d-Xのコードから呼び出す場合は1行でOKです。

Cocos2dExt::NativeCodeLauncher::openTweetDialog("テストツイート #ハッシュタグ http://d.hatena.ne.jp/okahiro_p/");

結果
Android
アプリケーションを選択

twiccaを選んだ場合

chromeを選んだ場合

iOS
TWTweetComposeViewControllerの場合

ブラウザの場合