Taskerとnmaで”Find My iPhone”が作れるよ。そう、Androidならね

Standard

iPhone5の発表を目前にして、Androidのメモです。
 
iPhoneをなくしてしまった時に端末の現在地を確認できたりする“Find My iPhone”ですが、当然Android端末でも同じようなことしたいわけです。Google Playで検索すれば同じことができるアプリがたくさん出てきます。が、そこは自分でやるのが楽しいAndroidなのでTaskerを使って実現してみます。
 
 
Android端末についてのアレコレを自動化してくれるという、すべてのAndroidユーザがインストールすべきTaskerですが、今回やろうとしていることと同じことをやっているサンプルはネット上で見つけることができます。ただK-9っていうメーラーアプリを使っていることが前提になっているので、ボクは設定していませんでした。
 
http://www43.atwiki.jp/taskeru/pages/15.html

■K-9で指定メールアドレスから受信をした際に、携帯電話所在地を特定電話番号へSMS送信。■
[Context]Evnet>>3rdParty>>K9 EmailReceived (from 指定メールアドレス)
[Task]
Misc>>GPS>>on
Misc>>GetLocation(source GPS)
Misc>>GPS>>off
Net>>SendSMS(number[送信先携帯電話番号] ,Message[%LOC])
※LOC は取得した現在地を表す変数です。

出来れば、紛失した携帯の所在地を確認するために、送信したメールアドレスに現在地を返信したいのですが、方法が分かりません。

 
で、ある時Taskerの[Evnet] >> [3rd Party]の中に「Notify My Android」っていうのがあるのを見つけまして、調べてみると「Notify My Android (nma)」っていうのはAndroid端末に外部から通知を送ることができるサービスでした。
https://www.notifymyandroid.com/
https://play.google.com/store/apps/details?id=com.usk.app.notifymyandroid&hl=ja
見落としていたことが残念でしかたありません。自動化ライフにかなり役立ちそうなサービスであります。このアプリをインストールして、アカウントを作成後、サイトにログインすると、ここから端末にマニュアルで通知を送ることができるようになります。
 
Screenshot_from_2012-09-05_001

20120906

 
この通知をトリガーとして現在地をどこかに送信するタスクをTaskerに設定してみます。
 
Context
===============================================================
[Evnet] >> [3rd Party] >> [Notify My Android]
>> (App“Web Notification”と入力)
 
20120906-001

20120906-001

===============================================================
 
 
Task
===============================================================
5つです。
20120906-002

20120906-002

 

  1. [Misc] >> [GPS]
    >> (SetOn)
  2. [Misc] >> [Get Location]
    >> (SourceAny)
  3. [Misc] >> [GPS]
    >> (SetOff)
  4. [App] >> [Calendar Insert]
    >> (Calendarは虫めがねボタンを押していつも使ってるGoogleアカウントを選択、
    Titleは適当な文字列、
    Description%DATE, %TIMEを含んだ文字列
    Location%LOCと入力)
    20120906-003

    20120906-003
  5. [Net] >> [HTTP Post]
    >> (設定値は後述)

===============================================================
 
Taskについて簡単に解説します。
1.〜3.で現在地を取得しています。端末をなくした場合を想定しているので、バッテリーを節約するために、現在地を取得したらGPSをオフにしています。
2.の設定値で、SourceAnyにしていますが、こうすると、GPSではじめに取得して、取得できなかったら、基地局から取得するらしいです。
4.で取得した現在地をGoogleカレンダーに記録しています。Android端末のアカウント同期機能を使っていれば、記録された情報を別の端末やPCから確認することができます。上の設定値だと
Screenshot_from_2012-09-05_003

20120906-004

という感じで登録されます。
5.Googleカレンダーだけでもいいですが、アカウントの同期機能を使っていないこともあるので、位置情報をメールで自分に送ってみます。Taskerからは「特定のメールアドレスにメールを送る」っていうのはできないっぽい(SMSは送信できる)ので、どっかのサーバにプログラムを置いて、そこにTaskerからリクエストを送信、そのプログラムでリクエストをメールに変換して送信っていう感じでやりました。
設定値は
20120906-130822

20120906-005

な感じです。見たままです。メールを送信するプログラムは
 
post-2-mail.php

<?php
/*
 * Send E-mail from POST request
 * POSTリクエストをE-mailに変換して送信するスクリプト
 *
 *  Request Parameters
 *    now: DateTime
 *         日時
 *    loc: Location - Latitude and Longitude
 *         場所 - 緯度・経度
 */

require_once("Common.php");

$mail_to = YOUR_EMAIL_ADDRESS;
$mail_from = "Your.Android.Phone";
$mail_title = "I'm here!";
$mail_body = <<<EOD
This E-mail has been sent from your phone.
  Time: CURRENT_DATE_TIME
  Loc:  CURRENT_LOCATION
EOD;

if ( isset($_POST) && !empty($_POST) ) {
  if ( isset($_POST['now']) && !empty($_POST['now']) ) {
    $now = str_replace("_", " ", $_POST['now']);
    $now = str_replace(".", ":", $now);
    $mail_body = str_replace("CURRENT_DATE_TIME", $now, $mail_body);
  }
  if ( isset($_POST['loc']) && !empty($_POST['loc']) ) {
    $mail_body = str_replace("CURRENT_LOCATION", $_POST['loc'], $mail_body);
  }
  Common::send_jp_mail(
    array(
      'to' => $mail_to,
      'subject' => $mail_title,
      'body' => $mail_body,
      'from_email' => $mail_from,
      'from_name' => $mail_from
    )
  );
}

 
Common.php

<?php
class Common {
  /*
   * This method send a mail for Japanese.
   * (charaset of the email is 'ISO-2022-JP')
   *
   *  Parameters
   *    to:           sending email's TO
   *    cc:           sending email's CC
   *    bcc:          sending email's BCC
   *    subject:      sending email's subject
   *    body:         sending email's body
   *    from_email:   sending email's From and Reply-To
   *    from_name:    sending email's From and Reply-To
   *    attach_files: sending email's attach files.
   *                  This parameter is Array type, so you can set multiple files.
   *
   *  Return
   *    The result of sending as TRUE or FALSE.
   */
  public static function send_jp_mail( $params = array() ) {
    $to = ( array_key_exists('to', $params) ? $params['to'] : null);
    $cc = ( array_key_exists('cc', $params) ? $params['cc'] : null);
    $bcc = ( array_key_exists('bcc', $params) ? $params['bcc'] : null);
    $subject = ( array_key_exists('subject', $params) ? $params['subject'] : null);
    $body = ( array_key_exists('body', $params) ? $params['body'] : null);
    $from_email = ( array_key_exists('from_email', $params) ? $params['from_email'] : null);
    $from_name = ( array_key_exists('from_name', $params) ? $params['from_name'] : null);
    $attach_files = ( array_key_exists('attach_files', $params) ? $params['attach_files'] : array());
    $boundary = null;
    $has_attachment = is_array($attach_files) && count($attach_files) > 0;
    if ($has_attachment) {
      $boundary = md5(uniqid(rand(), true));
    }

    $headers  = "MIME-Version: 1.0 \n" ;
    $headers .= "From: " .
                "".mb_encode_mimeheader (mb_convert_encoding($from_name,"ISO-2022-JP","AUTO")) ."" .
                "<".$from_email."> \n";
    $headers .= "Reply-To: " .
                "".mb_encode_mimeheader (mb_convert_encoding($from_name,"ISO-2022-JP","AUTO")) ."" .
                "<".$from_email."> \n";
    $headers .= "Cc: ".$cc."\n";
    $headers .= "Bcc: ".$bcc."\n";
    if ($has_attachment) {
      $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
    } else {
      $headers .= "Content-Type: text/plain;charset=ISO-2022-JP \n";
    }
    $headers .= "Content-Transfer-Encoding: 7bit";


    /* Convert body to same encoding as stated
    in Content-Type header above */

    if ($has_attachment) {
      $r_body = $body;
      $body = "--$boundary\n";
      $body .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
      $body .= "Content-Transfer-Encoding: 7bit\n";
      $body .= "\n";
      $body .= mb_convert_encoding($r_body, "ISO-2022-JP","AUTO")."\n";

      foreach ($attach_files as $file) {
        if (!file_exists($file)) {
          continue;
        }
        $filename = basename($file);
        $body .= "\n";
        $body .= "--$boundary\n";
        $body .= "Content-Type: application/octet-stream; name=\"$filename\"\n";
        $body .= "Content-Disposition: attachment; filename=\"$filename\"\n";
        $body .= "Content-Transfer-Encoding: base64\n";
        $body .= "\n";
        $body .= chunk_split(base64_encode(file_get_contents($file)))."\n";
      }
      $body .= '--'.$boundary.'--';
    } else {
      $body = mb_convert_encoding($body, "ISO-2022-JP","AUTO");
    }

    /* Mail, optional paramiters. */
    $sendmail_params  = "-f$from_email";

    mb_language("ja");
    $subject = mb_convert_encoding($subject, "ISO-2022-JP","AUTO");
    $subject = mb_encode_mimeheader($subject);

    $result = mail($to, $subject, $body, $headers, $sendmail_params);
    return $result;
  }
}

 
という感じです。これもそのままです。メールがたくさん来たら困る人はリクエストパラメータに固定のキーでも埋め込んだらいいと思います。
 
 
タスクの設定が終わったら保存して、上述のnmaのサイトから自分の端末に通知を送ってみます。
Screenshot_from_2012-09-05_002

20120906-006

っていう感じのメールを受信できました。
 
 
参考(Taskerでデフォルトで使える変数)
http://tasker.dinglisch.net/tour.html#variables
http://www43.atwiki.jp/taskeru/pages/17.html