LoginSignup
19
21

More than 5 years have passed since last update.

Unityからネィティブプラグインを使いTwitterに投稿して、ツィートしたら何かを行う

Posted at

引き続きネィティブ周りのど素人が苦戦しながら調べてみました。
基本的に前回の続きです。
環境なども同じです。

どういうことか

筆者はゲーム開発会社にて、ご飯を食べているので
「Twitterでつぶやいてくれたら何かあげるよ!」
みたいな感じが実装したかったのです。

Twitterに投稿するサンプルはググれば結構でてくるのですが
そこでツィートしたか?していないのか?の検知がなかなか見つからなかったので実装してみました。
ちなみにiOSの方法はググれば結構でてきたので、それを参考にしています。
苦戦したのはほとんどがAndroidだったりします。

実装

Unity

Hierarchy、Game画面こんな感じです。
「Button」が「ツィートする」のボタン
「CallBackText」が「ツィートしてません」のテキスト
「TwitterController」が処理を行うスクリプト
キャプチャ.PNG

TwitterController
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Runtime.InteropServices;

public class TwitterController : MonoBehaviour {
    public Text callBackText;

#if UNITY_IOS
    [DllImport("__Internal")]
    static extern void Twitter();
#endif

    public void OnTwitter()
    {
#if UNITY_EDITOR
        Debug.Log("UnityEditorでは使用できません");
#elif UNITY_ANDROID
        // パッケージ名 + クラス名を引数にする.
        AndroidJavaClass plugin = new AndroidJavaClass("okuhiiro.twitter.Twitter");
        // そのクラスのメソッドを指定する.
        // 引数があるの場合は、第2引数以降がそのメソッドの第1引数に該当する.
        plugin.CallStatic("LaunchTwitterActivity");

#elif UNITY_IOS
        Twitter();
#endif
    }

    public void OnTwitterResult(string str)
    {
        callBackText.text = str;
    }
}

Android

javaソース

UnityからCallされるクラスです。
パッケージ名 + クラス名は適宜置き換えてください。

Twitter.java
package okuhiiro.twitter;

import android.app.Activity;
import android.content.Intent;
import com.unity3d.player.UnityPlayer;

public class Twitter {
    // TwitterのActivityを起動する.
    public static void LaunchTwitterActivity() {
        Intent intent = new Intent();
        final Activity activity = UnityPlayer.currentActivity;

        intent.setAction(Intent.ACTION_MAIN);
        intent.setClassName(activity, "okuhiiro.twitter.TwitterActivity");

        activity.startActivity(intent);
    }
}

上記のjavaからCallされるActivityクラスです。
startActivityForResultを使わないとツィートしたかどうか検知できなかったので
Activityを起動するという方法をとっています。

package okuhiiro.twitter;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;

import com.unity3d.player.UnityPlayer;

import java.util.List;

public class TwitterActivity extends Activity {

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);

        tweet();
    }

    // ツィートする.
    private void tweet() {
        // ツィートするデフォルトの文字列.
        String s = "hogehoge #hashtag" + System.getProperty("line.separator") + "http://aaa";

        Intent tweetIntent = new Intent(Intent.ACTION_SEND);
        tweetIntent.putExtra(Intent.EXTRA_TEXT, s);
        tweetIntent.setType("text/plain");

        // Androidにインストールされているパッケージをリストで取得?.
        PackageManager packManager = getPackageManager();
        List<ResolveInfo> resolvedInfoList = packManager.queryIntentActivities(
                tweetIntent,
                PackageManager.MATCH_DEFAULT_ONLY
        );

        // Twitterのパッケージ + クラス名をセットする.
        boolean resolved = false;
        for(ResolveInfo resolveInfo: resolvedInfoList){
            if(resolveInfo.activityInfo.packageName.startsWith("com.twitter.android")){
                tweetIntent.setClassName(
                        resolveInfo.activityInfo.packageName,
                        resolveInfo.activityInfo.name );
                resolved = true;
                break;
            }
        }

        // Twitterアプリがインストールされている場合.
        if(resolved)
        {
            startActivityForResult(tweetIntent, 1);
        }
        // Twitterアプリがインストールされていない場合.
        else
        {
            UnityPlayer.UnitySendMessage("TwitterController", "OnTwitterResult", "アプリがないよ");
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // ツィートせず.
        if (resultCode == 0)
        {
            UnityPlayer.UnitySendMessage("TwitterController", "OnTwitterResult", "ツィートせず");
        }
        // ツィートした.
        else
        {
            UnityPlayer.UnitySendMessage("TwitterController", "OnTwitterResult", "ツィートしたよ");
        }

        finish();
    }
}

AndroidManifest.xml

Activityを使う場合は記述が必要なようです。
パッケージ名とクラス名は、1文字1句間違いなくいれてください。地味にハマりました... :disappointed_relieved:

UnityのAndroidManifestテンプレートは下記にありました。
C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Apk\AndroidManifest.xml
これに以下の追記を行い、「Plugins」-「Android」以下にコピーしました。
キャプチャ.PNG

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    android:installLocation="preferExternal"
    android:versionCode="1"
    android:versionName="1.0">
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>

    <application
        android:theme="@style/UnityThemeSelector"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:debuggable="true">
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>

        <!-- ここに追加しました -->
        <activity android:name="okuhiiro.twitter.TwitterActivity"
                  android:label="TwitterActivity"
                  android:configChanges="keyboard|keyboardHidden|orientation">
        </activity>
    </application>
</manifest>

iOS

Androidと比べてシンプルです。
下記ファイルを「プラグインを配置するフォルダを作成」で作成した「iOS」の下にいれます。

twitter.mm
#import <QuartzCore/QuartzCore.h>
#import "Social/Social.h"

extern "C" {
    void Twitter() {
        NSString *_text = @"hogehoge #hashtag";
        NSString *_url = @"http://aaaa";

        SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];

        composeViewController.completionHandler = ^(SLComposeViewControllerResult res) {
            if (res == SLComposeViewControllerResultCancelled) {
                UnitySendMessage("TwitterController", "OnTwitterResult", "ツィートせず");
            }else if (res == SLComposeViewControllerResultDone) {
                UnitySendMessage("TwitterController", "OnTwitterResult", "ツィートしたよ");
            }
            [composeViewController dismissViewControllerAnimated:YES completion:nil];
        };

        if ([_text length] != 0) {
            [composeViewController setInitialText:_text];
        }

        if ([_url length] != 0) {
            [composeViewController addURL:[NSURL URLWithString:_url]];
        }

        [UnityGetGLViewController() presentViewController:composeViewController animated:YES completion:nil];
    }
}

XCode側で下記frameworkが必要です。
スクリーンショット 2016-09-06 11.47.25.png

表示

Android

「ツィートする」ボタンの押下。アプリがインストールされていない場合。
真っ白な画面に...。ちょっとここはすぐActivity終了するなりしたほうが良さそうです。

戻るボタン押下後

「ツィートする」ボタンの押下。アプリがインストールされているがログインしていない場合。

「ツィートする」ボタンの押下。アプリがインストールされていてログインしている場合。

ツィートせず戻ってきた場合。

ツィートしてきた場合。

iOS

iOSの場合は、以下パターンで見てみました。
- アプリがインストールされていない + Twitterとアカウントが結びついていない
- アプリがインストールされている + Twitterとアカウントが結びついていない
- アプリがインストールされている + Twitterとアカウントが結びついている

「ツィートする」ボタンの押下。
アプリがインストールされていない + Twitterとアカウントが結びついていない場合。

「キャンセル」ボタンの押下。

「ツィートする」ボタンの押下。
アプリがインストールされている + Twitterとアカウントが結びついていない場合。

「OK」ボタンの押下。「投稿」ボタンが押せない感じになっていました。

「キャンセル」ボタンの押下。

「ツィートする」ボタンの押下。
アプリがインストールされている + Twitterとアカウントが結びついている場合。

「投稿」ボタンの押下。

19
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
21