もう、Ruputerは卒業だぁ! SmartWatchアプリを作ろう/すまべん関西#20
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

もう、Ruputerは卒業だぁ! SmartWatchアプリを作ろう/すまべん関西#20

on

  • 6,408 views

 

Statistics

Views

Total Views
6,408
Views on SlideShare
4,726
Embed Views
1,682

Actions

Likes
2
Downloads
9
Comments
0

4 Embeds 1,682

http://d.hatena.ne.jp 1675
http://webcache.googleusercontent.com 5
https://twitter.com 1
https://www.google.co.jp 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

もう、Ruputerは卒業だぁ! SmartWatchアプリを作ろう/すまべん関西#20 Presentation Transcript

  • 1. もう、Ruputerは卒業だぁ!SmartWatchアプリを作ろう たろサ(@momoonga)
  • 2. 2 自己紹介 ご当地名産 太刀重 最近作ったスマホアプリ和歌山県 有田市 丁! 重一 最太刀
  • 3. 内 容(1)SmartWatchについて(2)SmartWatchの開発環境(3)SmartWatch用アプリの作成(4)何、作ろうか?
  • 4. SmartWatch MN2について 余計な話が、いっぱい出てくると思います。 すいません。
  • 5. 5 SmartWatch MN2発売 LiveViewの 後継機 BluetoothAndroid SmartWatch
  • 6. 6SmartWatch MN2発売 4月10日発売 約3時間で売り 切れ!
  • 7. 7SmartWatch MN2発売 4月10日発売 約3時間で売り 切れ!
  • 8. 8SmartWatch MN2発売 2003年5月7日午前 10時より発売、 約15分で売り切れるWristomo(リストモ) NTTドコモのPHS
  • 9. 9 SmartWatch MN2発売 2003年5月7日午前 10時より発売、 約15分で売り切れるちなみに、BTウォッチは結構出ています。 Wristomo(リストモ) NTTドコモのPHS
  • 10. 10 SmartWatch MN2発売 ・BT通信 ・EL液晶 ・着信を振動や音で知らせる ・発信者名の表示する ・腕時計の操作で保留応答や着信 拒否 ・置き忘れ防止(携帯電話と腕時計 がある程度の距離で離れ、双方の リンクが途絶えた場合、腕時計が アラートする) ・着信音のミュート及び解除 ・時刻情報の同期 Testanova(発表のみ発売せず) プログラムできないのが残念
  • 11. 11 SmartWatch MN2発売 ・BT通信 ・EL液晶 ・着信を振動や音で知らせる ・発信者名の表示する ・腕時計の操作で保留応答や着信 プログラムできる 拒否 ・置き忘れ防止(携帯電話と腕時計 腕時計といえば がある程度の距離で離れ、双方の リンクが途絶えた場合、腕時計が アラートする) ・着信音のミュート及び解除 ・時刻情報の同期 Testanova(発表のみ発売せず) プログラムできないのが残念
  • 12. 12 SmartWatch MN2発売 ・赤外線通信 ・シリアル通信 ・モノクロ液晶 ・WPS-DOS搭載 ・プログラムできる [非公開仕様] ・ソフト的にvsync割り込み取得可 ・M/B上にA/D変換端子の有り 元宇宙飛行士の 毛利さんも使っていたRuputer
  • 13. 13 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用SmartWatch
  • 14. 14 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 そうでもなさそうです・・・SmartWatch
  • 15. 15 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mmSmartWatch
  • 16. 16 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mmSmartWatch 確かに小さいです。
  • 17. 17 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mm ・質量:15.5g (リストバンド除く)SmartWatch
  • 18. 18 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mm ・質量:15.5g (リストバンド除く) ・ディスプレイ:1.3インチカラー有機ELディスプレイ (128×128ドット)SmartWatch
  • 19. 19 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mm ・質量:15.5g (リストバンド除く) ・ディスプレイ:1.3インチカラー有機ELディスプレイ (128×128ドット) 128ドット 102ドット 64ドット Ruputer 128ドット SmartWatch SmartWatchカラー有機ELディスプレイは屋外でたいへん見にくいです。
  • 20. 20 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mm ・質量:15.5g (リストバンド除く) ・ディスプレイ:1.3インチカラー有機ELディスプレイ (128×128ドット) ・内蔵電池:リチウムイオン電池(専用充電端子)SmartWatch
  • 21. 21 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mm ・質量:15.5g (リストバンド除く) ・ディスプレイ:1.3インチカラー有機ELディスプレイ (128×128ドット) ・内蔵電池:リチウムイオン電池(専用充電端子)SmartWatch CR2025×2
  • 22. 22 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mm ・質量:15.5g (リストバンド除く) ・ディスプレイ:1.3インチカラー有機ELディスプレイ (128×128ドット) ・内蔵電池:リチウムイオン電池(専用充電端子) ・全面マルチタッチディスプレイ ・加速度センサ3軸 ・振動アラームSmartWatch
  • 23. 23 SmartWatchのスペック ・Android OS 2.3以降のXperia™シリーズ専用 (そうでもなさそうです・・・) ・大きさ:36mm×36mm×8mm ・質量:15.5g (リストバンド除く) ・ディスプレイ:1.3インチカラー有機ELディスプレイ (128×128ドット) ・内蔵電池:リチウムイオン電池(専用充電端子) ・全面マルチタッチディスプレイ ・加速度センサ3軸 ・振動アラームSmartWatch リストモの方が ブルブル
  • 24. SmartWatchの開発環境
  • 25. 25 EDK 2.0のインストールAndroid SDK Managerを使って、EDK 2.0をインストール
  • 26. 26 AVDの作成ウィンドウ>設定の「Android」のところに、ターゲット名 EDK 2.0ができている
  • 27. 27 AVDの作成EDK 2.0(Sony MobileCommunications AB)用AVDが作成できるSD CardはEDK 2.0にあるsdcard.imgを使うフォルダ/android-sdk/add-ons/addon-edk_2_0-sony_ericsson_mobile_communications_ab-10/images/sdcard.img
  • 28. 28AVDの作成作成したAVDには、LiveWare マネージャと、Smart Extendion Emulatorがある
  • 29. 29ASmart Extension Emuの設定 SmartWatchを選ぶ
  • 30. 30Smart Extension SDKのダウンロード Smart Extension SDKを選ぶhttp://developer.sonymobile.com/cws/devworld/search-downloads/docstools/sdk
  • 31. 31 Smart Extension SDKのダウンロードライブラリがソースで入っているSmartExtensionAPI EclipseにインポートしますSmartExtensionUtilsサンプルプログラムソースSampleControlExtension ・ライブラリとして使うSampleNotificationExtension のはUtilsのみです。SampleSensorExtension APIは、Utilsが使ってSampleWidgetExtension います。
  • 32. SmartWatch用 アプリの作成
  • 33. 33 SmartWatchアプリの仕組みサービスとして常駐 SmartWatchアプリ を管理SmartWatch アプリ(1) イベントSmartWatch LiveWare Smart アプリ(2) 画面データ マネージャ WatchSmartWatch Bluetooth アプリ(3) タッチデータ SmartWatchとのやり取り は、すべてLiveWareマネー ジャが行っている
  • 34. 34 SmartWatchアプリの仕組みサービスとして常駐 SmartWatchアプリ を管理 なんと、SmartWatchSmartWatch アプリ(1) は画像しかもらえないSmartWatch イベント LiveWare Smart アプリ(2) 画面データ マネージャ WatchSmartWatch Bluetooth アプリ(3) タッチデータ SmartWatchとのやり取り は、すべてLiveWareマネー ジャが行っている
  • 35. 35 SmartWatchアプリの仕組み 画像のみの送信サービスとして常駐 SmartWatchアプリ を管理SmartWatch アプリ(1) イベントSmartWatch LiveWare Smart アプリ(2) 画面データ マネージャ WatchSmartWatch Bluetooth アプリ(3) タッチデータ SmartWatchとのやり取り は、すべてLiveWareマネー ジャが行っている
  • 36. 36 Manifest<uses-permission android:name="com.sonyericsson.extras.liveware.aef.EXTENSION_PERMISSION" /><intent-filter> <action android:name="android.intent.action.MAIN" /></intent-filter><service android:name="SampleExtensionService" />
  • 37. 37 Manifest<receiver android:name=".ExtensionReceiver" > <intent-filter> <!-- Generic extension intents. --> <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" /> <!-- Notification intents --> <action android:name="com.sonyericsson.extras.liveware.aef.notification.VIEW_EVENT_DETAIL" /> <action android:name="com.sonyericsson.extras.liveware.aef.notification.REFRESH_REQUEST" /> <!-- Widget intents --> <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" /> <!-- Control intents --> <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" /> </intent-filter>
  • 38. 38プログラムの概要
  • 39. 39 プログラムに必要なクラス プログラムには6つのクラスが必要です。・PreferenceActivityクラス   Android本体側での設定等を行うために用いるクラス・RegistrationInformationクラス  LiveWareマネージャに登録するためクラス・BroadcastReceiverクラス  Manifestに設定されたインテントを受けてサービスを開始させる  ためのクラス・ExtensionServiceクラス  常駐するためのサービスクラス・メイン処理クラス  実処理が書かれているクラス。ExtensionServiceクラスから呼ばれる。
  • 40. 40 プログラムに必要なクラス プログラムには6つのクラスが必要です。・PreferenceActivityクラス   Android本体側での設定等を行うためのクラス メイン処理のクラスは、・RegistrationInformationクラス 2つです。  LiveWareマネージャに登録するためクラス・BroadcastReceiverクラス  Manifestに設定されたインテントを受けてサービスを開始させる  ためのクラス・ExtensionServiceクラス  常駐するためのサービスクラス・メイン処理クラス  実処理が書かれているクラス。ExtensionServiceクラスから呼ばれる。
  • 41. 41 プログラムに必要なクラス メイン処理のクラス・ControlExtensionクラス   SmartWatch本体側プログラムとして振舞うクラス・WidgetExtensionクラス  SmartWatch本体でWidgetプログラムとして振舞うクラス
  • 42. 42 プログラムに必要なクラス メイン処理のクラス・ControlExtensionクラス  振舞うクラス?  SmartWatch本体側プログラムとして振舞うクラス・WidgetExtensionクラス  SmartWatch本体でWidgetプログラムとして振舞うクラス
  • 43. 43 プログラムに必要なクラス メイン処理のクラス SmartWatch本体ではプログラム・ControlExtensionクラス  は動いていないからです。  SmartWatch本体側プログラムとして振舞うクラス・WidgetExtensionクラス プログラムは全て、Android側で動いている  SmartWatch本体でWidgetプログラムとして振舞うクラス
  • 44. 44プログラムの概要 BroadcastReceiverクラスを継承 ExtensionServiceクラスを継承 PreferenceActivityクラスを継承 RegistrationInformationクラスを継承 メイン処理のクラス ControlExtensionクラスを継承している
  • 45. 45 PreferenceActivityクラス/** * The sample control preference activity handles the preferences for * the sample control extension. */public class SamplePreferenceActivity extends PreferenceActivity { private static final int DIALOG_READ_ME = 1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preference); // Handle read me Preference preference = findPreference(getText(R.string.preference_key_read_me)); preference.setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { showDialog(DIALOG_READ_ME); return true; } }); }
  • 46. 46 PreferenceActivityクラス @Override protected Dialog onCreateDialog(int id) { Dialog dialog = null; switch (id) { case DIALOG_READ_ME: dialog = createReadMeDialog(); break; default: Log.w(SampleExtensionService.LOG_TAG, "Not a valid dialog id: " + id); break; } return dialog; } /** * Create the Read me dialog * * @return the Dialog */ private Dialog createReadMeDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.preference_option_read_me_txt) .setTitle(R.string.preference_option_read_me) .setIcon(android.R.drawable.ic_dialog_info) .setPositiveButton(android.R.string.ok, new OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); return builder.create(); }}
  • 47. 47 RegistrationInformationクラス/** * Provides information needed during extension registration */public class SampleRegistrationInformation extends RegistrationInformation { final Context mContext; /** * Create control registration object * * @param context The context */ protected SampleRegistrationInformation(Context context) { if (context == null) { throw new IllegalArgumentException("context == null"); } mContext = context; } @Override public int getRequiredControlApiVersion() { return 1; } @Override public int getRequiredSensorApiVersion() { return 0; } @Override どのAPIを使うか public int getRequiredNotificationApiVersion() { return 0; } @Override public int getRequiredWidgetApiVersion() { return 0; }
  • 48. 48 RegistrationInformationクラス /** * Get the extension registration information. * * @return The registration configuration. */ @Override public ContentValues getExtensionRegistrationConfiguration() { String iconHostapp = ExtensionUtils.getUriString(mContext, R.drawable.icon); String iconExtension = ExtensionUtils.getUriString(mContext, R.drawable.icon_extension); String iconExtensionBw = ExtensionUtils.getUriString(mContext, R.drawable.icn_18x18_black_white_sample_control); ContentValues values = new ContentValues(); values.put(Registration.ExtensionColumns.CONFIGURATION_ACTIVITY, SamplePreferenceActivity.class.getName()); 登録する情 values.put(Registration.ExtensionColumns.CONFIGURATION_TEXT, mContext.getString(R.string.configuration_text)); 報をセットし values.put(Registration.ExtensionColumns.NAME, mContext.getString(R.string.extension_name)); values.put(Registration.ExtensionColumns.EXTENSION_KEY, SampleExtensionService.EXTENSION_KEY); ている values.put(Registration.ExtensionColumns.HOST_APP_ICON_URI, iconHostapp); values.put(Registration.ExtensionColumns.EXTENSION_ICON_URI, iconExtension); values.put(Registration.ExtensionColumns.EXTENSION_ICON_URI_BLACK_WHITE, iconExtensionBw); values.put(Registration.ExtensionColumns.NOTIFICATION_API_VERSION, getRequiredNotificationApiVersion()); values.put(Registration.ExtensionColumns.PACKAGE_NAME, mContext.getPackageName()); return values; } @Override public boolean isDisplaySizeSupported(int width, int height) { return ((width == SampleControlSmartWatch.getSupportedControlWidth(mContext) && height == SampleControlSmartWatch .getSupportedControlHeight(mContext)) || (width == SampleControlSmartWirelessHeadsetPro .getSupportedControlWidth(mContext) && height == SampleControlSmartWirelessHeadsetPro .getSupportedControlHeight(mContext))); }}
  • 49. 49 BroadcastReceiverクラス/** * The extension receiver receives the extension intents and starts the * extension service when it arrives. */public class ExtensionReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { Log.d(SampleExtensionService.LOG_TAG, "onReceive: " + intent.getAction()); intent.setClass(context, SampleExtensionService.class); context.startService(intent); }} インテントにサービスとして呼び出す クラスをセットしている
  • 50. 50 ExtensionServiceクラスpublic class SmartWatchTest00Service extends ExtensionService { public static final String EXTENSION_KEY = "com.sonyericsson.extras.liveware.extension.samplecontrol.key"; public static final String LOG_TAG = "SmartWatchTest00"; public SmartWatchTest00Service() {  super(EXTENSION_KEY); } /** * {@inheritDoc} * * @see android.app.Service#onCreate() */ @Override public void onCreate() { super.onCreate(); Log.d(SmartWatchTest00Service.LOG_TAG, "SmartWatchTest00: onCreate"); } @Override protected RegistrationInformation getRegistrationInformation() { return new SmartWatchTest00RegistrationInformation(this); } LiveWareマネージャ登録クラス生成
  • 51. 51 ExtensionServiceクラス @Override protected boolean keepRunningWhenConnected() { return false; } @Override public ControlExtension createControlExtension(String hostAppPackageName) { final int controlSWWidth = SmartWatchTest00.getSupportedControlWidth(this); final int controlSWHeight = SmartWatchTest00.getSupportedControlHeight(this); for (DeviceInfo device : RegistrationAdapter.getHostApplication(this, hostAppPackageName) .getDevices()) { SmartWatch for (DisplayInfo display : device.getDisplays()) { if (display.sizeEquals(controlSWWidth, controlSWHeight)) { return new SmartWatchTest00(hostAppPackageName, this, new Handler()); の画面サイズ } } } などをチェック } throw new IllegalArgumentException("No control for: " + hostAppPackageName); している} メインの処理クラスの生成
  • 52. 52 メイン処理クラス ControlExtensionクラスpublic final void start()public final void resume()public final void pause()public final void stop()public final void destroy()public void onDoAction(int requestCode, Bundle bundle)public void onDestroy()public void onStart()public void onStop()public void onPause()public void onResume()public void onError(final int code)public void onKey(final int action, final int keyCode, final long timeStamp)public void onTouch(final ControlTouchEvent event)public void onSwipe(int direction)protected void startRequest()protected void stopRequest()protected void showImage(final int resourceId)protected void showBitmap(final Bitmap bitmap)protected void showBitmap(final Bitmap bitmap, final int x, final int y)protected void setScreenState(final int state)protected void startVibrator(int onDuration, int offDuration, int repeats)protected void stopVibrator()protected void startLedPattern(int id, int color, int onDuration, int offDuration, int repeats)protected void stopLedPattern(int id)protected void clearDisplay()protected void sendToHostApp(final Intent intent)protected long getHostAppId()protected boolean hasVibrator()
  • 53. 53 メイン処理クラス WidgetExtensionクラスpublic final void startRefresh()public final void stopRefresh()public final void destroy()public abstract void onStartRefresh()public abstract void onStopRefresh()public void onScheduledRefresh()protected void scheduleRepeatingRefresh(long triggerAtTime, long interval, String extensionKey)protected void scheduleRefresh(long triggerAtTime, String extensionKey)protected void cancelScheduledRefresh(String extensionKey)public void onDoAction(int requestCode, Bundle bundle)public void onDestroy()public void onTouch(final int type, final int x, final int y)protected void sendImageToHostApp(final int resourceId)protected void sendToHostApp(final Intent intent)protected void showBitmap(final Bitmap bitmap)
  • 54. 54 メイン処理クラス 画面を作る例 // Extract the last part of the host application package name. String packageName = mHostAppPackageName .substring(mHostAppPackageName.lastIndexOf(".") + 1); Bitmapを生成 // Create background bitmap for animation. mBackground = Bitmap.createBitmap(width, height, BITMAP_CONFIG); // Set default density to avoid scaling. mBackground.setDensity(DisplayMetrics.DENSITY_DEFAULT); LinearLayout root = new LinearLayout(mContext); 画面のレイアウトを生成 root.setLayoutParams(new LayoutParams(width, height)); LinearLayout sampleLayout = (LinearLayout)LinearLayout.inflate(mContext, R.layout.sample_control, root); ((TextView)sampleLayout.findViewById(R.id.sample_control_text)).setText(packageName); レイアウトに書き sampleLayout.measure(width, height); sampleLayout.layout(0, 0, sampleLayout.getMeasuredWidth(), 込み sampleLayout.getMeasuredHeight()); Canvas canvas = new Canvas(mBackground); sampleLayout.draw(canvas); レイアウトをBitmapに書き込む showBitmap(mBackground);画像を送信するインテントを発行している
  • 55. 55 メイン処理クラス 画面を作る例 // Extract the last part of the host application package name. String packageName = mHostAppPackageName .substring(mHostAppPackageName.lastIndexOf(".") + 1); Bitmapを生成 // Create background bitmap for animation. mBackground = Bitmap.createBitmap(width, height, BITMAP_CONFIG); // Set default density to avoid scaling. インテントで画像を送 mBackground.setDensity(DisplayMetrics.DENSITY_DEFAULT); 画面のレイアウトを生成 LinearLayout root = new LinearLayout(mContext); root.setLayoutParams(new LayoutParams(width, height)); 信すると知ったとき、 LinearLayout sampleLayout = (LinearLayout)LinearLayout.inflate(mContext, R.layout.sample_control, root); ((TextView)sampleLayout.findViewById(R.id.sample_control_text)).setText(packageName); レイアウトに書き sampleLayout.measure(width, height); sampleLayout.layout(0, 0, sampleLayout.getMeasuredWidth(), 込み sampleLayout.getMeasuredHeight()); Canvas canvas = new Canvas(mBackground); sampleLayout.draw(canvas); レイアウトをBitmapに書き込む showBitmap(mBackground);画像を送信するインテントを発行している
  • 56. 56 メイン処理クラス 画面を作る例 // Extract the last part of the host application package name. String packageName = mHostAppPackageName .substring(mHostAppPackageName.lastIndexOf(".") + 1); Bitmapを生成 // Create background bitmap for animation. mBackground = Bitmap.createBitmap(width, height, BITMAP_CONFIG); // Set default density to avoid scaling. ついに、Binderが 画面のレイアウトを生成 mBackground.setDensity(DisplayMetrics.DENSITY_DEFAULT); LinearLayout root = new LinearLayout(mContext); Bluetoothを超えたか!! root.setLayoutParams(new LayoutParams(width, height)); LinearLayout sampleLayout = (LinearLayout)LinearLayout.inflate(mContext, R.layout.sample_control, root); ((TextView)sampleLayout.findViewById(R.id.sample_control_text)).setText(packageName); レイアウトに書き sampleLayout.measure(width, height); sampleLayout.layout(0, 0, sampleLayout.getMeasuredWidth(), 込み sampleLayout.getMeasuredHeight()); Canvas canvas = new Canvas(mBackground); sampleLayout.draw(canvas); レイアウトをBitmapに書き込む showBitmap(mBackground);画像を送信するインテントを発行している
  • 57. 57 メイン処理クラス 画面を作る例 // Extract the last part of the host application package name. String packageName = mHostAppPackageName .substring(mHostAppPackageName.lastIndexOf(".") + 1); Bitmapを生成 // Create background bitmap for animation. mBackground = Bitmap.createBitmap(width, height, BITMAP_CONFIG); そんなことは 画面のレイアウトを生成 // Set default density to avoid scaling. mBackground.setDensity(DisplayMetrics.DENSITY_DEFAULT); LinearLayout root = new LinearLayout(mContext); ありませんでした。 root.setLayoutParams(new LayoutParams(width, height)); LinearLayout sampleLayout = (LinearLayout)LinearLayout.inflate(mContext, R.layout.sample_control, root); ((TextView)sampleLayout.findViewById(R.id.sample_control_text)).setText(packageName); レイアウトに書き sampleLayout.measure(width, height); sampleLayout.layout(0, 0, sampleLayout.getMeasuredWidth(), 込み sampleLayout.getMeasuredHeight()); Canvas canvas = new Canvas(mBackground); sampleLayout.draw(canvas); レイアウトをBitmapに書き込む showBitmap(mBackground);画像を送信するインテントを発行している
  • 58. Smart Extension Emulator を使う
  • 59. 59Extensions エミュレータには、  Extendions  Events  Widgets  Controls の4つの画面があります。 登録・動作しているアプリ 情報一覧
  • 60. 60 Extension settingsMenuボタンを押す→Extension preferences アプリ一覧が表示される
  • 61. 61Extension settings PreferenceActivityが 呼ばれる
  • 62. 62 Eventsイベントの内容を表示してくれます。 アプリ別にも出せます
  • 63. 63Widgets SmartWatchの Widget画面
  • 64. 64 Controls SmartWatchの アプリ動作画面 PauseイベントUp Swipeイベント Left SwipeイベントDown Swipeイベント Right Swipeイベント
  • 65. 何、作ろうか?
  • 66. 66 何、作ろうか・SmartWatch用 スクリプト
  • 67. 67 何、作ろうか・SmartWatch用 スクリプト・Ruputer エミュレータ
  • 68. 68Ruputer エミュレータ
  • 69. 69 何、作ろうか・SmartWatch用スクリプト・Ruputer エミュレータ・ひとり AR
  • 70. 70ひとりAR
  • 71. 71 何、作ろうか・SmartWatch用スクリプト・Ruputer エミュレータ・ひとり AR
  • 72. おしまい