はじめに
今更感が拭えませんが、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と指定されており、アプリのプロジェクトとバージョンを揃えたかったためです。)
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
をコピーして使用することにします。ただし、SmartExtensionUtils
はSmartExtensionAPI
に依存関係があるため、dependencies
にその点を追記する必要があります。
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('~')
の役割です。
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をクリックするだけで大丈夫なはずです。
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に画面を描画したり、入力を取得したりします。そのため、Service
とBroadcastReceiver
の実装、AndroidManifest.xml
への修正が必要となります。
Service
はSDKに含まれるExtensionService
を継承して実装します。今回は準備ということで、特に細かい実装はしません。クラス名はWatchExtensionService
としました。
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
に送り付ける実装になっています。基本的に、このクラスはこれ以上実装することはありません。
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);
}
}
ここで実装したService
とBroadcastReceiver
を有効にするため、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に表示する画面の実装を行っていきます。この点に関してはまた今後書いていきたいと思います。