Java初心者による携帯アプリ作成講座その8::ネットワークに接続する(後編)

By uchida - 08/12/19 - このエントリをはてなブックマークに追加このエントリをYahoo!ブックマークに追加このエントリをdel.icio.usに追加このエントリをFC2ブックマークに追加

前編に引き続きiアプリでネットワークに接続する方法を解説します。
まずネットワークに接続する必要があります。当たり前ですが、サーバーが必要です。
また、サーバーサイドで動作するプログラムも必要になり、本稿ではPHPを使用しています。


今回はサンプルプログラムに沿って解説を行います。
サンプルプログラムの概要ですが、以前スクラッチパッドを使用してメモ張を作成したものを流用しています。
内容はメモ帳と同じですが、保存場所をスクラッチパッドからサーバーのディレクトリにユーザーごとのテキストファイルを作成し、そこに保存していきます。
 

サーバーサイドプログラムをPHPで作成する

まずはPHPのサンプルからご紹介します。
sample8.php エンコード SJIS

<?php
//パラメータ取得
$type = $_GET['type'];     // 操作タイプ(0:INPUT:1:OUTPUT)
$memo = $_POST['memo'];   // メモ
$id = "sample8";
 
//ファイルを作成する
$file_pass = 'memo/' . $id . '.txt';
if (!file_exists( $file_pass ) ) {
    touch($file_pass);
    chmod($file_pass,0666);
}
 
//ファイル操作
if(!$type){
    //入力
    $fh=fopen($file_pass,"w");
    fwrite($fh,$memo);
    fclose($fh); 
}else{
    //出力
    $fh=fopen($file_pass,"r");
    $data = file($file_pass);
    fclose($fh); 
    for($i=0;$i

 
格納場所は/public_html/imode/sample8.phpとしています。
メモファイルの格納場所は/public_html/imode/mono/にしています。
引数
・type --> 保存・読込の切り分けに使います。
・memo --> iアプリで入力したテキストを渡します。
以上の引数をしようして格納ディレクトリに「固体識別番号」.txtファイルを保存していきます。
PHPに関する解説は今回省かせて頂きます。
概要としまして、GETで入力・出力を制御しています。
また、POSTでiアプリで入力したテキストデータを取得しています。
 

ネットワークに接続するiアプリプログラムを作成する

それでは、iアプリ側のプログラムを作成していきます。
 

/* sample8
 *
 * @author NAME
 */
 
//インポート
import com.nttdocomo.ui.*;
import com.nttdocomo.net.*;
import com.nttdocomo.io.*;
import javax.microedition.io.*;
import java.io.*;

public class sample8 extends IApplication {
  public void start() {
      // panelオブジェクト生成
      MainPanel w_panel = new MainPanel(this);

      // ソフトキー1ラベルに"クリア"を設定
      w_panel.setSoftLabel(w_panel.SOFT_KEY_1,"クリア");

      // ソフトキー2ラベルに"終了"を設定
      w_panel.setSoftLabel(w_panel.SOFT_KEY_2,"終了");

      // mycanvasオブジェクトを画面にセット
      Display.setCurrent(w_panel);
  }
}

class MainPanel extends Panel implements ComponentListener, SoftKeyListener {
    // 変数宣言
    IApplication iapp;
    private Label        w_label;
    private TextBox      w_text;
    private Button       w_button1;
    private Button       w_button2;
    private Dialog       w_dialog;
    private HTMLLayout   w_layout;

    public MainPanel(IApplication ap) {
        // アクションを退避
        this.iapp = ap;
        
        // オブジェクトの生成
        w_label   = new Label("文字を入力:");
        w_text    = new TextBox("", 20, 7, TextBox.DISPLAY_ANY);
        w_button1 = new Button("保存");
        w_button2 = new Button("読込");
        w_dialog  = new Dialog(Dialog.DIALOG_INFO,"INFO");
        w_layout  = new HTMLLayout();
        
        // 画面にオブジェクトをセット
        this.setLayoutManager(w_layout);
        w_layout.begin(HTMLLayout.CENTER);
        this.add(w_label);
        w_layout.br();
        this.add(w_text);
        w_layout.br();
        this.add(w_button1);
        this.add(w_button2);
        w_layout.br();
        w_layout.end();

        // タイトルセット
        setTitle("Sample Program");

        // リスナーをインスタンス生成
        setSoftKeyListener(this);
        setComponentListener(this);
    }
    
    // コンポーネントイベント発生時に実行
    public void componentAction(Component w_component, int w_type, int w_param){
        if((w_component == w_button1) && (w_type == this.BUTTON_PRESSED)){
            
            //保存
            String w_memo = "memo=" + w_text.getText();
            byte[] w_data = w_memo.getBytes();
            try{
                HttpConnection httpc = (HttpConnection) Connector.open(iapp.getSourceURL() + "/imode/sample8.php?type=0"
                                        ,Connector.READ_WRITE, true);
                httpc.setRequestMethod(HttpConnection.POST);
                httpc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                OutputStream ops = httpc.openOutputStream();
                ops.write(w_data, 0, w_data.length);
                ops.close();
                httpc.connect();
                
                httpc.close();
            }catch(Exception e){
                System.out.println(e.toString());
            }
        }
        if((w_component == w_button2) && (w_type == this.BUTTON_PRESSED)){
            
            try{
                //読込
                HttpConnection httpc =(HttpConnection) Connector.open(iapp.getSourceURL() + "/imode/sample8.php?type=1"
                                                                    ,Connector.READ, true);
                httpc.setRequestMethod(HttpConnection.GET);
                httpc.connect();
                
                int respCode=httpc.getResponseCode();
                String respMsg = httpc.getResponseMessage();
                long contentLength = httpc.getLength();
                
                if(respCode==HttpConnection.HTTP_OK){
                    byte rcvData[] = new byte[(int)contentLength];
                    InputStream ips = httpc.openInputStream();
                    ips.read(rcvData);
                    ips.close();
                    
                    w_text.setText(new String(rcvData));
                }
                httpc.close();
            }catch(Exception e){
                System.out.println(e.toString());
            }
        }
    }
    
    public void softKeyPressed(int key) {
        switch (key) {
            case Frame.SOFT_KEY_1:
                textClear();
                break;
            case Frame.SOFT_KEY_2:
                iapp.terminate();
                break;
        }  
    }
    
    public void softKeyReleased(int arg0) 
    {
        
    }
    
    // テキストフィールドクリア処理
    public void textClear(){
        w_text.setText("");
    }
}

 
少しサンプルが長くなってしまいました。。。
概要としまして、保存はPOSTで読込はGETリクエストしています。
テキストデータの保存先は/public_html/imode/memo/以下になります。
 
まず、ネットワークを使用する為、以下をインポートします。

import com.nttdocomo.net.*;
import com.nttdocomo.io.*;
import javax.microedition.io.*;
import java.io.*;

 
次にパネルクラスにComponentListenerを実装します。これはスクラッチパッドを使用する時にも実装したものです。
 
保存時の解説
では、ネットワークを使用している箇所の解説を致します。メソッドの説明は前編を参照下さい。
まずは保存時のロジックです。

HttpConnection httpc = (HttpConnection) Connector.open(iapp.getSourceURL() + "/imode/sample8.php?type=0"
                                                                                   ,Connector.READ_WRITE, true);

保存時のネットワークコネクションを作成します。引数にURLを渡すのですが、iアプリクラスのgetSourceURLでダウンロード元のアドレスを取得し、その後ろにサーバーサイドプログラムパスの続きをつなげています。また、?以下でGETパラメータを指定しています。ここでは0:保存を設定しています。
 

httpc.setRequestMethod(HttpConnection.POST);
httpc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

コネクションのリクエストの設定を行っています。ここではPOSTリクエストと属性を"Content-Type", "application/x-www-form-urlencoded"に設定しています。これにより、POST値にKEYとなる名称と値をそれぞれ分けてサーバーに送信することができます。
 

OutputStream ops = httpc.openOutputStream();
ops.write(w_data, 0, w_data.length);
ops.close();

POST値の設定を行っています。w_dataにiアプリで入力したテキストにmemoという名称を与えています。
最後はかならずcloseしてください。
 

httpc.connect();               
httpc.close();

今まで設定したコネクションでサーバーに接続します。
最後にコネクションをcloseしています。
 


 
読込時の解説
 

HttpConnection httpc =(HttpConnection) Connector.open(iapp.getSourceURL() + "/imode/sample8.php?type=1"
                                                                                 ,Connector.READ, true);
httpc.setRequestMethod(HttpConnection.GET);
httpc.connect();

保存時と同じでまずコネクションを作成します。URLには同じプログラムパスを指定し、GETのtypeに1:読込を指定しています。
リクエストはGETにして、サーバーに接続します。

int respCode=httpc.getResponseCode();
String respMsg = httpc.getResponseMessage();

サーバーからのレスポンスを取得します。getResponseCodeで成功か失敗かを取得して、getResponseMessageでリターン値を取得しています。
 

if(respCode==HttpConnection.HTTP_OK){
  byte rcvData[] = new byte[(int)contentLength];
  InputStream ips = httpc.openInputStream();
  ips.read(rcvData);
  ips.close();

  w_text.setText(new String(rcvData));
}

接続に成功した場合iアプリのテキストにリターン値をセットします。
 

httpc.close();

最後にコネクションをcloseして終了です。


これで一通りの解説は終わりになります。このプログラムにはユーザーごとにテキストファイルの切り分けはできません。
固体識別番号などにより実現できると思うのですが、解説が長くなりすぎるのでまた後日解説できればと思います。