LoginSignup
2
2

More than 5 years have passed since last update.

AndroidアプリをSONY SmartWatch 2に対応させる準備

Posted at

はじめに

今更感が拭えませんが、SONY SmartWatch 2への対応に関する記事です。ここではGradleを用いたAndroidアプリのプロジェクトにSONY SmartWatch 2 (以下SW2)のSDKを導入する手順を示します。SW2のSDK自体は次に示す開発者向けのページに従って導入されているものとします。
Detailed instructions | Sony Developer World

開発環境にはIntelliJ IDEA 14を使用し、コンパイルおよびターゲットのSDKのバージョンは19 (Android 4.4.2)としています。SW2のSDKがAndroid 4.4.2 'API 19)の項目に表示されているため、最新バージョンの22ではなく19を指定しています。アプリのモジュール名はappとしています。

SDKのコピー

上記の開発者向けページに従ってSW2のSDKを導入すると、AndroidのSDK内のadd-ons\addon-sony_add-on_sdk_3_0-sony-19\samplesにAPIを含んだソースコードが展開されます。必要なファイルはSmartExtensions内のSmartExtensionAPIおよびSmartExtensionUtilsです。プロジェクト内にsdkフォルダを作成し、この2つのフォルダをその中にコピーします。(プロジェクトフォルダを散らかさない目的でsdkフォルダに入れているだけで、プロジェクトルートでもかまいません。)

Gradleファイルの用意

SmartExtensionAPIには既にbuild.gradleが用意されていますが、コンパイルに使用するSDKとビルドツールのバージョンをAndroid 4.4.2のものに変更しておきます。(元のバージョンが18と指定されており、アプリのプロジェクトとバージョンを揃えたかったためです。)

sdk\SmartExtensionAPI\build.gradle
apply plugin: 'android-library'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
}

android {
    compileSdkVersion 19                            // 変更
    buildToolsVersion "19.1.0"                      // 変更

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

    }
}

一方で、SmartExtensionUtilsにはbuild.gradleは用意されていません。SmartExtensionAPIと同じ構成なので、上記のbuild.gradleをコピーして使用することにします。ただし、SmartExtensionUtilsSmartExtensionAPIに依存関係があるため、dependenciesにその点を追記する必要があります。

sdk\SmartExtensionUtils\build.gradle
apply plugin: 'android-library'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':SmartExtensionAPI')           // 追加
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.1.0"

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

    }
}

ルートプロジェクトに追加

つづいて、この2つのモジュールを追加するためルートプロジェクトのsettings.gradleを書き換えます。モジュールを追加するにはincludeにモジュール名を追記するだけで大丈夫ですが、ルートではなくsdkフォルダ内にコピーしているため、プロジェクトフォルダを別途指定する必要があります。それが2、3行目にあるproject('~').projectDir = new File('~')の役割です。

settings.gradle
include ':app', ':SmartExtensionAPI', ':SmartExtensionUtils'                     // 変更
project(':SmartExtensionAPI').projectDir = new File('sdk/SmartExtensionAPI')     // 追加
project(':SmartExtensionUtils').projectDir = new File('sdk/SmartExtensionUtils') // 追加

最後に、SW2のSDKをアプリで使用するために、アプリのbuild.gradleに依存関係を追記して、Gradleを同期させます。Intellij IDEAなら上に表示されるSync Nowをクリックするだけで大丈夫なはずです。

app\build.gradle
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.1'
    }
}
apply plugin: 'com.android.application'

repositories {
    jcenter()
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.1.0"

    defaultConfig {
        applicationId "net.leak4mk0.sw2sampleapplication.app"
        minSdkVersion 9
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_6
        targetCompatibility JavaVersion.VERSION_1_6
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':SmartExtensionUtils')                                                    // 追加
    compile 'com.android.support:support-v4:19.1.0'
    compile 'com.android.support:appcompat-v7:19.1.0'
}

実装の準備

プロジェクト側の準備は完了しました。次は実装側の準備を行います。SW2のSDKはServiceを立ち上げ、SW2のホストアプリケーションとIntentを利用して通信し、SW2に画面を描画したり、入力を取得したりします。そのため、ServiceBroadcastReceiverの実装、AndroidManifest.xmlへの修正が必要となります。

ServiceはSDKに含まれるExtensionServiceを継承して実装します。今回は準備ということで、特に細かい実装はしません。クラス名はWatchExtensionServiceとしました。

app\src\main\...\WatchExtensionService.java
package net.leak4mk0.sw2sampleapplication.app;

import com.sonyericsson.extras.liveware.extension.util.ExtensionService;
import com.sonyericsson.extras.liveware.extension.util.registration.RegistrationInformation;

public class WatchExtensionService extends ExtensionService {
    @Override
    protected RegistrationInformation getRegistrationInformation() {
        return null;
    }

    @Override
    protected boolean keepRunningWhenConnected() {
        return false;
    }
}

さらにBroadcastReceiverを継承してWatchExtensionReceiverクラスを作成します。受信したIntentをすべて上で作成したWatchExtensionServiceに送り付ける実装になっています。基本的に、このクラスはこれ以上実装することはありません。

app\src\main\...\WatchExtensionReceiver.java
package net.leak4mk0.sw2sampleapplication.app;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class WatchExtensionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        intent.setClass(context, WatchExtensionService.class);
        context.startService(intent);
    }
}

ここで実装したServiceBroadcastReceiverを有効にするため、AndroidManifest.xmlに修正を加えます。

app\src\main\AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.leak4mk0.sw2sampleapplication.app" >

    <!-- 追加 -->
    <uses-permission android:name="com.sonyericsson.extras.liveware.aef.EXTENSION_PERMISSION"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 追加 -->
        <service android:name=".service.WatchExtensionService"/>
        <service android:name="com.sonyericsson.extras.liveware.extension.util.TunnelService">
            <intent-filter>
                <action android:name="com.sonyericsson.extras.liveware.aef.tunnel.action.BIND"/>
            </intent-filter>
        </service>

        <!-- 追加 -->
        <receiver android:name=".service.WatchExtensionReceiver">
            <intent-filter>
                <action android:name="com.sonyericsson.extras.liveware.aef.registration.EXTENSION_REGISTER_REQUEST"/>
                <action android:name="com.sonyericsson.extras.liveware.aef.registration.ACCESSORY_CONNECTION"/>
                <action android:name="android.intent.action.LOCALE_CHANGED"/>
                <action android:name="com.sonyericsson.extras.liveware.aef.notification.VIEW_EVENT_DETAIL"/>
                <action android:name="com.sonyericsson.extras.liveware.aef.notification.REFRESH_REQUEST"/>
                <action android:name="com.sonyericsson.extras.aef.widget.START_REFRESH_IMAGE_REQUEST"/>
                <action android:name="com.sonyericsson.extras.aef.widget.STOP_REFRESH_IMAGE_REQUEST"/>
                <action android:name="com.sonyericsson.extras.aef.widget.ONTOUCH"/>
                <action android:name="com.sonyericsson.extras.liveware.extension.util.widget.scheduled.refresh"/>
                <action android:name="com.sonyericsson.extras.aef.control.START"/>
                <action android:name="com.sonyericsson.extras.aef.control.STOP"/>
                <action android:name="com.sonyericsson.extras.aef.control.PAUSE"/>
                <action android:name="com.sonyericsson.extras.aef.control.RESUME"/>
                <action android:name="com.sonyericsson.extras.aef.control.ERROR"/>
                <action android:name="com.sonyericsson.extras.aef.control.KEY_EVENT"/>
                <action android:name="com.sonyericsson.extras.aef.control.TOUCH_EVENT"/>
                <action android:name="com.sonyericsson.extras.aef.control.SWIPE_EVENT"/>
                <action android:name="com.sonyericsson.extras.aef.control.OBJECT_CLICK_EVENT"/>
                <action android:name="com.sonyericsson.extras.aef.control.LIST_REFERESH_REQUEST"/>
                <action android:name="com.sonyericsson.extras.aef.control.LIST_REQUEST_ITEM"/>
                <action android:name="com.sonyericsson.extras.aef.control.LIST_ITEM_CLICK"/>
                <action android:name="com.sonyericsson.extras.aef.control.LIST_ITEM_SELECTED"/>
                <action android:name="com.sonyericsson.extras.aef.control.MENU_ITEM_SELECTED"/>
                <action android:name="com.sonyericsson.extras.aef.control.MENU_SHOW"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

さいごに

以上で実装の直前まで準備できました。ここからはWatchExtensionServiceクラスに手を入れて、ホストアプリケーションへのアプリの登録やSW2に表示する画面の実装を行っていきます。この点に関してはまた今後書いていきたいと思います。

2
2
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
2
2