2013年9月24日火曜日

iPhone5S,5Cに搭載された指紋認証のすごいところ

iPhone5S,5Cが発売されて数日経過しましたねー。
やっぱり話題になっているのは指紋認証ではないでしょうか?


今回は、iPhoneの指紋認証は何がすごいのか、何故こんなにもてはやされるのかを書いていきたいと思います。


認証方法が変わったから?
指紋認証すごいですよね。
今までの認証のイメージだと、指を置いてスライドさせるイメージ。
(下のはThinkPadですが、ガラケーの頃からこんなイメージでしたよね??)

しかし、iPhoneはじーっとしとくだけになってますもんね。

昔、指紋認証付きのガラケーを使っていましたが、今考えると指をスライドさせるの面倒でしたよね。。。

やっぱり認証技術の進歩とともに、読み取り方法が変わってきて使いやすくなったので採用されたのかなと思います。


でも、ほんとに凄い所は別にある!
これってできそうじゃないですか?日本のガラケーでも、アンドロイドでも。
僕がこれに関して魅力的だなと感じていることは「知的システム」であり「知的な人工物」であるということです。

知的システム?知的な人工物?
知的システムや知的な人工物に関しては同志社大学の三木先生が研究されています。
簡単に言うと外部環境をSenseし、そのデータを元にJudgeし、何かactする。
Sense,Judge,Actの3つの要素を含むものです。
以下のリンクが参考になります。
http://mikilab.doshisha.ac.jp/dia/research/intellectualization01/intelligent/intelligent_top.html

例えば、自動ドアですね。
ドアを通りたい人が前に来るとセンサが反応し、人が来たと判断して、ドアを開ける。
もし、ドアにスイッチが付いていれば知的ではありません。

他には自動で水がでる蛇口ですね。(公衆トイレなどで見かけるやつです)
人が手を洗おうと蛇口に手を近づけると、センサが反応し、手が近くにあると判断し、水を出す。

これらは人が意識せずに、人以外のモノ(コンピュータなど)が判断し、動作する。
立派な知的な人工物です。
人の効率の向上や不必要な動作や判断を避けることができます。


iPhoneと知的人工物
iPhoneの指紋認証のすごいところに話を戻します。
この認証は知的かというと認証なので知的なのですが、いいところはホームボタンに認証機能があるということです。

ユーザは画面をつけるためにホームボタンを押し、その際に認証も行う。
これまでは、ユーザからすると画面をつけることと認証は全く違う動作でした。
しかし、iPhoneは自動で認証までユーザに意識をさせずに行うのです。
不必要な動作を避け、効率を向上する。
これは立派な知的なシステムだと思います。

もし、ホームボタンではなく、まったく違う位置に認証機能があれば、ダメな機能だったでしょう。
アンドロイドで指紋認証を載せたとしても、ホームボタンなどのユーザが普段行う動作のどこかに潜りこませないと良いシステムとは言えないでしょう。

iPhoneの指紋認証はこの知的システムだからすごい
と思います。


知的にデザインを行うことについて
人は効率を求めます。無駄なことや面倒なことはしたくありません。
無駄なことや面倒なことを避けるために、お金を使います。
身の回りでもそうでしょう。
知的にデザインを行うことは、多くの人に使ってもらうためのとても大切な要素だと思います。(お金も儲かるかも・・・w)

知的なシステムを考えると結構簡単に(アイデアのしょぼさは問わず←)考えられます。
今回のiPhoneの指紋認証の発展を考えれば、PCのキーボードに手を置いた瞬間に認証されればいいでしょう。(そもそも椅子に座った段階でお尻で認証する研究もあった気がする。)
PC以外に考えると、例えば、ドアノブを回すときに認証を行う。認証できなかったら鍵を開けないでおくなど。


これかも、「知的」というキーワードでアイデアを探し続けていこうと思います。





下の本はブログ中にも書きました、三木先生の本です。


知的システム工学 (情報工学テキストシリーズ 2)
三木 光範
共立出版
売り上げランキング: 1,050,626

2013年9月12日木曜日

NFCとiBeaconを比較している記事に対して1つ言いたいことがある

iOS7の隠れキラーコンテンツとなる近距離無線通信「iBeacon」とは? 

iPhone5S, 5Cの発売に関してのこの記事についてです。
◆NFCよりも優れるBeacon 近距離無線通信技術としてNFCと競合するBeaconですが、様々な点でBeaconが優れています。
と、書かれていますが、本当に?と思っています。

トリガーが違うよ!

NFC

タッチ(かざす)ことがトリガー

iBeacon

通りがかる(近くによる)ことがトリガー


この2つの違いは大きいと思います。
NFCはユーザにとって明確なトリガー、iBeaconはユーザにとって不明確な(自然な)トリガーです。

必ずしもiBeaconがいいのではない!(ツン)

例えば、自動販売機でジュースをスマホで決済することを想像してください。

この場合、僕は、ボタンを押して自動で決済してくれるiBeaconよりも従来のNFCが優れていると思います。
なぜなら、購入者は本当に購入の意図があったかが確認できるからです。
(子供が勝手に違うものを選んだとかではなく)

iBeaconでも確認画面をつければいいじゃないか?って思う人もいるかもしれません。
でも、それってiBeaconの良さが無くね???NFCでよくね???と思います。


長所もあるよ!(デレ)

もちろんiBeaconにも長所はあります。
屋内位置推定が一番の長所かなと。
ユーザの行動を分析し自動で情報を受信できる。
現在はポスターにNFCを埋め込む形式の広告があります。

僕は「広告=ユーザに無理やり見せようとするもの」という考え方をしています。
CMやWEBだってそうです。
その中でユーザにとって有益な広告があれば、ユーザは反応するのです。

ポスターに埋め込んだNFCに意図的にタッチして情報を取りに行くよりかは、
ポスターの前を通りがかるとポスターが語りかけてくるほうがいいですよね!

だから、こういうものに対してはNFCよりもiBeaconのほうが強いのではないでしょうか。


まとめ

つまり、NFCもiBeaconも全く利用方法や応用範囲が違うのではないかと思います。
そして、Googleさん、Appleさん、
NFCもiBeaconもどっちも使えるようにしてしまえばいいじゃないw




Android NFCプログラミング完全ガイド (Smart Mobile Developer) オレンジタグス 業務用 FeliCa フェリカ ラベルシール 45x35 非接触 ICタグ FeliCa Lite , TL-L4
オレンジタグス 業務用 NFC Forum Type2 Tag 非接触ICカード Mifare Ultralight , TU-C1
株式会社オレンジタグス
売り上げランキング: 64,702




2013年7月26日金曜日

SublimeText2とGoogle日本語入力を使用して、日本語コメントを入力してENTER押すと消える問題(長っ


タイトルどおりです。
問題はどういうことかというと、日本語コメント入力して、



ENTER押すと・・・・




消えた・・・\(^o^)/

おそらくはコメント行を自動で補完してくれる優しさが日本語に上書きされるのが問題だと思われます。

ググったらやさしい方がGitHubに回避方法を公開していました。
http://koizuss.hatenablog.com/entry/2013/01/14/112350
https://gist.github.com/koizuss/4521934
お、Default.sublime-keymapの36行から3つ分をコメントすればいいみたい。
やっほい!

Default.sublime-keymapはSublimeを立ち上げて、
 Preference > Browse Packages...
から、
/Packages/DocBlockr/Default.sublime-keymap
で開ける。


・・・
・・・・・・
直らない・・・・

結局設定を読んでいるともう一箇所コメントしないといけないことに気づく。
コメントアウトしたら上記の問題が回避できた。

結局、設定はこのようになりました↓
合計4箇所コメントアウトしてます。

[
  // open a docblock with enter
  { "keys": ["enter"], "command": "jsdocs",
    "context": [
      { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,                    "match_all": true },
      { "key": "selection_empty",       "operator": "equal",          "operand": true,                    "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal",          "operand": false,                   "match_all": true },
      { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*(\\/\\*|###)\\*$", "match_all": true }
    ]
  },
  // open a docblock with keypad enter
  { "keys": ["keypad_enter"], "command": "jsdocs",
    "context": [
      { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,                    "match_all": true },
      { "key": "selection_empty",       "operator": "equal",          "operand": true,                    "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal",          "operand": false,                   "match_all": true },
      { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*(\\/\\*|###)\\*$", "match_all": true }
    ]
  },
  // open a docblock with tab
  { "keys": ["tab"], "command": "jsdocs",
    "context": [
      { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,                    "match_all": true },
      { "key": "selection_empty",       "operator": "equal",          "operand": true,                    "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal",          "operand": false,                   "match_all": true },
      { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*(\\/\\*|###)\\*$", "match_all": true }
    ]
  },

  /**
   * Google日本語入力を使っている場合のENTERで入力内容が消える問題に対応
   * ↓をコメントアウトすることでとりあえず入力できるようになる
   * (Docコメント内で改行しても整形されなくなる)
   */

  // // extend a docblock by adding an asterisk at the start
  // { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n${TM_CURRENT_LINE/^\\s*(\\*\\s*).*$/$1/}"},
  //   "context": [
  //     { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,              "match_all": true },
  //     { "key": "selector",              "operator": "equal",          "operand": "comment.block",   "match_all": true },
  //     { "key": "auto_complete_visible", "operator": "equal",          "operand": false,             "match_all": true },
  //     { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*\\*\\s*\\S", "match_all": true }
  //   ]
  // },
  // // extend a docblock by adding an asterisk at the start
  // { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n${TM_CURRENT_LINE/^\\s*(\\*\\s*).*$/$1/}"},
  //   "context": [
  //     { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,            "match_all": true },
  //     { "key": "selector",              "operator": "equal",          "operand": "comment.block", "match_all": true },
  //     { "key": "auto_complete_visible", "operator": "equal",          "operand": false,           "match_all": true },
  //     { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*\\*",      "match_all": true }
  //   ]
  // },
  // // extend a docblock with keypad enter by adding an asterisk at the start
  // { "keys": ["keypad_enter"], "command": "insert_snippet", "args": {"contents": "\n${TM_CURRENT_LINE/^\\s*(\\*\\s*).*$/$1/}"},
  //   "context": [
  //     { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,            "match_all": true },
  //     { "key": "selector",              "operator": "equal",          "operand": "comment.block", "match_all": true },
  //     { "key": "auto_complete_visible", "operator": "equal",          "operand": false,           "match_all": true },
  //     { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*\\*",      "match_all": true }
  //   ]
  // },

  // trim the automatically added whitespace
  { "keys": ["enter"], "command": "jsdocs_trim_auto_whitespace",
    "context": [
      { "key": "setting.auto_indent",                "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "selector",                           "operator": "equal",          "operand": "comment.block", "match_all": true },
      { "key": "auto_complete_visible",              "operator": "equal",          "operand": false,           "match_all": true },
      { "key": "setting.trim_automatic_white_space", "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "preceding_text",                     "operator": "regex_contains", "operand": "^\\s*\\*\\s*$", "match_all": true },
      { "key": "following_text",                     "operator": "regex_contains", "operand": "^\\s*$",        "match_all": true }
    ]
  },
  // trim the automatically added whitespace
  { "keys": ["keypad_enter"], "command": "jsdocs_trim_auto_whitespace",
    "context": [
      { "key": "setting.auto_indent",                "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "selector",                           "operator": "equal",          "operand": "comment.block", "match_all": true },
      { "key": "auto_complete_visible",              "operator": "equal",          "operand": false,           "match_all": true },
      { "key": "setting.trim_automatic_white_space", "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "preceding_text",                     "operator": "regex_contains", "operand": "^\\s*\\*\\s*$", "match_all": true },
      { "key": "following_text",                     "operator": "regex_contains", "operand": "^\\s*$",        "match_all": true }
    ]
  },
  // extend line comments (// and #)
  /**
   * ここでENTERキーを押してもコメントの行が自動補完されないようにする。
   */
//  { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n${TM_CURRENT_LINE/^\\s*((?:#|\\/\\/)\\s*).*/$1/}"},
//    "context": [
//      { "key": "setting.auto_indent",                "operator": "equal",          "operand": true,              "match_all": true },
//      { "key": "setting.jsdocs_extend_double_slash", "operator": "equal",          "operand": true,              "match_all": true },
//      { "key": "selector",                           "operator": "equal",          "operand": "comment.line",    "match_all": true },
//      { "key": "auto_complete_visible",              "operator": "equal",          "operand": false,             "match_all": true },
//      { "key": "preceding_text",                     "operator": "regex_contains", "operand": "^\\s*(\\/\\/|#)", "match_all": true }
//    ]
//  },
  // extend line comments (// #) with keypad enter
  { "keys": ["keypad_enter"], "command": "insert_snippet", "args": {"contents": "\n${TM_CURRENT_LINE/^\\s*((?:#|\\/\\/)\\s*).*$/$1/}"},
    "context": [
      { "key": "setting.auto_indent",                "operator": "equal",          "operand": true,           "match_all": true },
      { "key": "setting.jsdocs_extend_double_slash", "operator": "equal",          "operand": true,           "match_all": true },
      { "key": "selector",                           "operator": "equal",          "operand": "comment.line", "match_all": true },
      { "key": "auto_complete_visible",              "operator": "equal",          "operand": false,          "match_all": true },
      { "key": "preceding_text",                     "operator": "regex_contains", "operand": "^\\s*\\/\\/",  "match_all": true }
    ]
  },
  // close a block comment (/*  */)
  { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n$0\n */"},
    "context": [
      { "key": "selection_empty", "operator": "equal",          "operand": true,           "match_all": true },
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s*\\/\\*$", "match_all": true }
    ]
  },
  // close a block comment (/*  */)
  { "keys": ["keypad_enter"], "command": "insert_snippet", "args": {"contents": "\n$0\n */"},
    "context": [
      { "key": "selection_empty", "operator": "equal",          "operand": true,           "match_all": true },
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s*\\/\\*$", "match_all": true }
    ]
  },
  { "keys": ["enter"], "command": "insert_snippet", "args": {"contents": "\n$0\n "}, "context":
    [
      { "key": "selection_empty", "operator": "equal",          "operand": true,           "match_all": true},
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s*\\/\\*$", "match_all": true},
      { "key": "following_text",  "operator": "regex_contains", "operand": "^\\*\\/\\s*$", "match_all": true}
    ]
  },
  { "keys": ["keypad_enter"], "command": "insert_snippet", "args": {"contents": "\n$0\n "}, "context":
    [
      { "key": "selection_empty", "operator": "equal",          "operand": true,           "match_all": true},
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s*\\/\\*$", "match_all": true},
      { "key": "following_text",  "operator": "regex_contains", "operand": "^\\*\\/$",     "match_all": true}
    ]
  },
  // De-indent at the end of a comment block
  { "keys": ["enter"], "command": "jsdocs_deindent",
    "context": [
      { "key": "selection_empty", "operator": "equal",          "operand": true,        "match_all": true },
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s+\\*/", "match_all": true }
    ]
  },
  // de-indent at the end of a comment block with keypad-enter
  { "keys": ["keypad_enter"], "command": "jsdocs_deindent",
    "context": [
      { "key": "selection_empty", "operator": "equal",          "operand": true,        "match_all": true },
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s+\\*/", "match_all": true }
    ]
  },
  // Open an inline docblock (/** */)
  { "keys": ["shift+enter"], "command": "jsdocs", "args": {"inline": true},
    "context": [
      { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,              "match_all": true },
      { "key": "selection_empty",       "operator": "equal",          "operand": true,              "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal",          "operand": false,             "match_all": true },
      { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*\\/\\*{2}$", "match_all": true }
    ]
  },
  // Open an inline docblock
  { "keys": ["shift+keypad_enter"], "command": "jsdocs", "args": {"inline": true},
    "context": [
      { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,              "match_all": true },
      { "key": "selection_empty",       "operator": "equal",          "operand": true,              "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal",          "operand": false,             "match_all": true },
      { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*\\/\\*{2}$", "match_all": true }
    ]
  },
  // show the autocomplete
  { "keys": ["@"], "command": "run_macro_file", "args": {"file": "Packages/DocBlockr/jsdocs-auto-complete.sublime-macro"},
    "context": [
      { "key": "setting.auto_complete", "operator": "equal",    "operand": true,                           "match_all": true },
      { "key": "selection_empty", "operator": "equal",          "operand": true,                           "match_all": true },
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s*(?:\\/\\*|###)?\\*\\s*$", "match_all": true },
      { "key": "selector",        "operator": "equal",          "operand": "comment.block",                "match_all": true }
    ]
  },
  // show the autocomplete in a coffee doc block
  { "keys": ["@"], "command": "run_macro_file", "args": {"file": "Packages/DocBlockr/jsdocs-auto-complete.sublime-macro"},
    "context": [
      { "key": "selection_empty", "operator": "equal",          "operand": true,                              "match_all": true },
      { "key": "preceding_text",  "operator": "regex_contains", "operand": "^\\s*#\\s*$",                     "match_all": true },
      { "key": "selector",        "operator": "equal",          "operand": "comment.line.number-sign.coffee", "match_all": true }
    ]
  },
  // indent to align with the previous line
  { "keys": ["tab"], "command": "jsdocs_indent",
    "context": [
      { "key": "setting.jsdocs_deep_indent", "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "setting.auto_indent",        "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "selection_empty",            "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "preceding_text",             "operator": "regex_contains", "operand": "^\\s*\\*\\s*$", "match_all": true },
      { "key": "selector",                   "operator": "equal",          "operand": "comment.block", "match_all": true }
    ]
  },
  // decorate a double-slash comment
  { "keys": ["ctrl+enter"], "command": "jsdocs_decorate",
    "context": [
      { "key": "selector", "operator": "equal", "operand": "comment.line.double-slash"}
    ]
  },
  // decorate a double-slash comment
  { "keys": ["ctrl+keypad_enter"], "command": "jsdocs_decorate",
    "context": [
      { "key": "selector", "operator": "equal", "operand": "comment.line.double-slash"}
    ]
  },
  // join lines inside a comment block, stripping the leading asterisk
  { "keys": ["ctrl+j"], "command": "jsdocs_join",
    "context": [
      { "key": "selector", "operator": "equal", "operand": "comment.block" }
    ]
  },
  // join lines in a line comment, stripping the leading // or #
  { "keys": ["ctrl+j"], "command": "jsdocs_join",
    "context": [
      { "key": "selector", "operator": "equal", "operand": "comment.line" }
    ]
  },
  // reparse a comment block's placeholders
  { "keys": ["ctrl+alt+tab"], "command": "jsdocs_reparse",
    "context": [
      { "key": "selector", "operator": "equal", "operand": "comment.block" }
    ]
  },
  { "keys": ["alt+q"], "command": "jsdocs_wrap_lines",
    "context": [
      { "key": "selector", "operator": "equal", "operand": "comment.block", "match_all": true }
    ]
  },

  // add line after, in a DocBlock
  { "keys": ["ctrl+enter"], "command": "run_macro_file", "args": {"file": "Packages/DocBlockr/Add DocBlockr Line.sublime-macro"},
    "context": [
      { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "selector",              "operator": "equal",          "operand": "comment.block", "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal",          "operand": false,           "match_all": true },
      { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*\\*",      "match_all": true }
    ]
  },

  // add line before, in a DocBlock
  { "keys": ["ctrl+shift+enter"], "command": "run_macro_file", "args": {"file": "Packages/DocBlockr/Add DocBlockr Line Before.sublime-macro"},
    "context": [
      { "key": "setting.auto_indent",   "operator": "equal",          "operand": true,            "match_all": true },
      { "key": "selector",              "operator": "equal",          "operand": "comment.block", "match_all": true },
      { "key": "auto_complete_visible", "operator": "equal",          "operand": false,           "match_all": true },
      { "key": "preceding_text",        "operator": "regex_contains", "operand": "^\\s*\\*",      "match_all": true }
    ]
  }
]


2013年1月3日木曜日

Android端末でGAEブロブストア上の画像の取得

Basic認証とストレージに画像保存とイメージビューに画像を保存まで。

package com.taku.nfchome;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import extra.UrlManager;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.ImageView;

public class ImageActivity extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.image_activity);
  final ImageView iv = (ImageView)findViewById(R.id.imageView);
  
  new AsyncTask() {
   @Override
   protected Bitmap doInBackground(String... params) {
    Bitmap bmp = null;
    try{
     DefaultHttpClient httpClient = new DefaultHttpClient();
     String url = new String(params[0]);
     HttpGet request = new HttpGet(url);
     // 認証するUserとPW
     UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("「ユーザ名」","「パスワード」");
     AuthScope scope = new AuthScope(request.getURI().getHost(), request.getURI().getPort());
     httpClient.getCredentialsProvider().setCredentials(scope, credentials);
     
     HttpResponse httpResponse = httpClient.execute(request);
        
        // ステータスコードを取得
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        
        HttpGet httpRequest = new HttpGet(url); 
        
        //ーーー画像生成処理ーーー
        HttpResponse response = (HttpResponse) httpClient.execute(httpRequest); 
        HttpEntity entity1 = response.getEntity();
        BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity1);
        InputStream is = bufHttpEntity.getContent();
        bmp = getBitmap(is);
        // リソースを解放
        entity1.consumeContent();
        // クライアントを終了させる
        httpClient.getConnectionManager().shutdown();
    } catch (UnsupportedEncodingException e) {
     e.printStackTrace();
    } catch (ClientProtocolException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
    
    return bmp;
   }
   @Override
   protected void onPostExecute(Bitmap bmp) {
    Log.v("image", "ok");
    iv.setImageBitmap(bmp);
    saveBitmapToSd(bmp);
    
   }
   
  }.execute("「URL」");
 }
 /**
  * 画像に変換
  * @param is
  * @return
  */
 public static Bitmap getBitmap(InputStream is) {
  Bitmap bmp = null;
  byte[] line = new byte[1024];
  int byteSize = 0;
  try {
   // バイト単位での読込
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   while ((byteSize = is.read(line)) > 0) {
    out.write(line, 0, byteSize);
   }
   // オプション
   BitmapFactory.Options options = new BitmapFactory.Options();
   options.inSampleSize = 0;
   
   byte[] byteArray = out.toByteArray();
   Log.v("image", "byteArray.length = " + byteArray.length);
   bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, options);
   is.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return bmp;
 }
 /**
  * 画像をストレージへ保存
  * @param mBitmap
  */
 public void saveBitmapToSd(Bitmap mBitmap) {
  try {
  // sdcardフォルダを指定
  File root = Environment.getExternalStorageDirectory();

  // 日付でファイル名を作成 
  Date mDate = new Date();
  SimpleDateFormat fileName = new SimpleDateFormat("yyyyMMdd_HHmmss");

  // 保存処理開始
  FileOutputStream fos = null;
  fos = new FileOutputStream(new File(root, fileName.format(mDate) + ".jpg"));
  Log.v("image", (new File(root, fileName.format(mDate) + ".jpg").toString()));
  // jpegで保存
  mBitmap.compress(CompressFormat.JPEG, 100, fos);
  // 保存処理終了
  fos.close();
  } catch (Exception e) {
   Log.e("Error", "" + e.toString());
  }
 }
}

2012年12月4日火曜日

Androidのタッチイベント(ICS)

Androidのタッチイベントについてのまとめ(API8以降の場合)

・マルチタッチする際のポインタ(指)のidの取得方法
  int index = event.getActionIndex();
  int id = event.getPointerId(index);
・マルチタッチの場合はevent.getActionMasked()を使ってイベントを判定
 マルチタッチの場合はMotionEvent.ACTION_POINTER_DOWNを使う。
 この際getAction()ではなく、getActionMasked()を使う。※getAction()ではない。
switch (event.getActionMasked()) {
 case MotionEvent.ACTION_DOWN:
  //指1本でタッチした時
  break;
 case MotionEvent.ACTION_POINTER_DOWN:
  //指2本目以降でタッチした時
  break;
・タッチされた指が2本目か3本目かを判定したい場合はACTION_POINTER_DOWNの場合に、getPointerCount()を用いる
switch (event.getActionMasked()) {
 case MotionEvent.ACTION_POINTER_DOWN:
  //指2本目以降でタッチした時
  if(event.getPointerCount() == 2){
   //2本指の時の処理
  }
  break;

2012年11月22日木曜日

GoogleAppEngine(GAE)でのBasic認証に関して

GAEでBasic認証をした時に参考にしたサイトのメモ
@tomorierさんの記事が参考になりました。ありがとうございます。


おおまかに3つの手順
・filterを作る
・filterをweb.xmlでBasic認証したいサーブレットと結びつける
・アカウントとパスワードを管理するファイルを作成する

filterクラスもリンク先のリンク先にサンプルがある。

ちなみに、パスワードファイルの

 User1=test
User2=test2

は、アカウント名が左でパスワードが右ですね。

2012年11月15日木曜日

ListViewの内容取得(ListView拡張、カスタムListView、カスタムAdapter)

AndroidのListViewをカスタマイズしたい、データによって背景の色を変えたいと思っていろいろ調べたので分かった範囲でメモ。
やりたいこと
・ListViewの1行ごとの内容(オブジェクト)を取得
・取得したオブジェクト内のフラグによって背景色を塗り分ける
・1行内のレイアウトを自由に行う
・ListViewは1行ごとにレイアウトを指定できる。
 例)twitterみたいに、画像を左、アカウント名を右上、テキストを右下など



で、こんな感じにできた。




手順
1.ListViewの1行のレイアウトを作成
レイアウトをxmlで作る
idとかを指定しておく
【past_order_item.xml】



    
   

     
     
     
  
  
     
 



2.ListView自体のレイアウトの作成
説明することは特になし
(Activityに貼付けるレイアウトのこと)
【past_order.xml】
ここのTextViewはListViewに表示するリストが無い場合だけ表示される


 
 



3.ListViewの1行に貼付けたい情報やフラグをもったオブジェクトのクラスの宣言
  ここは自分で好きなようなクラスを作ってください。
  (※不必要なフィールドも書いてたりします)   【PastOrder.java】
public class PastOrder {
 private String order;   
 private String num;    
 private Long dateLong;
 private Date date;
 private String dateString;
 public PastOrder(String order, String num, String dateString) {
  super();
  this.order = order;
  this.num = num;
  this.dateString = dateString;
 }
 public String getOrder() {
  return order;
 }
 public void setOrder(String order) {
  this.order = order;
 }
 public String getNum() {
  return num;
 }
 public void setNum(String num) {
  this.num = num;
 }
 public String getFormatDate(){
  Date date = new Date(dateLong);
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd  HH:mm:ss", Locale.JAPAN);
  return sdf.format(date);
 }
 public boolean isCompleted() {
  return isCompleted;
 }
 public void setCompleted(boolean isCompleted) {
  this.isCompleted = isCompleted;
 }
 public String getDateString() {
  return dateString;
 }
 public void setDateString(String dateString) {
  this.dateString = dateString;
 }
}


4.アダプターの作成(ここがメイン!!)
アダプターとはListViewに貼付けたいデータとレイアウトへの貼付けを行うもの(であってる?)
アダプターの拡張をして、ここで背景の判定とかを行う

ArrayAdapterの拡張をおこなう
(ここでTは先ほど作ったPastOrderクラスとしている) コンストラクタ
 LayoutInflaterオブジェクトの生成
 1行ごとのレイアウトを指定して、データを貼付けたりできる
getView()・・・1行ごとに実行されるメソッド
 convertView==nullならinflate
 ポジションからT itemの取得
あとはitemオブジェクトを好きなように煮て食う
 (今回はオーダー情報から調理完了かどうかをみて背景色を変更する処理を行っている)

public class OrderArrayAdapter extends ArrayAdapter{
 private Context myContext;
 private LayoutInflater li;

 public OrderArrayAdapter(Context context, List objects) {
  super(context, 0, objects);
  myContext = context;
  li = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 }

   //ListViewの1行ごとに呼び出されるメソッド
  //ここで1行ごとオブジェクトを取得し、好きな処理を行う
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  int UNCOMPLETE_COLOR = myContext.getResources().getColor(R.color.status_item_background_complete);
  int COMPLETE_COLOR = myContext.getResources().getColor(R.color.status_item_background_uncomplete);

  if(convertView == null){
   convertView = li.inflate(R.layout.past_order_item, null);
  }
  //対象の行のアイテムを取得
  PastOrder pastOrder = (PastOrder)this.getItem(position);

  if(pastOrder != null){
   //テキストビューの生成
   TextView pastOrderName = (TextView)convertView.findViewById(R.id.pastOrderName);
   TextView pastOrderNum = (TextView)convertView.findViewById(R.id.pastOrderNum);
   TextView pastOrderDate = (TextView)convertView.findViewById(R.id.pastOrderDate);
   //1行のビューに名前、数量、日時の設定
   if(pastOrderName != null){
    pastOrderName.setText(pastOrder.getOrder());
   }
   if(pastOrderNum != null){
    pastOrderNum.setText(pastOrder.getNum());
   }
   if(pastOrderDate != null){
    pastOrderDate.setText(pastOrder.getDateString());
   }
   //背景色を調理完了かどうかで色分け
   if(pastOrder.isCompleted()){
    convertView.setBackgroundColor(COMPLETE_COLOR);
    Log.v("Adapter", position+"\t"+"comp"+"\t"+pastOrder.getOrder());
   }else{
    convertView.setBackgroundColor(UNCOMPLETE_COLOR);
    Log.v("Adapter", position+"\tuncomp"+"\t"+pastOrder.getOrder());
   }
  }
  return convertView;
 }
}


5.ListViewActivity
ListViewに貼付けるデータの生成
アダプターのセット

protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.past_order);
 //リストに貼付けるデータの作成
 List pastOrderList = createPastData2(result);
 //過去のオーダ情報をレイアウトに表示
 setPastOrderToView3(pastOrderList);
}
private List createPastData2(JSONArray jArr){
 //TODO PastOrderクラスのインスタンスを登録する
 List pastOrderList = new ArrayList();
 JSONObject jObj;
 for(int i = 0; i < jArr.length(); i++){
  try {
   jObj = jArr.getJSONObject(i);
        //---------------------------
        //ここでPastOrderインスタンスを作成し、リストに登録していく
   String order = jObj.getString("order");
   String num = jObj.getString("num");
   Long dateLong = jObj.getLong("date");
   Date date = new Date(dateLong);
   boolean completed = jObj.getBoolean("completed");
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd  HH:mm:ss", Locale.JAPAN);    
   PastOrder pastOrder = new PastOrder(order, num, sdf.format(date), completed);
   pastOrderList.add(pastOrder);
        //---------------------------
  } catch (JSONException e) {
   e.printStackTrace();
  }
 }
 return pastOrderList;
}
private void setPastOrderToView3(List pastOrderList){
 Log.v("Adapter", pastOrderList.size()+"-------");
 mOrderArrayAdapter = new OrderArrayAdapter(this,pastOrderList);
   //---------------------------
   //アダプターをセットする!正直メソッドにする必要はないッ!!!
 setListAdapter(mOrderArrayAdapter);
}
ほぼ、この流れで「オブジェクトをListViewに貼付けて、オブジェクトごとに背景色を塗り分ける」という処理が実装できるはず。
何かコメントなどあればお願いします。
(※いろいろ消してるのでたぶんこのままでは動きません)