androidをリモートコントロール

PCから、ネットワーク越しにAndroidをリモート操作し、以下を行った。

  • トースト通知表示
  • カメラで写真撮影
  • センサ情報の取得

Androidでは、SL4Aのサーバを起動し、PCからpythonを使って、そのサーバ越しに上記操作を行った。

以下のサイトを参考にして作業を行った。

  1. AndroidFacadeAPIセンサー
  2. RemoteControl How to control the device while running scripts on your computer
  3. SL4A+PythonでAndroidをリモートコントロール

androidをノートPCに無線接続(帰属)

Windows7のノートPCをアクセスポイントにして、そこにAndroidを無線接続(帰属)させた。
また、開発環境は、Windows7VM上のLinux(Ubuntu10.04)であったため、Windows上でルーティング解決が必要であった。

  1. アクセスポイント(AP)モードで起動可能な無線LANアダプタを用意する。
  2. APモードで起動する。
    • 「クライアントマネージャ」を起動し、「携帯電話を接続する」を選択する。すると、アクセスポイントモードで起動できる。
    • 適当に編集する。
    • 例えば、SSIDにunpopo,チャネルを13,認証タイプをWPA2-PSK,暗号化タイプをTKIP,WPAプリシェアドキーをhogefugahogefugaなど。
    • SSID,WPAプリシェアドキーは後でandroid端末から帰属させるのに必要である。
  3. Android端末をAPに帰属させる。
    • 自分が持っている端末(N-06C)だと、設定->無線とネットワーク->Wi-Fi設定で設定できる。
    • 先のAPが見えているはずなので、パスワードにプリシェアドキーと同じ文字を入れる。
  4. 接続後、先の画面でもう一度APをタップすると、IPアドレスが表示される。

ルーティング設定

※必要ない時は読み飛ばして可

  1. fowardingの有効化
    • サービスの"Routing and remote Access"で右クリック、"開始"をする。
    • ipconfig /allしたときに、"IPルーティング有効"が"はい"になっていることを確認する。
  2. 仮想ネットワークの追加
  3. ルーティング設定

linuxのアドレスが192.168.28.1で、192.168.28.0/24ネットワーク(eth1)、Androidが192.168.100.0/24ネットワークであったので、Linuxにルーティング設定した。

$ sudo ip route add 192.168.100.0/24 via 192.168.28.1 dev eth1

android端末でSL4Aのサーバを動かす

  1. サーバ起動
    • SL4Aをインストール後、起動。メニュー画面を開きView->Interpretersを開く。
    • さらにメニュー画面を開き、StartServer->Publicを開く。
    • このとき、Publicの場合、帰属しているIPでサーバが立ち上がる。(Privateだとlocalhost/127.0.0.1で立ち上がる。)
    • 画面上部の通知領域にアイコンが出るのでそれを開く。IPアドレスとポート番号が表示されるの控えておく。例えば、192.168.100.2:42378など。リモート操作時に必要。

PCからandroidをリモート操作準備

  1. 接続サーバのIP,ポート番号を環境変数に設定する。
$ export AP_HOST=192.168.100.2
$ export AP_PORT=42378
  1. androidリモートコントロール用のscriptを用意する。

android.pyをダウンロードする。
(中を見るとAndroidクラスの__init__()でsocket作ってる。コンストラクタで接続先を指定されない時に環境変数利用している。)

リモート操作用のプログラム作成

あとは、作って実行するだけ。

  1. toast通知用

とりあえず練習。

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import android
droid = android.Android()
droid.makeToast("Hello,nihohi")
  1. カメラ撮影用

リモートから任意のタイミング(定期的でも)撮影できるので、何か使えそう。
OpenCVと組み合わせて画像認識して撮影とかもできるかも。

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import android
droid = android.Android()
droid.cameraCapturePicture('/mnt/sdcard/sl4a/fuga.jpg')
  1. センサ情報取得用

手で光センサ部分を覆ったり、傾けたりすると値が変化して面白い。
こちらのサイトが大変参考になった。
AndroidFacadeAPIセンサー

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import android
import time
droid = android.Android()
droid.startSensingTimed(1, 500)
for i in range(100):
    event = droid.eventWaitFor("sensors")
    for key,val in event.result["data"].items():
        print "%s:%f"%(key,val)
    print "\n"
droid.stopSensing()