LoginSignup
21
8

More than 5 years have passed since last update.

Android端末にGetWildを歌わせる

Posted at

GetWild Advent Calendar 2016の6日目です!!

はじめに

このカレンダーに参加を決めて何を書くか考えている時に、パッと浮かんだのはこちらの記事でした!

そこで、同じようにAndroid端末が盗まれそうになったらできないかなーと思い、Wearと連携させることで実現できるのではないかと開発を始めました。

概要

  • AndroidMobileに接続されているWearから歌をリクエストするとMobileが歌います
  • AndroidMobileがWearから離れすぎて接続が切れるとMobileが歌います

動画

pic.twitter.com/pwUvb6jc5G

— futabooo (@futabooo) 2016年12月4日

コード

Mobile側

Mobile側で特定のServiceを起動している状態でのみ歌うようにします。
ServiceがWearからのMessageを受け取れるようにManifestに下記を追加します。

AndroidManifest.xml
<service android:name=".GetWildListenerService">
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/>
        <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
            <data
                android:host="*"
                android:scheme="wear"/>
    </intent-filter>
</service>

dataタグの中ではoptionとしてandroid:pathPrefix="/prefix"も使えるので、もっと細かいことがしたい場合は使えそうです。
WearableListenerService

GetWildListenerServiceはこんな感じです。
歌うときだけ音量MAXにしています。
onPeerDisconnectedonMessageReceivedがそれぞれMobileとWearの接続が切れたとき、Messageを受け取った時に呼ばれるメソッドです。

GetWildListenerService.java
public class GetWildListenerService extends WearableListenerService {

    private TextToSpeech tts;

    private AudioManager audioManager;
    private int originalVol;
    private int maxVol;

    @Override
    public void onCreate() {
        super.onCreate();

        // 歌う時に音量MAXにするために
        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        originalVol = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        maxVol = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                Log.d(TAG, "tts onInit");
            }
        });
    }

    @Override
    public void onDestroy() {
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, originalVol, 0);
        super.onDestroy();
    }

    @Override
    public void onPeerDisconnected(Node node) {
        super.onPeerDisconnected(node);
        Log.d(TAG, "onPeerDisconnected");
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVol, 0);
        startSing();
    }

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        super.onMessageReceived(messageEvent);
        Log.d(TAG, "onMessageReceived");
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVol, 0);
        startSing();
    }

    private void startSing() {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        if (!sp.getBoolean("isEnable", false)) {
            return;
        }

        getWildAndTough(Locale.ENGLISH, getString(R.string.lyrics_get_wild_and_tough));
        getWildAndTough(Locale.JAPAN, getString(R.string.lyrics_1));
        getWildAndTough(Locale.ENGLISH, getString(R.string.lyrics_get_wild_and_tough));
        getWildAndTough(Locale.JAPAN, getString(R.string.lyrics_2));
        getWildAndTough(Locale.ENGLISH, getString(R.string.lyrics_get_chance_and_luck));
        getWildAndTough(Locale.JAPAN, getString(R.string.lyrics_3));
        getWildAndTough(Locale.ENGLISH, getString(R.string.lyrics_get_chance_and_luck));
        getWildAndTough(Locale.JAPAN, getString(R.string.lyrics_4));
    }

    private void getWildAndTough(Locale locale, String string) {
        // 日本語遅すぎなので歌っぽくするために
        if (locale == Locale.JAPAN) {
            tts.setSpeechRate(2.0f);
        } else if (locale == Locale.ENGLISH) {
            tts.setSpeechRate(1.0f);
        }

        tts.setLanguage(locale);
        tts.speak(string, TextToSpeech.QUEUE_ADD, null, "1");
    }
}

Wear側

Waer側からはMobileに対してメッセージを送る実装をします。
sendMessage"/get-wild"がAndroidManifestでoptionとして追加可能なprefix部分です。

WearMainActivity.java
public class WearMainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.wear_activity_main);

        WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                Button button = (Button) stub.findViewById(R.id.button);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                // Mobile側へメッセージを送る
                                GoogleApiClient client = new GoogleApiClient.Builder(getApplicationContext()).addApi(Wearable.API).build();
                                client.blockingConnect(100, TimeUnit.MILLISECONDS);
                                NodeApi.GetConnectedNodesResult result = Wearable.NodeApi.getConnectedNodes(client).await();
                                List<Node> nodes = result.getNodes();
                                if (nodes.size() > 0) {
                                    client.blockingConnect(100, TimeUnit.MILLISECONDS);
                                    Wearable.MessageApi.sendMessage(client, nodes.get(0).getId(), "/get-wild", null);
                                    client.disconnect();
                                }
                                client.disconnect();
                            }
                        }).start();
                    }
                });
            }
        });
    }
}

おわりに

どれぐらいの距離を離れると接続が切れるのか試すことができませんでしたorz
Bluetoothの接続可能な距離って結構長いんですねw
TextToSpeechのチューニングしだいでもっと歌っぽくできそうです。

今回作ったものはここに置いてあります
https://github.com/futabooo/getwild

参考

https://developer.android.com/reference/android/speech/tts/TextToSpeech.html
https://developer.android.com/training/wearables/data-layer/messages.html

21
8
1

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
21
8