【Unity / 2020年版】SocialConnectorを使ってツイッター共有のみ実装する

Unity
マイケル
マイケル
さあアプリにSNS共有ボタンを追加するぞ〜〜!
エレキベア
エレキベア
急クマね〜〜〜
前つくったアプリにもついてた気がするクマ
マイケル
マイケル
そう、実は前作ったゴーゴーゴロヤンにも
下の画像のように共有ボタンはつけていたんだ。
IMG 6867
↑ゴーゴーゴロヤンのSNS共有
マイケル
マイケル
だけどこれは共有する機能が多すぎるし
ぶっちゃけ共有はTwitterだけでいいと思うんだよね
エレキベア
エレキベア
確かにこれだけ種類があると選ぶ手間がかかるクマね
マイケル
マイケル
そうなんだ、テストも大変だしね・・・
マイケル
マイケル
というわけで今回はTwitterだけの共有機能を実装してみるよ!
Screenshot 2020 08 18 6 48 01
↑Twitterのみの共有機能を追加する
エレキベア
エレキベア
やったるクマ〜〜〜〜
スポンサーリンク

ツイッター共有の実装

マイケル
マイケル
UnityでSNS共有の有名なライブラリといえば
SocialConnectorだね。

最新版SocialConnector:

Social Connector v0.5.0

エレキベア
エレキベア
これはなかなか便利クマね
マイケル
マイケル
そう、だけど最新版をそのまま使うと
ゴーゴーゴロヤンのように複数の共有画面を開く処理になってしまうんだ。
マイケル
マイケル
そのため、下記サイトを参考にさせていただいて過去バージョンをインポートする方法で実装してみようと思います!

参考サイト:

UnityでTwitterだけのシェアボタンを作る方法(画像付き)

エレキベア
エレキベア
過去バージョンでは共有機能が選べるようになっているクマね
マイケル
マイケル
そのとおり!
さっそく実装してみよう!

過去バージョンをインポート

マイケル
マイケル
記事で紹介されている通り、
下記のバージョンをインポートします!

過去バージョンSocialConnector:

Social Connector v0.2.9

マイケル
マイケル
そしてインポートした後に何箇所か修正する点がありますが、
基本的に記事の通り実装すれば大丈夫です!


・SocialConnector.mmの編集
・Platform settingsの設定

エレキベア
エレキベア
この記事はわかりやすく説明してくれてるクマね

共有スクリプトの作成

マイケル
マイケル
そして共有処理のスクリプトに関しては、
最終的には下記のようになりました。
public class GameSceneManager : MonoBehaviour
{

・・・略・・・

    // 共有ボタン押下時
    public void PushShareButton()
    {
        // 共有画面を表示
        StartCoroutine(_Share());
    }

・・・略・・・

    // SNS共有処理
    public IEnumerator _Share()
    {
        string imgPath = Application.persistentDataPath + "/image.png";

        // 前回のデータを削除
        File.Delete(imgPath);
        // 削除が完了するまで待機
        while (true)
        {
            if (!File.Exists(imgPath)) break;
            yield return null;
        }

        // スクリーンショットを取得
        ScreenCapture.CaptureScreenshot("image.png");
        // 撮影画像の書き込みが完了するまで待機
        while (true)
        {
            if (File.Exists(imgPath)) break;
            yield return null;
        }
        // 撮影画像の保存処理のため、1フレーム待機
        yield return new WaitForEndOfFrame();

        // 投稿する
        string tweetText = "【ツイート内容】";
        string tweetURL = "【ツイートURL】";
        SocialConnector.PostMessage(SocialConnector.ServiceType.Twitter, tweetText, tweetURL, imgPath);
    }

・・・略・・・

}
マイケル
マイケル
前のスクショの削除 -> 新しいスクショの保存
の処理がそれぞれ終わるまで待機するようにしています。
エレキベア
エレキベア
保存や削除を行うのに若干のラグが発生してしまうクマね
マイケル
マイケル
これで基本的に完了ですが、
一点、Android端末で画像が切り替わらない時がある
という不具合が発生しました。
マイケル
マイケル
最新版では同じスクリプトで処理できたため、
何か足りていない処理があるのかどうか・・・。
原因を調査してみました!

不具合の原因

マイケル
マイケル
不具合の原因を最新版のSocialConnectorの実装と見比べながら調べたところ・・・
マイケル
マイケル
どうやら原因は、AndroidではAPI24からFileProviderを使用して画像の保存を行うようになっており、その対応が入っていないことのようでした。
エレキベア
エレキベア
権限の仕様が変わったのクマね


・SocialConnector.csの修正
・AndroidManifest.xmlの修正

マイケル
マイケル
最新版では上記の修正がされていたため、
同じ修正を入れてあげます!

SocialConnector.csの修正

マイケル
マイケル
まずはスクリプトの修正から!
インポートしたSocialConnector.csの105行目付近の下記処理をコメントアウトし
修正しましょう!
----------------------------------------------------------------------------------------------
            // *** UPDATE START ***
            //if (!string.IsNullOrEmpty(textureUrl))
            //{
            //    var uri = new AndroidJavaClass("android.net.Uri");
            //    var file = new AndroidJavaObject("java.io.File", textureUrl);
            //    intent.Call<AndroidJavaObject>("putExtra", "android.intent.extra.STREAM", uri.CallStatic<AndroidJavaObject>("fromFile", file));
            //}
            if (!string.IsNullOrEmpty(textureUrl))
            {

                var versionClazz = new AndroidJavaClass("android.os.Build$VERSION");
                var apiLevel = versionClazz.GetStatic<int>("SDK_INT");
                AndroidJavaObject uri;
                if (24 <= apiLevel)
                {
                    var context = activity.Call<AndroidJavaObject>("getApplicationContext");
                    var fileProvider = new AndroidJavaClass("android.support.v4.content.FileProvider");
                    var file = new AndroidJavaObject("java.io.File", textureUrl);
                    uri = fileProvider.CallStatic<AndroidJavaObject>("getUriForFile", context, Application.identifier + ".fileprovider", file);
                }
                else
                {
                    var uriClazz = new AndroidJavaClass("android.net.Uri");
                    var file = new AndroidJavaObject("java.io.File", textureUrl);
                    uri = uriClazz.CallStatic<AndroidJavaObject>("fromFile", file);
                }
                intent.Call<AndroidJavaObject>("putExtra", "android.intent.extra.STREAM", uri);
            }
            // *** UPDATE END ***
----------------------------------------------------------------------------------------------

AndroidManifest.xmlの作成

マイケル
マイケル
そしてFileProviderを使用できるよう、
AndroidManifest.xml を Assets/Plugins/Android 配下
filepaths.xml を Assets/Plugins/Android/res/xml 配下
にそれぞれ作成しましょう!


・AndroidManifest.xml

Screenshot 2020 08 17 12 26 23
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:theme="@style/UnityThemeSelector"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name">
        <activity
            android:label="@string/app_name"
            android:name="com.unity3d.player.UnityPlayerActivity">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
        </activity>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="【自身のパッケージ名】.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"></meta-data>
        </provider>
    </application>
</manifest>


※2021/2/22 補足
一部環境では「android.support.v4.content.FileProvider」は使えず、
「androidx.core.content.FileProvider」を使うとうまく動作するようです。
(rygrep 様からの情報提供、詳細はコメント欄参照。)


・filePaths.xml

Screenshot 2020 08 17 12 26 35
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="unity_persistent_data_path" path="." />
</paths>
マイケル
マイケル
AndroidManifestの【自身のパッケージ名】については、
自身のアプリのパッケージ名に置き換えましょう!
エレキベア
エレキベア
ここまででちゃんとツイートできたクマ〜〜〜
マイケル
マイケル
以上でTwitter共有処理の実装は完了です!

おわりに

マイケル
マイケル
というわけで今回はTwitter共有の実装でした!
どうだったかな?
エレキベア
エレキベア
なんだかんだシンプルでいいクマね〜〜〜
マイケル
マイケル
Tiwitter機能以外にも Facebook / LINE のみ
の実装も可能なので、是非やってみましょう!
マイケル
マイケル
それでは今日はこの辺で!
アデュー!!
エレキベア
エレキベア
クマ〜〜〜〜〜〜〜

コメント

  1. rygrep より:

    記事参考にさせていただき、
    キャプチャ付きのツイート機能実装できました。
    ありがとうございます。

    1点、自分の環境だと
    android.support.v4.content.FileProvider
    は使えないようで、代わりに
    androidx.core.content.FileProvider
    を使うとうまくいきました。
    同じような人がいるかもしれないので、書いておきますね。

    ↓のブログを参考にしました。
    https://waken.hatenablog.com/entry/2019/10/24/115035

    • マイケル より:

      コメント及び情報提供ありがとうございます!
      念のため記事にも補足として追記させていただきました。
      今後もお役に立てれば幸いです!