2013年5月28日火曜日

「条件によってボタンを差し替える」…ように見せる

入社2年目、システム開発部 中嶋です。

今回は「条件によってボタンを差し替える」…ように見せる実装方法です。
ボタンのStyleリソースを用意していれば、「setBackgroundResource」で条件によってスタイルを変更することができます。
しかし、Styleリソースを使わずに行う方法もあります。
用意するのが面倒くさい時など使える場面は限られるかもしれませんが、知っておいて損はないと思うのでご紹介します。

■動作イメージ
・「中①」ボタンを押下すると、「中①」ボタンが「中②」ボタンに変化
・「中②」ボタンを押下すると、「中②」ボタンが「中①」ボタンに変化
・「A」ボタンを押下すると、「A」ボタンが「B」ボタンに変化
・「B」ボタンを押下すると、「B」ボタンが「A」ボタンに変化

■XMLレイアウト

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/buttonLeft"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="左" />

        <Button
            android:id="@+id/buttonCenter1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="中①" />

        <Button
            android:id="@+id/buttonCenter2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="中②" />

        <Button
            android:id="@+id/buttonRight"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="右" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center" >

        <Button
            android:id="@+id/buttonA"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="A" />

        <Button
            android:id="@+id/buttonB"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="B" />
    </LinearLayout>

</LinearLayout>

■Javaソース(一部)
※setVisibilityのパラメタの説明
VISIBLE:表示
INVISIBLE:非表示
GONE:無かったことにする

onCreate内
  // 初期は「中②」を非表示にする
  buttonCenter2.setVisibility(View.GONE);

  // 初期は「B」を非表示にする
  buttonB.setVisibility(View.GONE);

onClick内
  // 「中①」押下時
  if (v == buttonCenter1) {
   buttonCenter1.setVisibility(View.GONE);
   buttonCenter2.setVisibility(View.VISIBLE);
  }

  // 「中②」押下時
  if (v == buttonCenter2) {
   buttonCenter1.setVisibility(View.VISIBLE);
   buttonCenter2.setVisibility(View.GONE);
  }

  // 「A」押下時
  if (v == buttonA) {
   buttonA.setVisibility(View.GONE);
   buttonB.setVisibility(View.VISIBLE);
  }

  // 「B」押下時
  if (v == buttonB) {
   buttonA.setVisibility(View.VISIBLE);
   buttonB.setVisibility(View.GONE);
  }
■もう少し説明
【View.GONE】で片方が消えた後、
【layout_weight】の動きによって幅が自動的に調整されます。
ユーザーは片方のボタンずつしか目にしないので、
「同じ位置にあるボタン」が「刺し変わっているように見える」はずです。

2013年5月24日金曜日

Java Day Tokyo 2013



Java Day Tokyo 2013 に行ってきました。
その時のレポートを書きたいと思います。




まずはキーノートです。
これからはJava ME Embedded。小型の組み込み市場への導入を加速させる。
それは昔、サーバーの市場をJavaEEで満たしたように。とおっしゃっていました。
期待しましょう。

それとJDK8の話をしていました。
正式版のリリース予定は2014年2月で、今後は2年サイクルでメジャーバージョンを
上げていく予定との事です。JDK9は2016年2月ということになります。

JDK8に組み込まれた主要なものとしてラムダ(Lambda)式の導入がありました。
ラムダ式というとコードをより簡素にスマートに記述できるのがメインであると感じられるが
実際はもっと重要な効果があるようです。
それは今時のコンピューターにはマルチコアなCPUが当たり前で、同時に複数の処理をこなす
事があたりまえの時代なのですが、ラムダ式の効果は「もっと効率的にCPUを使おうよ」
ということらしいです。それもThreadのような大きな単位ではなくてもっと細かい処理の単位で
パラレル処理が行えるようです。

ラムダ式については試してみたいと思っています。
JDK8のearly releaseが以下からダウンロードできます。
https://jdk8.java.net/download.html


あとは、JavaFX。
JavaFXがJavaの標準GUIライブラリとして採用されましたので、デスクトップアプリケーション等の
UIはJavaFXで書くことになっていくのかなと思いました。
数年前に名前を聞いたっきりあまり聞かなかったのですが、JDKの標準に組み込まれ更に進化
していたようでこれも少し興味がわいてきました。
JavaFXスクリプトで記述する必要があったのですが、もうそのスクリプトは廃止されJavaのAPIとしてJavaFXが使えるようになったようです。

・多彩なGUI部品を持っています。例えばチャートなど
・ハードウェアアクセラレーションを使った高速なレンダリング
・H.264のサポート、動画再生のAPI
面白そうですね。


最後にJaveEEでWebSocketに対応する(JavaEE7 finalリリースはあと少し)との事です。
今までサーバーから情報をクライアントに渡す場合(PUSH)、クライアントからしか接続
できないので、ポーリングやロングポーリング等で「ごまかしていた」わけです。
それがwebSocketにより完全な全二重通信が可能になるわけですね。
webSocketは当然httpとは別のプロトコルなので、http通信をトリガとしてプロトコルを
upgradeしてあげる必要があります。
httpヘッダの最初の要求には

Upgrade: websocket
Connection: Upgrade

と書かれてます。これがhttpプロトコルをwebsocketプロトコルにupgradeするということです。
upgradeされたらhttpのプロトコルに従う必要はなくなるわけです。
例えばhttp requestに対して必ずhttp responseを返す等というルールに従う必要はありません。
サーバーが一方的にクライアントに対してデータを定期的に送りつけるという事ができます。

websocketを使うと通信のオーバーヘッドがとても少なくすみ効率的です。
Arun Guptaさんは実際にエコーサーバーを使ってどれだけの違いがあるか試して頂けました。

100byteのペイロードを1000回エコー要求した場合
http req/resp では8198msec
websocket では      248msec
8.2秒と0.2秒。ここまで差がついてしまうとは驚きでした。

glassFish4.0等で試す事ができますので興味ある方はどうぞ。


最後にJJUGグループに参加して皆でjavaを創っていきましょう!とのことでした。

日本JJUGグループ
http://www.java-users.jp/


それでは失礼致します。

2013年5月17日金曜日

Android Studio を使ってみる


Android Studio は、JetBrains 社の IntelliJ IDEA をベースに作られた、 Android のための新しい開発環境で、「Google I/O 2003」の基調講演で発表され、現在、early access preview がダウンロード可能になっています。

早速使ってみます。
 ( インストールする端末: Windows 7 64bit )

■ インストール
  1. http://developer.android.com/sdk/installing/studio.html より EXE ファイルをダウンロードする。
  2. EXE ファイルを実行し、setup wizard にしたがってインストールする
■ Android Studio 起動
    前のバージョンをインストールしている場合、設定をインポートできるようです。今回初めてインストールしたので、↓の選択肢を選びます。









    ■ Eclipse のプロジェクトを移植
    1. Eclipse から Export する
      1. Eclipse ADT Plugin をアップデート ( Ver. 22.0 以上にする )
      2. Eclipse のメニュー「File」 ⇒ 「Export」 を選択
      3. Android を展開し、Generate Gradle build files を選択








      4. Export したいプロジェクトにチェックを入れて「Finish」 をクリック
      5. ※ Export したプロジェクトは、同じ場所に残ったまま、build.gradle ファイルが作成される

    2. Android Studio へ Import する
      1. Android Studio のメニュー「File」 ⇒ 「Import Project」 を選択
      2. Eclipse から Export したプロジェクトのルートディレクトリを選択し、「OK」をクリック
      3. 「Create project from existing sources」を選択し、「Next」をクリック
      4. 「Next」を押し続ける

    ■ テーマを黒にする方法
    1. メニュー「File」 ⇒ 「Settings」 を選択
    2. 「Appearance」を選択 ⇒ 「Theme」を Darcula に変更











    少し使ってみて便利な機能がいくつかありました。

    ・ Preview で、「Preview All Screen Sizes」を選択するいろいろな画面でのレイアウトのプレビューがライブで表示できる。





















    ・ レイアウト xml で、レンダリング時の問題点が表示され、クリックすると補完できる。
     下記のように、<Button/> と入力すると、必須のattributes が抜けているので、設定するための選択肢が表示される。















    ・ コード内で画像を使用していると、左側に表示される。








    ショートカット一覧
















    参考

    http://developer.android.com/sdk/installing/studio.html
    http://developer.android.com/sdk/installing/migrate.html
    http://developer.android.com/sdk/installing/studio-tips.html
    http://android-developers.blogspot.jp/2013/05/android-studio-ide-built-for-android.html

    - 追記
    Java 7だとインストールに失敗するという話があったので調べました。
    JDK_HOME, JAVA_HOME を設定するとよいそうです。
    http://stackoverflow.com/questions/16574189/android-studio-installation-on-windows-7-fails-no-jdk-found


    2013年5月10日金曜日

    公開鍵暗号方式によるセキュリティ基盤(PKI)



    最近「公開鍵とかって何なんですか?」と質問されたのでそれについて書きたいと思います。
    どちらかというとインフラ系の話になってしまいます。

    ■PKIとは何でしょうか?

     Public Key Infrastructure
     公開鍵暗号方式によるセキュリティ基盤
     ~~~~~~~~~~

     ⇒なんだか難しそうですが名前からして「公開鍵」がキーワードなんでしょうか。


    ■PKIでどの様な効果を得る事ができるのか?

     PKIによって得られる効果は

     (a)データの暗号化
       ●機密性…データの暗号化を行うことで盗聴の脅威を防ぐ。

     (b)デジタル署名
       ●認証…その人が誰であるかを証明する。(なりすましを防ぐ)
       ●完全性…データが変更(改ざん)されていない事を証明する。
       ・否認防止…自分が行った行為を否認できなくする。(行動を証明する)
        (否認とは例えば、ネットショッピングしたのにそんなの買ってないと言い張る等)

     ⇒データの暗号化はイメージが湧きますがデジタル署名の
      なりすましを防ぐとか、データの改ざんを防ぐとか、行動の証明
      ってどういう事なんでしょうかね?


    ■データの暗号化方式

     暗号化方式は大別すると2種類ある

     (a)共通鍵暗号方式

      通信し合う者同士が同じ鍵を持ち暗号化する方式。

      ⇒例えばお客様に設計書ファイルをメールに添付して渡す際は
       設計書ファイルを圧縮してパスワードをかけたりします。
       そしてパスワードのかかった設計書とパスワードをお客様に渡して
       お客様にパスワードを解除してもらいます。

       これで安全に設計書がお客様の手元に渡ると思っていたのですが
       いろいろ調べていくと本当に安全なのかと思いました。
       もし、パスワードのかかった設計書とパスワード両方を悪人にとられたら
       もうアウトです。

       ※共通鍵暗号化方式の弱点が見えてきました。
       ネットワーク越しに鍵(パスワード)を配送すると、その鍵がとられたら終わりという事です。

       どうしましょうか。。そこで公開鍵の登場です。


     (b)公開鍵暗号方式 ※PKIは公開鍵暗号方式によるセキュリティなのでこの方式は重要です。

      この方式は共通鍵暗号化方式の弱点を克服しています。
      どういう方式かというと、特殊な鍵を使います。
      それは「公開鍵(PublicKey)」「秘密鍵(PrivateKey)」という2種の鍵を使用するということです。
      「片方の鍵で暗号化したデータを、もう片方の鍵で復号化する」これ以上の性質はない。

      ○○○ & 公開鍵 = ▼◎■×● <============> ▼◎■×● & 秘密鍵 = ○○○
      (双方向で可能です)

      ※この鍵の凄いところは「鍵Aで暗号化したデータを鍵Aで複合化できない」というところです。
       「鍵Aで暗号化したデータは鍵Bでしか複合化できません」凄い鍵が発明されました!

       この2つの鍵は「キーペア」と呼ばれます。

       例えばサーバーに対して安全にデータを送信したい場合、サーバーに2つの鍵を
       格納しておきます。
       クライアントはサーバーに暗号化されたデータを渡す為に、まずサーバーから鍵を
       1つもらいます。
       クライアントは自分が持っているデータをサーバーからもらった鍵で暗号化します。
       この暗号化されたデーターをネットワークに流してサーバーに届けます。

       もし悪人がネットワークを盗聴していて、サーバーからもらった鍵と、暗号化されたデータが
       盗まれた場合どうなりますか?
       答えは全く問題ありません。何故なら盗んだ鍵では暗号化されたデータを
       複合化できないからです。

       サーバーに渡ってきた暗号化されたデータはもう一方の鍵で複合化され、
       安全にデータを渡す事ができます。

       もしサーバーに格納されているもう一方の鍵が盗まれたら完全にアウトなのでこれは
       厳重に管理する必要があります。

       サーバーに格納しているキーペアの内、クライアントに渡す用の鍵を「公開鍵」と呼びます。
       公開なので誰でもその鍵を入手できるという事です。
       もう一方の鍵は「秘密鍵」と呼びます。これは絶対に誰にも渡してはいけません。


     ※ちなみに馴染みの深いSSL。例えばブラウザでネットバンキング等を利用する時に
      URLの頭にhttpsという文字列がついていますよね。
      このhttpsはネットワークに流すデータを安全に通信するため暗号化を行っている。
      というところまではご存知かと思いますが、どういう仕組みなのかはよくわかりません。

      答えはもう皆さまご存じの「共通鍵暗号方式」と「公開鍵暗号方式」を組み合わせて
      使っています。
      「公開鍵暗号方式」だけでは不十分で「共通鍵暗号方式」の要素も必要なのです。

      何故、公開鍵暗号化方式だけでは駄目なのか。じっくり考えてみて下さい。

      答えは・・・この辺に分かり易く書かれています。
      http://itpro.nikkeibp.co.jp/article/COLUMN/20071012/284424/


    ■セキュアハッシュ関数

     公開鍵暗号方式を用いたデジタル署名の実現のための重要な関連技術に
     「セキュアハッシュ関数」があります。

     [ポイント]
      ①可変長のデータから固定長のビット列を生成する。
      ②その固定長のビット列を「ダイジェスト」という。(ダイジェスト=ハッシュ値)
      ③ダイジェストから元のメッセージを算出することはできない(不可逆)。
      ④2つの異なるデータから、同じダイジェストが生成されることがある。
       これをコリジョン(衝突)と言う。

     [ハッシュ方式]
      ①MD5…128byteのダイジェストを生成する。
      ②SHA1…160byteのダイジェストを生成する。


    ■デジタル署名

     [目的]
      ・データの完全性(改ざんされた場合の検知)
      ・データ作成者の認証

     [流れ]
      【送信者A】
       送信者は予めAの公開鍵をCAに提出し、Aの情報にCAの署名が付いた「証明書」を
       発行してもらいます。
       ①Aは、データのダイジェスト(=ハッシュ値)を生成する。
       ②Aは、ダイジェストをAの秘密鍵で暗号化する。
       ③Aは、データ(平文)にデジタル署名を付与し相手に送信する。
        恐らく、デジタル署名=公開鍵証明書(X.509形式)のことで、
        公開鍵証明書とはCAから署名されたAの公開鍵証明書である。
        (公開鍵証明書の最後の項目に署名アルゴリズムと署名値を設定するところがある。)
        (署名値とは、②でダイジェストを暗号化した値のこと)
        (詳しくは、http://www.ipa.go.jp/security/pki/033.htm)
       ※注意! デジタル署名でデータが暗号化されるわけではありません!

      【受信者B】
       ①Bは、Aからデジタル署名されたデータを受信する。
       ②Bは、デジタル署名から「Aの公開鍵」と「暗号化されたダイジェスト」を取り出す。
       ③Bは、暗号化されたダイジェストをAの公開鍵で復号し、「ダイジェスト」を取得する。
       ④Bは、Aから受信したデータ(平文)のダイジェストを生成し、③のダイジェストと
        一致しているか検証する。

       一致していればデータの改ざんは無いという事がいえます。

       ポイントはAがデータのダイジェストを秘密鍵で暗号化して、Bに対して
       「データ(平文)」「秘密鍵で暗号化されたダイジェスト」「Aの公開鍵」を渡すところです。
       ん?「秘密鍵で暗号化されたダイジェスト」「Aの公開鍵」を渡すと言う事は
       暗号化されたデータとパスワードを一緒に渡している様なもので、
       そもそも暗号化する必要ないのでは?
       と思いがちですがこれは重要な意味を持っています。

       この本来の目的はデータの改ざんがないよね?ということを検証する。
       では「データ(平文)」と「暗号化していないダイジェスト」を送った場合、
       「データ(平文)」と同時に「暗号化していないダイジェスト」も一緒に改ざんされたら
       終わりです。
       それを防止するために「秘密鍵で暗号化されたダイジェストを公開鍵で複合できれば
       ダイジェストは改ざんされていないと言えます」

       ここで更に、全く別の秘密鍵と公開鍵ですり替えられた場合どうなるのか?

       そんな不安を解消するためにBは公開鍵が本当にAの公開鍵である事を
       検証する必要があります。
       Aの公開鍵がBの信頼している人に署名されていれば安心です。
       信頼している人は有名なベリサイン等です。


     [署名アルゴリズム]
       署名アルゴリズムで代表的なものは「公開鍵暗号化をRSAで行いSHA1でハッシュする」
       です。公開鍵暗号化はRSA以外にもDSAやECDSAがあり、MD5のハッシュも有名です。


    ■認証モデル

     相手の公開鍵が本物であるか判断するための認証について2つのモデルがある。
     (a)PGPモデル
      公開鍵の所有者を信頼できる人物に保証してもらう方法です。
      Aさんが未知のCさんの公開鍵を取得したい場合、AさんとCさんの双方と信頼関係にある
      Bさんが、Cさんの公開鍵に署名を付けてAさんに送付します。
      主体が存在しないため企業や組織向けではありません。

     (b)認証局モデル
      信頼できる第三者機関(TTP:TrustedThirdParty)に公開鍵の所有者を保証してもらう方法。
      認証局はパブリックCAとプライベートCAがあります。
      パブリックCAとはベリサインやグローバルサインの有名どころです。
      企業の独自CAはプライベートCA(おれおれ認証局)と言われます。

      ブラウザでhttps通信するとたまに
     このサイトのセキュリティ証明書は信頼できません
      と言われる事があります。これは、プライベートCAが署名した証明書をもつサイトであり、
      ブラウザがこのCAを信用できないためユーザに警告しているのです。
      ユーザは、信用できるCAであるとわかっているのに毎度警告されるのが嫌であれば
      プライベートCAのCA証明書をもらってブラウザにインポートして下さい。
      するとブラウザはこのCAが署名した証明書を全て信頼します。



    ■最後に

     公開鍵による暗号化とデジタル署名の理解が少しでも深まればより安全にネットを
    利用できるのではないかと思います。


    参考
    http://www.ipa.go.jp/security/pki/032.html
    http://www.ipa.go.jp/security/pki/033.html
    http://www.techscore.com/tech/J2EE/Servlet/11-4.html
    http://itpro.nikkeibp.co.jp/article/COLUMN/20071012/284424/
    http://www.net.c.dendai.ac.jp/~kousu/sotsuken.htm