2016年1月2日土曜日

android:Googleトレンドから急上昇ワードを取得する

androidアプリ内でGoogleトレンドの急上昇ワードを扱う。
  • Googleトレンドへのアクセスは、AsyncTaskLoaderを使用して非同期で通信する。
  • Googleトレンドから取得したXMLのパースはXmlPullParserで解析する。
  • 取得したワードはリストビュー(ListView)で表示する。

MainActivity


package net.kuttya.googletrendaccesssample;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Xml;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import org.xmlpull.v1.XmlPullParser;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<String> {
    private final String GOOGLETREND_URL = "http://www.google.co.jp/trends/hottrends/atom/hourly";
    private final String ENCODING = "UTF-8";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Googleトレンドからワードを取得(非同期)
        getSupportLoaderManager().initLoader(0, null, this);

    }

    @Override
    public Loader<String> onCreateLoader(int id, Bundle args) {
        // GoogleトレンドにアクセスするAsyncTaskLoaderを返す
        return new HttpAccessingTaskLoader(this, GOOGLETREND_URL);
    }

    @Override
    public void onLoadFinished(Loader<String> loader, String data) {
        // Googleトレンドから取得したXMLから、CDATAの部分を抽出
        String htmlData = getHtmlData(data);

        // CDATAからワードを抽出
        List<String> words = getListData(htmlData);

        // リストビューのアダプタを作成、Googleトレンドのワードを設定
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, words);

        // リストビューにアダプタを設定
        ListView view = (ListView)findViewById(R.id.listView);
        view.setAdapter(adapter);
    }

    @Override
    public void onLoaderReset(Loader<String> loader) {
    }

    /**
     * Googleトレンドから取得したXMLデータから、CDATAの部分を抽出する
     * @param data 解析するXMLデータ
     * @return CDATA内のHTMLデータ
     */
    private String getHtmlData(String data) {
        String htmlData = "";
        try {
            // Xmlパーサで解析
            XmlPullParser xmlPullParser = Xml.newPullParser();
            xmlPullParser.setInput(new ByteArrayInputStream(data.getBytes(ENCODING)), ENCODING);
            int eventType;
            String tagName;
            while((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) {
                if(eventType == XmlPullParser.START_TAG) {
                    tagName = xmlPullParser.getName();

                    // contentタグの中身を抽出する
                    if(tagName.equals("content")) {
                        htmlData = xmlPullParser.nextText();
                        break;
                    }
                }
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }

        return htmlData;
    }

    /**
     * CDATA内のHTMLからワードを抽出する
     * @param htmlData 解析するHTMLデータ
     * @return 抽出したワードのリスト
     */
    private List<String> getListData(String htmlData) {
        List<String> listData = new ArrayList<String>();

        try {
            // HTMLでもXmlパーサで解析可能
            XmlPullParser xmlPullParser = Xml.newPullParser();
            xmlPullParser.setInput(new ByteArrayInputStream(htmlData.getBytes(ENCODING)), ENCODING);

            // content内の構造は下記
            // <li><span><a>データ</a></span></li>
            int eventType;
            String tagName;
            String word;
            boolean inLi = false;
            boolean inSpan = false;
            while((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) {
                switch(eventType) {
                    case XmlPullParser.START_TAG:
                        tagName = xmlPullParser.getName();
                        if(tagName.equals("li")) {
                            inLi = true;
                            break;
                        }
                        if(inLi != true) {
                            break;
                        }

                        // <Li>タグ内部のみ以下を実施

                        if(tagName.equals("span")) {
                            inSpan = true;
                            break;
                        }
                        if(inSpan != true) {
                            break;
                        }

                        // <span>タグ内部のみ以下を実施

                        if(tagName.equals("a")) {
                            // ワードを抽出
                            word = xmlPullParser.nextText();
                            listData.add(word);
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        tagName = xmlPullParser.getName();
                        if(tagName.equals("li")) {
                            inLi = false;
                        }
                        else if(tagName.equals("span")) {
                            inSpan = false;
                        }
                        break;
                }
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }

        return listData;
    }
}



AsyncTaskLoader


package net.kuttya.googletrendaccesssample;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

/**
 * Created by junichi on 2016/01/02.
 */
public class HttpAccessingTaskLoader extends AsyncTaskLoader<String> {
    private String mUrl;

    public HttpAccessingTaskLoader(Context context, String url) {
        super(context);
        mUrl = url;
    }

    @Override
    public String loadInBackground() {
        String result = "";

        try {
            // URL
            URL url = new URL(mUrl);

            // 接続
            URLConnection connection = url.openConnection();

            // 結果を文字列で返す
            BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while((line = br.readLine()) != null) {
                sb.append(line);
            }
            result = sb.toString();
        }
        catch(Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    @Override
    protected void onStartLoading() {
        forceLoad();
    }
}




レイアウト


リストビューだけ。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="net.kuttya.googletrendaccesssample.MainActivity">

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/listView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"/>
</RelativeLayout>



AndroidManifest.xml


パーミッションの追加を忘れずに。
<?xml version="1.0" encoding="utf-8"?>
<manifest package="net.kuttya.googletrendaccesssample"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

</manifest>


実行結果




2015年11月24日火曜日

Linux(CentOS7)にVisual Studio Codeをインストールし、C#アプリを実行する

CentOS7にVisual Studio Codeをインストールし、C#アプリケーションをデバッグする。

動作環境
・CentOS 7
 

インストールするもの

インストールするものは以下。

  • Visual Studio Code 
  • Mono
  • DNVM、DNX
  • Node.js

Visual Studio Code単体ではコンパイルできないため、LinuxでのC#実行環境であるDNX、DNXの動作に必要なMonoのインストールが必要となる。
DNVMは.NETのバージョン管理で、DNXをインストールするのに必要となる。
Node.jsは、Visual Studio Codeのインテリセンスに必要となる。

 

Monoのインストール

MonoをLinuxのインストール用ページに記載されている方法でインストールする。

software.opensuse.org: Install package home:tpokorra:mono / mono-opt

20151121000345

ウェブブラウザで上記のページを開いた後、CentOSをクリックする。
上の画像のように、インストール方法が表示される。
記載されているコマンドを実行する。

% cd /etc/yum.repos.d/
% wget http://download.opensuse.org/repositories/home:tpokorra:mono/CentOS_CentOS-7/home:tpokorra:mono.repo
% yum install mono-opt

monoのインストール中、何度かYes/Noの入力を促されるため、「y 」を入力する。
インストール完了後、環境変数MONO_HOMEを設定し、Monoのコマンドを実行可能にする。


% vi /etc/profile.d/mono.sh

#!/bin/bash
MONO_HOME=/opt/mono
PATH=$PATH:$MONO_HOME/bin
export PATH MONO_HOME
export CLASSPATH=.


設定用のシェルに実行権限を与える。

% chmod +x /etc/profile.d/mono.sh

環境変数を有効にする。


% source /etc/profile.d/mono.sh


インストールが完了していることの確認として、バージョンを表示する。


% mono --version


 


DNVM、DNXのインストール


DNVMを下記のコマンドでインストールする。


% curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh


インストールが完了していることの確認として、バージョンを表示する。


% dnvm -v


 


DNXを下記のコマンドでインストールする。


% dnvm upgrade -r mono


インストールが完了していることの確認として、バージョンを表示する。


% dnx --version


 


Node.jsのインストール


Node.jsを下記のコマンドでインストールする。


% yum install epel-release
% yum install nodejs


インストールが完了していることの確認として、バージョンを表示する。


% node -v


 


Visual Studio Codeのインストール


VisualStudioのサイトからダウンロードする。


Visual Studio Code - Code Editing. Redefined.


 20151122145155


ダウンロード後、zipファイルを展開する。
展開したディレクトリ内の「Code」というシェルファイルを実行することによって、VisualStudioCodeが起動する。


 20151123004245


 


C#プロジェクトの作成、実行、デバッグ


ここから、C#アプリケーションのプロジェクト、コードを作成する。


Visual Studio Codeの左上のアイコン「Explore」を押し、「Open Folder」を押す。
任意のフォルダを作成する。
ここでは、「HelloWorld」というフォルダを作成することにする。


作成したフォルダ名の横のアイコン「New File」を押し、csファイルを作成する。
ここでは、「HelloWorld.cs」というファイルを作成することにする。


HelloWorld.csに下記のコードを記述する。



using System;

namespace HelloWorld
{
public class HelloWorld
{
static public void Main()
{
Console.WriteLine("Hello World");
Console.ReadKey();
}
}
}


次に、作成したフォルダ名の横のアイコン「New File」を押し、csprojファイルを作成する。
ここでは、「HelloWorld.csproj」というファイルを作成することにする。


HelloWorld.csprojに下記の設定内容を記述する。



<Project DefaultTargets = "Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!-- Specify the inputs by type and file name -->
<ItemGroup>
<CSFile Include = "HelloWorld.cs"/>
</ItemGroup>

<Target Name = "Build">
<!-- Run the Visual C# compilation using input files of type CSFile -->
<CSC Sources = "@(CSFile)"
DebugType="full"
Optimize="no"
OutputAssembly="HelloWorld.exe" >

<!-- Set the OutputAssembly attribute of the CSC task to the name of the executable file that is created -->
<Output TaskParameter="OutputAssembly"
ItemName = "EXEFile" />
</CSC>
</Target>
</Project>


 


プロジェクトファイルができたので、ビルドする。
Ctrl+Shift+pを押すと、コマンド入力欄が表示される。
「build」と入力し、「Run Build Task」を押す。
続けて、「Configure Task Runner」を押すと、「tasks.json」ファイルができる。


「tasks.json」ファイルは、プロジェクトをコンパイルするタスクの設定を書いておくファイル。
このファイル内を「CSC」で検索し、CSC用の設定のコメントアウトを解除して、有効化する。
(本記事の執筆時点では、109行目から128行目のコメントアウトを解除した。)
初期状態ではTypescript用の設定が有効化されているが、これはコメントアウトして無効化する。
さらに、「command」が「msbuild」となっている箇所を、「xbuild」に変更する。変更すると、下記のようになる。


{
"version": "0.1.0",
"command": "xbuild",
"args": [
// Ask msbuild to generate full paths for file names.
"/property:GenerateFullPaths=true"
],
"taskSelector": "/t:",
"showOutput": "silent",
"tasks": [
{
"taskName": "build",
// Show the output window only if unrecognized errors occur.
"showOutput": "silent",
// Use the standard MS compiler pattern to detect errors, warnings
// and infos in the output.
"problemMatcher": "$msCompile"
}
]
}

再度、Ctrl+Shift+p、「build」を入力し、「Run Build Task」を押す。
ビルドが成功し、「HelloWorld.exe」が出力される。


20151124214130


次に、デバッグする。
画面左側のアイコン「Debug」を押し、緑色三角のアイコン「Start」を押す。
デバッグの候補がいくつか表示されるので、「C# mono」を選択する。
「launch.json」が出力される。


「launch.json」を下記のように修正する。


{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "mono",
"request": "launch",
"program": "HelloWorld.exe",
"args": [],
"cwd": ".",
"runtimeExecutable": null
//"env": {}
},
{
"name": "Attach",
"type": "mono",
"request": "attach",
"address": "localhost",
"port": 5858
}
]
}

「launch.json」を編集後、再度、「Start」アイコンを押す。
プログラムが実行され、コンソール画面が立ち上がる。


20151124215108


ブレイクポイントを作成していないためこのようになったが、ブレイクポイントを作成しておけば、任意の箇所でブレイクできる。


20151124215707


 


参考:


Visual Studio Code を使ってUbuntu でC# コンソールアプリをデバッグ
CentOS 7 に Node.js をインストールする - Qiita
Installing ASP.NET 5 On Linux — ASP.NET 0.0.1 documentation


 


2015年11月13日金曜日

BaasBoxにDocumentを作成する。

オープンソースmBaasのBaasBoxにドキュメントを作成する。
BaasBoxはドキュメントデータベースを採用しており、作成したドキュメントを検索することもできる。

今回はターミナル上でBaasBoxのREST APIをたたく。

BassBoxのインストールはこちら。
 ちくわのあなから花が咲く。: オープンソースmBaasのBaasBoxをインストールする

 

ログイン

まずはログインから。adminユーザでログインする。

% curl http://localhost:9000/login -d "username=admin" -d "password=admin" -d "appcode=1234567890"

成功すると下記のJSONが返ってくる。

{
"data": {
"X-BB-SESSION": "2ffe6a91-71a6-4345-8a9c-9a227a2017ff",
"signUpDate": "2015-11-08T11:54:56.500+0900",
"user": {
"name": "admin",
"roles": [
{
"isrole": true,
"name": "administrator"
}
],
"status": "ACTIVE"
}
},
"http_code": 200,
"result": "ok"
}


 


コレクションの作成


ドキュメントを作成するコレクションを作成する。
下記では、「sample」というコレクションを作成する。


% curl -X POST http://localhost:9000/admin/collection/sample -H X-BB-SESSION:2ffe6a91-71a6-4345-8a9c-9a227a2017ff


成功すると下記のJSONが返ってくる。



{
"data": "",
"http_code": 201,
"result": "ok"
}

 



ドキュメントの作成


コレクションができたら、コレクションにドキュメントを登録する。
URLに「sample」コレクションを指定する。


% curl -X POST http://localhost:9000/document/sample -d '{"No" : "1", "message" : "Hello."}' -H Content-type:application/json -H X-BB-SESSION:2ffe6a91-71a6-4345-8a9c-9a227a2017ff


成功すると下記のJSONが返ってくる。



{
"data": {
"@class": "sample",
"@rid": "#25:0",
"@version": 1,
"No": "1",
"_author": "admin",
"_creation_date": "2015-11-11T01:03:09.904+0900",
"id": "eee962f4-929e-4377-adcf-e511b29e2e98",
"message": "Hello."
},
"http_code": 200,
"result": "ok"
}


別のドキュメントを作成する。


% curl -X POST http://localhost:9000/document/sample -d '{"No" : "2", "message" : "Hello. Hello."}' -H Content-type:application/json -H X-BB-SESSION:2ffe6a91-71a6-4345-8a9c-9a227a2017ff


成功すると下記のJSONが返ってくる。



{
"data": {
"@class": "sample",
"@rid": "#25:1",
"@version": 1,
"No": "2",
"_author": "admin",
"_creation_date": "2015-11-11T01:04:08.144+0900",
"id": "f50947d4-cde7-4a7b-a017-ed72fae28e79",
"message": "Hello. Hello."
},
"http_code": 200,
"result": "ok"
}

 


ドキュメント数の出力


作成したドキュメント数を出力してみる。


% curl http://localhost:9000/document/sample/count -H X-BB-SESSION:2ffe6a91-71a6-4345-8a9c-9a227a2017ff


成功すると下記のJSONが返ってくる。



{
"data": {
"count": 2
},
"http_code": 200,
"result": "ok"
}

 


ドキュメントの検索


ドキュメントを検索する。「No」が「1」のドキュメントを検索する。


% curl http://localhost:9000/document/sample?where=No='1' -H X-BB-SESSION:2ffe6a91-71a6-4345-8a9c-9a227a2017ff -H X-BAASBOX-APPCODE:1234567890


成功すると下記のJSONが返ってくる。



{
"data": [
{
"@class": "sample",
"@rid": "#25:0",
"@version": 1,
"No": "1",
"_author": "admin",
"_creation_date": "2015-11-11T01:03:09.904+0900",
"id": "eee962f4-929e-4377-adcf-e511b29e2e98",
"message": "Hello."
}
],
"http_code": 200,
"result": "ok"
}

2015年11月9日月曜日

オープンソースmBaasのBaasBoxをインストールする

LinuxにオープンソースmBaasのBaasBoxをインストールする方法を記載する。

動作環境
・CentOS7

インストールするもの

インストールするものは以下。

  • JDK
  • Play Framework 
  • BaasBox

BaasBoxが動作するためには、JavaのフレームワークであるPlay Frameworkをインストールしなくてはならない。
さらに、Play FrameworkはJavaで実装されているため、JDKをインストールしなくてはならない。

なので、通常はJDK→Play Framework→BaasBoxの順でインストールをするのだが、
BaasBoxのReadMeで、JDK、Play Frameworkのバージョンが指定されているため、
先にBaasBoxのダウンロード、インストールを実施する。
BaasBoxのインストールは、JDK、Play Frameworkがインストールされていなくても 可能。

 

BaasBoxのインストール

BaasBoxはターミナル上でダウンロードする。

% wget --content-disposition http://www.baasbox.com/download/baasbox-stable.zip

執筆時点でのバージョンは0.9.4となっている。
ダウンロードされるファイル名は「baasbox-0.9.4.zip」。

Webサイトからもダウンロードできる。

The open source backend for your mobile app | BAASBOX

20151108222737

ダウンロード後、zipファイルを展開する。
展開後、任意のディレクトリに移動してもよい。

% unzip baasbox-0.9.4.zip

展開したディレクトリ内の「start」というシェルファイルを実行することによって、BaasBoxが起動する。
「start」には実行権限がないため、実行権限を与える。

% cd baasbox-0.9.4
% chmod +x ./start
% ./start

この時点では、JDK、Play Frameworkがインストールされていないため、起動しない。

 

JDKのインストール

BaasBoxのディレクトリに、「README.md」が格納されている。
このファイルの中を見てみると、BaasBoxを起動させるために、JDKはバージョン8が必要だと書かれている。
間違ってJREをインストールしないようにとも書かれている。注意すること。

README.mdには、ダウンロード先URLが書かれているため、そこからダウンロードする。

Java SE - Downloads | Oracle Technology Network | Oracle

開いたページの中央右側の「JDK DOWNLOAD」からJDKのダウンロードページに移動する。
「Accept License Agreement」をチェックし、Linuxのrpmファイルをダウンロードする。
執筆時点での最新バージョンは8u65であったため、「jdk-8u65-linux-x64.rpm」をダウンロードした。
(実行環境がが32bitか64bitかによってダウンロードするファイルが異なる)

20151108225801

ダウンロード後、下記のコマンドでインストールする。

% yum localinstall jdk-8u65-linux-x64.rpm

インストール完了後、Javaのバージョンを確認する。

% java -version

筆者の環境では、先にJDK7がインストールされていたため、バージョンが1.7であった。
環境変数JAVA_HOMEを設定し直し、JDK8に切り替える。

% vi /etc/profile.d/java.sh

#!/bin/bash
JAVA_HOME=/usr/java/jdk1.8.0_65
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME
export CLASSPATH=.

設定用のシェルに実行権限を与える。

% chmod +x /etc/profile.d/java.sh

環境変数の変更を反映させるため、OSを再起動する。
再起動後、バージョンが1.8となっていることを確認する。

 

Play Frameworkのインストール

JDKと同様に「README.md」を確認すると、Play Frameworkのバージョンは2.2.4が指定されている。
同じくダウンロード先URLが書かれているため、そこから「play-2.2.4.zip」をダウンロードする。

Downloads

20151108233630

ダウンロード後、zipファイルを展開する。
展開後、作成されたディレクトリを下記のように移動し、リネームする。

% unzip play-2.2.4.zip
% mv play-2.2.4 /usr/local/lib
% cd /usr/local/lib
% ln –s play-2.2.4 play

環境変数PLAY_HOMEを設定し、Play Frameworkのコマンドを実行可能にする。

vi /etc/profile.d/play.sh

#!/bin/bash
PLAY_HOME=/usr/local/lib/play
PATH=$PATH:$PLAY_HOME
export PATH PLAY_HOME

設定用のシェルに実行権限を与え、OSを再起動する。

% chmod +x /etc/profile.d/java.sh

 

BaasBoxの起動、ログイン

下記のディレクトリに移動し、起動シェルを実行する。

% cd baasbox-0.9.4
% ./start

うまく起動していれば、下記URLにアクセスすることができる。

http://localhost:9000/

20151108235225

「Administration Login」をクリックする。

 

20151108235453

下記の様に入力し、「Login」をクリックする。

Username:admin
Passwork:admin
Application Code:1234567890

20151108235728

ログインに成功し、ダッシュボードが表示される。

Documentの作成はこちら。
ちくわのあなから花が咲く。: BaasBoxにDocumentを作成する。

2015年1月4日日曜日

Ruby on Rails 4をWindowsにインストールし、Eclipseで実行する

WindowsにRuby on Rails 4をインストールし、Eclipseで実行する方法を記載する。

動作環境
・Windows7 Ultimate Service Pack 1
・Eclipse 4.4 Luna Pleiades All in One

インストールするもの

インストールするものは以下。

  • Ruby
  • SQLite
  • DevKit
  • Node.js
  • Ruby on Rails 4
  • Eclipse
    Aptana Studio 3プラグイン

 

Rubyのインストール

Ruby Installer for WindowsからRubyをインストールする。

RubyInstaller for Windows
ダウンロードはこちらから。Downloads

ここでは、2.0系のRubyをインストールするため、「Ruby 2.0.0-pXXX」をダウンロードする。
執筆時点での最新版は「Ruby 2.0.0-p598」となっている。

Ruby Installer for Windowsは、通常のRubyウィザード形式でRubyをインストールできる。
「Rubyの実行ファイルへの環境変数PATHを設定する」にチェックを入れておくと、
インストール後に「ruby」コマンドを絶対パスで入力しなくてよい。

インストール完了後、コマンドプロンプトを開き、下記のコマンドを実行する。

 % ruby –v

実行結果は、下記のようになる。

ruby 2.0.0p598 (2014-11-13) [i386-mingw32]

 

SQLite3のインストール

SQLiteはRuby on Railsでアプリケーションを作成するために必要なデータベース。
アプリケーションでデータを扱う際に必要となる。

SQLiteを公式サイトからダウンロードする。

SQLite Download Page

開いたページの中程にある、「Precompiled Binaries for Windows」から
「sqlite-shell-win32-x86-XXXXXXX.zip」をダウンロードする。
執筆時点での最新版は「sqlite-shell-win32-x86-3080704.zip」となっている。

20141228142804

ダウンロードしたファイルを解凍すると、EXEファイル「sqlite3.exe」が格納されている。
EXEファイルを先ほどRubyをインストールしたフォルダ「C:\Ruby200\bin」に格納する。

格納後、コマンドプロンプトを開き、下記のコマンドを実行する。
EXEファイルへのパスは、Rubyのインストール時の設定(「Rubyの実行ファイルへの環境変数PATHを設定する」)により、通っている。

 % sqlite3 -version

実行結果は、下記のようになる。

3.8.7.4 2014-12-09 01:34:36 f66f7a17b78ba617acde90fc810107f34f1a1f2e

 

DevKitのインストール

DevKitはRuby on Railsをインストールするときや、railsコマンドを実行する際に必要となる。

DevKitはRuby Installerと同じWebサイトからダウンロードする。

RubyInstaller for Windows
ダウンロードはこちらから。Downloads

開いたページの下部にある、「DEVELOPMENT KIT」から
「DevKit-mingw64-32-x.x.x-xxxxxxxx-xxxx-sfx.exe」をダウンロードする。
執筆時点での最新版は「DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe」となっている。

ダウンロードしたEXEファイルを実行すると、展開先の入力を求められるので、
「C:\Ruby200\devkit\」を入力し、「Extract」ボタンを押下する。

展開後、コマンドプロンプトで下記のコマンドを実行する。

 % cd c:\Ruby200\devkit
 % ruby dk.rb init
 % ruby dk.rb install

実行結果は下記のようになる。

 % ruby dk.rb init

[INFO] found RubyInstaller v2.0.0 at C:/Ruby200

Initialization complete! Please review and modify the auto-generated
'config.yml' file to ensure it contains the root directories to all
of the installed Rubies you want enhanced by the DevKit.

 % ruby dk.rb install

[INFO] Updating convenience notice gem override for 'C:/Ruby200'
[INFO] Installing 'C:/Ruby200/lib/ruby/site_ruby/devkit.rb'

 

Node.jsのインストール

Ruby on Railsを実行するHTTPサーバとして必要となる。

Node.jsを公式サイトからダウンロードする。

node.js

20140510144810

サイト中央の「INSTALL」から自環境に適したインストーラをダウンロードする。
本稿執筆時、Node.jpの最新バージョンは「0.10.35」であった。

ダウンロードしたインストーラを起動し、インストールを実施する。
ソフトウェアの使用許諾契約やインストール先選択の画面が表示されるが、
画面の指示に従って先へ進んでいく。

「Completed the Node.js Setup Wizard」と記載された画面が表示されれば、インストールは完了。

 

Ruby on Rails 4のインストール

Ruby on Railsはgemコマンドからインストールする。

コマンドプロンプトで下記のコマンドを実行する。

 % gem install rails

コマンド実行後、10分程度の時間をかけてRuby on Railsをインストールする。
環境によっては、コマンド実行がエラーになる場合がある。SSLエラーが発生した場合、下記のサイトを参考にすると解決できる。

Windowsでgem installするとSSLエラーが出る場合の解決策 - Qiita

インストールが成功したことを確認するために、コマンドプロンプトで下記を実施する。

 % rails –v

実行結果は下記のようになる。

Rails 4.2.0

 

Eclipseのインストール

Eclipseは公式サイトからダウンロードすると言語が英語なので、日本語化されたPleiadesからダウンロードする。 

Eclipse 日本語化 | MergeDoc Project

20150104211705

ここでは、Eclipse 4.4 Luna Pleiades All in Oneをダウンロードした。

ダウンロードしたファイルは圧縮ファイルなので解凍する。解凍後のフォルダを格納する場所はどこでもよい。解凍後、「pleiades\eclipse\eclipse.exe」を実行すると、Eclipseが起動する。

 

Aptana Studio 3のインストール

EclipseでRuby on Railsのプロジェクトを作成するために、Aptana Studio 3プラグインをインストールする。

Eclipseのメニュー「ヘルプ」→「新規ソフトウェアのインストール」からソフトウェアのインストール画面を開く。

作業対象の欄に下記のURLを入力する。

 http://download.aptana.com/studio3/plugin/install

表示されたAptana Studioの項目にチェックを入れ、「次へ」ボタンを押下する。
インストール詳細、ライセンスのレビュー画面が表示されるので、指示に従ってインストールを実施する。
セキュリティの警告画面が表示された場合は、「OK」を押下する。

インストール完了後、Eclipseを再起動する。

 

Ruby on Railsプロジェクトの作成

Aptana Studio 3のインストールが完了すると、Ruby on Railsプロジェクトを作成できるようになる。
Eclipseのメニュー「ファイル」→「新規」→「プロジェクト」から新規プロジェクト画面を開く。

image

「Railsプロジェクト」を選択し、「次へ」ボタンを押下する。

image

「新規Railsプロジェクト」画面では、プロジェクト名を入力する。
ここでは、「SampleRails」とした。

image

Webパースペクティブでプロジェクトを開くか聞かれるので、「はい」を選択する。

Ruby on Railsのプロジェクトが作成される。

 

Ruby on Railsプロジェクトの実行

作成したプロジェクトでHTTPサーバを起動する。

Eclipseのメニュー「実行」→「Rails console」からコンソール画面を開く。
下記のコマンドを実行する。

 % rails server

実行結果は下記のようになる。

DL is deprecated, please use Fiddle
=> Booting WEBrick
=> Rails 4.2.0 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2015-01-04 23:41:08] INFO  WEBrick 1.3.1
[2015-01-04 23:41:08] INFO  ruby 2.0.0 (2014-11-13) [i386-mingw32]
[2015-01-04 23:41:08] INFO  WEBrick::HTTPServer#start: pid=6320 port=3000

Webブラウザで下記のURLにアクセスする。

 http://localhost:3000

20150104234556

Ruby on Railsのデフォルトのページが表示される。

2014年12月14日日曜日

Nodeclipseがインストールできない

PCを初期化したので、Node.jsの開発環境を作り直した。

過去記事の通りに環境を作成してみた。
Node.jsをWindowsにインストールし、Eclipseで実行する

Eclipseをダウンロードし、Nodeclipseもインストールしたが、
「新規作成」→「プロジェクト」を選択しても、Node.jsの項目がない。

Nodeclipseのインストールに失敗しているのかと思ったが、
インストールには成功している様子。
新規ソフトウェアのインストール画面でも、インストール済みと表示されている。

Google先生で検索しても、同様の症状が見つからない。

2週間くらい、そこで作業が止まっていたのだが、
何の気なしに新規プロジェクトの選択画面を見ていたら、
「ノード」と日本語で書かれたグループが目にとまった。

もしかして、とグループを展開してみると、
Node.jsのプロジェクトが存在した。

以前にインストールしたときには「Nodeclipse」だったはず。。。

img0018

2014年12月10日水曜日

Eclipseの圧縮ファイルが解凍できない

Eclipseの圧縮ファイルをダウンロード後、任意のフォルダで解凍すると、エラーが発生する場合がある。

次の画像は、解凍ソフトのLhaplusを使用し、解凍結果でエラーが発生した画面である。

img0016

解凍失敗の原因は、「CRCが一致しないか、出力先ファイルが使用中です。」とのこと。
他にも多数のファイルが同じエラーで解凍に失敗している。

CRCが一致しない原因を追及していっても解決しなかった。

ファイル名が長かったり、階層が深いファイルでエラーが発生しているようにも見えるため、
パスの長さが関係していると思うのだが、何が原因なのだろうか。

幸いなことに、Eclipseの圧縮ファイルはZIP形式であるため、
右クリック→「プログラムから開く」→「エクスプローラー」で圧縮ファイルの中身を見ることができる。

そして、中身を適当なフォルダにドラッグアンドドロップすれば、
全ファイルを解凍したのと同じ状態になる。

これでいったん解決。

2014年7月13日日曜日

Node.jsでTwitter APIを使用し、タイムラインを取得する

Node.jsからTwitter APIを使用してみる。
今回は自分のタイムラインを取得する。

動作環境
・Windows7 Ultimate Service Pack 1
・Node.js 0.10.28
・node-twitter 0.2.9

 

2014年7月12日土曜日

Twitter APIを使用するための各種キーの取得

Twitter APIを使用するためには、下記のキーを取得する必要がある。

  • Consumer key
  • Consumer secret
  • Access token
  • Access token secret

 

これらのキーを取得する手順について記載する。

なお、この手順は記事を執筆した2014年7月13日現在のもの。

 

2014年5月24日土曜日

Sails.jsでコントローラを作成する

Sails.jsでコントローラを作成する。

動作環境
・Windows7 Ultimate Service Pack 1
・Node.js 0.10.28
・Sail.js 0.9.16

参考にしたのはこのサイト。

Sails.js | Realtime MVC Framework for Node.js

2014年5月21日水曜日

Sails.jsでのログ出力

Sails.jsでログをファイルに出力する方法を記載する。
Sails.jsのログでは、ログはコンソールに出力するだけで、ファイルには出力されない。
ファイルに出力するために、ここではlog4jsを使用する。

動作環境
・Windows7 Ultimate Service Pack 1
・Node.js 0.10.28
・Sail.js 0.9.16
・log4js 0.6.14

2014年5月14日水曜日

Node.jsのフレームワークSails.jsをEclipseで実行する

Node.jsのフレームワークSails.jsを、Eclipseで実行する方法を記載する。

動作環境
・Windows7 Ultimate Service Pack 1
・Eclipse 4.3 Kepler Pleiades All in One

 

2014年5月11日日曜日

Node.jsのフレームワークExpressをEclipseで実行する

Node.jsのフレームワークExpressを、Eclipseで実行する方法を記載する。

動作環境
・Windows7 Ultimate Service Pack 1
・Eclipse 4.3 Kepler Pleiades All in One

 

2014年5月10日土曜日

Node.jsをWindowsにインストールし、Eclipseで実行する

WindowsにNode.jsをインストールし、Eclipseで実行する方法を記載する。

動作環境
・Windows7 Ultimate Service Pack 1
・Eclipse 4.3 Kepler Pleiades All in One

 

インストールするもの

インストールするものは以下。

  • Node.js
  • Eclipse
    Nodeclipseプラグイン

 

Node.jsのインストール

Node.jsを公式サイトからダウンロードする。

node.js

20140510144810

サイト中央の「INSTALL」から自環境に適したインストーラをダウンロードする。本稿執筆時、Node.jpの最新バージョンは「0.10.28」であった。

ダウンロードしたインストーラを起動し、インストールを実施する。ソフトウェアの使用許諾契約やインストール先選択の画面が表示されるが、画面の指示に従って先へ進んでいく。

「Completed the Node.js Setup Wizard」と記載された画面が表示されれば、インストールは完了。

 

Eclipseのインストール

Eclipseは公式サイトからダウンロードすると言語が英語なので、日本語化されたPleiadesからダウンロードする。 

Eclipse 日本語化 | MergeDoc Project

 

20140511122458

ここでは、Eclipse 4.3 Kepler Pleiades All in Oneをダウンロードした。

ダウンロードしたファイルは圧縮ファイルなので解凍する。解凍後のフォルダを格納する場所はどこでもよい。解凍後、「pleiades\eclipse\eclipse.exe」を実行すると、Eclipseが起動する。

 

Nodeclipseのインストール

EclipseでNode.jsを動作させるために、Nodeclipseプラグインをインストールする。

Eclipseのメニュー「ヘルプ」→「新規ソフトウェアのインストール」からソフトウェアのインストール画面を開く。

作業対象の欄に下記のURLを入力する。

 http://dl.bintray.com/nodeclipse/nodeclipse/

img0001

表示された項目全てをチェックし、「次へ」ボタンを押して進む。
インストール詳細、ライセンスのレビュー画面が表示されるので、指示に従ってインストールを実施する。
セキュリティ警告の画面では「OK」を押す。
インストール完了後、Eclipseを再起動すると、Nodeclipseを使用できる状態となる。

 

Node.jsを実行

インストールが完了すると、Node.js用のプロジェクトを作成できるようになる。
Eclipseのメニュー「ファイル」→「新規」→「プロジェクト」から新規プロジェクト画面を開く。

img0002

「Nodeclipse」の項目の中の「Node.js Project」を選択し、「次へ」ボタンを押して進む。

「New Node.js Project」画面では、プロジェクト名を入力する。

img0003

ここでは、「SampleNodeJS」とした。
「Template to use」の項目では、「Hello World」を選択する。
「完了」ボタンを押すと、プロジェクトの作成が完了する。

自動生成されたファイルのうち、「hello-world.js」にWebサーバを起動するコードが書かれている。
localhostの1337ポートでサーバを起動し、「Hello World」と表示するようになっている。

var http = require('http');
http.createServer(function handler(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');


実際に実行してみる。
メニュー「実行」→「実行」→「Node Application」を実行すると、コンソールに「Server running at http://127.0.0.1:1337/」と表示される。
これで、サーバが起動した。



ブラウザを開き、サーバにアクセスする。ソースコード通りだと、



 http://127.0.0.1:1337/



にアクセスすればよいが、

 http://localhost:1337/

でも同じ。



20140511152622



ブラウザ上には、「Hello World」とだけ表示される。
Node.jsの実行に成功。


2014年2月9日日曜日

CakePHPでマルチパートでないPost通信を受信する

CakePHPでマルチパートでないHTTP-Postリクエストを受信する方法を記載する。

動作環境
・Ubuntu 12.04.3 LTS
・CakePHP 2.4.4
・Apache 2.2.22

Webで実装方法を検索してみたところ、ピュアPHPではすぐに見つかったのだが、CakePHPではなかなか見つけることができなかった。
Webで検索するキーワードが悪かったのかもしれない。

HTTPクライアントはAndroidでHttpURLConnectionを使用した。
サンプルコードはこちら。
androidからAsyncTaskLoaderでHTTP-Post通信をする

 

ピュアPHPの場合

ピュアPHPでPostリクエストのデータを取得する場合は、file_get_contentsメソッドを使用する。

引数に「php://input」を指定する。

リクエストデータは戻り値で取得できる。

<?php
// 受信データ格納
$data = file_get_contents("php://input");

// レスポンス
echo "POST DATA RECEIVED. data[".$data."]"
?>

 


CakePHPの場合


CakePHPでPOSTデータを取得する場合、


 CakeRequest::data[‘key’]


などでデータを取得するが、マルチパートでないPOSTデータの場合、取得できない。
上記の「key」を「php://input」としても取得できない。


といっても、CakePHPのどこかで「php://input」からPOSTデータを取得している箇所があるはずなので、CakePHPのコードを「php://input」で検索してみる。


すると、CakeRequest::_readInputメソッドで「php://input」を使用していた。
_readInputメソッドはprotectedなので、さらに_readInputメソッドを使用している箇所を検索してみる。


_readInputメソッドを使用している箇所は2カ所あったが、CakeRequest::inputメソッドがpublicだったので、ここからPOSTデータを取得できそう。


というわけで、CakeRequest::inputメソッドを使用する。


inputメソッドは引数にデコード用コールバックを指定できるが、省略可能引数となっているため、今回は省略する。


リクエストデータは戻り値で取得できる。


下記のサンプルでは、取得したリクエストデータを、そのままレスポンスデータとして送信している。

<?php
class PostSamplesController extends AppController {
public function index() {
if($this->request->is('post')) { // Post通信
// 受信データ格納
$input_data = $this->request->input();

// レスポンス
$this->response->body($input_data);
return $this->response;
}
}
}
?>

2014年2月8日土曜日

androidからHttpClientでHTTP-Post通信をする

androidでは、HTTP通信をするための方法として、下記のふたつがある。

  • HttpURLConnection (java.net)
  • HttpClient (org.apache.http)

ここでは、HttpClientを使用する方法を紹介する。

HttpURLConnectionとHttpClientの違いについては、下記のサイトが参考になった。
Y.A.M の 雑記帳: Android Apache HTTP Client と HttpURLConnection どっちを使うべき?

HttpURLConnectionを使用する方法は下記を参照。
androidからAsyncTaskLoaderでHTTP-Post通信をする

 

Http通信処理を実現するためには、Androidアプリで下記の3つの部品を実装する。

  • UI処理
  • 通信データ
  • バックグラウンド処理

Androidアプリのマニフェストファイルにインターネット接続のパーミッションを追加すること。

また、サーバ側でも何らかの応答を返す処理を実装する必要がある。

UI処理

アプリケーション実行時に呼び出されるアクティビティ。
ここで通信データを生成し、バックグラウンド処理に渡す。

package net.kuttya.httppostsample2;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;

public class MainActivity extends FragmentActivity implements LoaderCallbacks {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// サーバにデータ送信(初期化)
TransData sendData = new TransData();
Bundle args = new Bundle();
sendData.data = "test";
args.putSerializable("data", sendData);
getSupportLoaderManager().initLoader(0, args, this);
}

public Loader onCreateLoader(int id, Bundle args) {
if( null != args ) {
TransData sendData = (TransData) args.getSerializable("data");

return new HttpAccesser(this, sendData);
}
return null;
}

public void onLoadFinished(Loader loader, TransData recvData) {
// AsyncTaskLoaderの処理が終了したら呼び出される
if(null == recvData) {
return;
}
else {

}
}

public void onLoaderReset(Loader arg0) {
// AsyncTaskLoaderが破棄されるときに呼び出される
}
}

通信データ


実際に使用する通信データはメッセージ種別など様々な情報が含まれていると思うが、ここでは簡略化して文字列のみを送受信することにする。

package net.kuttya.httppostsample2;

import java.io.Serializable;

public class TransData implements Serializable {
private static final long serialVersionUID = 1L;

public String data;
}

バックグラウンド処理


ここでHTTP-Post通信を実行する。

package net.kuttya.httppostsample2;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;

public class HttpAccesser extends AsyncTaskLoader {
private final static String SERVER_URL = "http://www.sample.com/index.php";
private final static String ENCODE = "UTF-8";

private TransData mSendData = null; // 送信データ
private DefaultHttpClient mHttpClient = null; // HTTPクライアント
private HttpPost mPost = null; // POST通信

public HttpAccesser(Context context, TransData sendData) {
super(context);

this.mSendData = sendData;
}

public TransData loadInBackground() {
// ここに非同期処理で実施したい処理を記載する
TransData recvData = null;

recvData = send(mSendData);

return recvData;
}

public void onCanceled(Boolean data) {
// キャンセル処理
}

protected void onStartLoading() {
// 開始処理
forceLoad();
}

public TransData send(TransData sendData) {
boolean ret = false;
TransData recvData = null;
List params = new ArrayList();
HttpResponse response = null;
HttpEntity resEntity = null;
int resStatus = 0;

// 接続初期化
ret = initConnection();
if(false == ret) {
return null;
}

try {
// 送信データ生成
params.add(new BasicNameValuePair("data", sendData.data));
// UTF-8にエンコードする
mPost.setEntity(new UrlEncodedFormEntity(params, ENCODE));

// 送信
response = mHttpClient.execute(mPost);

// リクエスト結果を取得
resStatus = response.getStatusLine().getStatusCode();

if(200 == resStatus) {
// リクエスト成功
resEntity = response.getEntity();
recvData = new TransData();
recvData.data = EntityUtils.toString(resEntity, ENCODE);
}
} catch(Exception e) {
e.printStackTrace();
recvData = null;
} finally {
try {
if(mHttpClient != null) {
mHttpClient.getConnectionManager().shutdown();
}
} catch(Exception e) {
recvData = null;
}
}

return recvData;
}

private boolean initConnection() {
mHttpClient = new DefaultHttpClient();
mPost = new HttpPost(SERVER_URL);

return true;
}
}

マニフェストファイルにパーミッション追加


下記のパーミッションを追加する。


2014年2月4日火曜日

androidからAsyncTaskLoaderでHTTP-Post通信をする

Android 3.0からUIスレッドではインターネットへの接続ができなくなった。

そこで、AsyncTaskLoaderを使って、Android 4.0.3でHTTP-Post通信を実行してみる。
HTTP通信には、HttpURLConnectionクラスを使用する。

処理を実現するためには、Androidアプリで下記の3つの部品を実装する。

  • UI処理
  • 通信データ
  • バックグラウンド処理

Androidアプリのマニフェストファイルにインターネット接続のパーミッションを追加すること。

また、サーバ側でも何らかの応答を返す処理を実装する必要がある。

UI処理

アプリケーション実行時に呼び出されるアクティビティ。
ここで通信データを生成し、バックグラウンド処理に渡す。

package net.kuttya.httppostsample2;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;

public class MainActivity extends FragmentActivity implements LoaderCallbacks {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// サーバにデータ送信(初期化)
TransData sendData = new TransData();
Bundle args = new Bundle();
sendData.data = "test";
args.putSerializable("data", sendData);
getSupportLoaderManager().initLoader(0, args, this);
}

public Loader onCreateLoader(int id, Bundle args) {
if( null != args ) {
TransData sendData = (TransData) args.getSerializable("data");

return new HttpAccesser(this, sendData);
}
return null;
}

public void onLoadFinished(Loader loader, TransData recvData) {
// AsyncTaskLoaderの処理が終了したら呼び出される
if(null == recvData) {
return;
}
else {

}
}

public void onLoaderReset(Loader arg0) {
// AsyncTaskLoaderが破棄されるときに呼び出される
}
}

通信データ


実際に使用する通信データはメッセージ種別など様々な情報が含まれていると思うが、ここでは簡略化して文字列のみを送受信することにする。

package net.kuttya.httppostsample2;

import java.io.Serializable;

public class TransData implements Serializable {
private static final long serialVersionUID = 1L;

public String data;
}

バックグラウンド処理


ここでHTTP-Post通信を実行する。

package net.kuttya.httppostsample2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;

public class HttpAccesser extends AsyncTaskLoader {
private final static String SERVER_URL = "http://www.sample.com/index.php";
private final static String ENCODE = "UTF-8";

private TransData mSendData = null; // 送信データ
private HttpURLConnection mHttpConnection = null; // HTTP通信

public HttpAccesser(Context context, TransData sendData) {
super(context);

this.mSendData = sendData;
}

public TransData loadInBackground() {
// ここに非同期処理で実施したい処理を記載する
TransData recvData = null;

recvData = send(mSendData);

return recvData;
}

public void onCanceled(Boolean data) {
// キャンセル処理
}

protected void onStartLoading() {
// 開始処理
forceLoad();
}

public TransData send(TransData sendData) {
OutputStream out = null; // HTTPリクエスト送信用ストリーム
InputStream in = null; // HTTPレスポンス取得用ストリーム
BufferedReader reader = null; // レスポンスデータ出力用バッファ
int retByte = 0;
boolean ret = false;
byte[] sendMessage = null;
byte[] recvMessage = null;
TransData recvData = null;

// 接続初期化
ret = initConnection();
if(false == ret) {
return null;
}

try {
// 送信データ生成
sendMessage = new byte[255];
System.arraycopy(mSendData.data.getBytes(), 0, sendMessage, 0, mSendData.data.length());

// 接続
mHttpConnection.connect();

// データを出力
out = new BufferedOutputStream(mHttpConnection.getOutputStream());
out.write(sendMessage);
out.flush();

// レスポンスを取得
in = new BufferedInputStream(mHttpConnection.getInputStream());
recvMessage = new byte[1024];
retByte = in.read(recvMessage);
if(0 > retByte) {
return null;
}

// 受信データ解析
recvData = new TransData();
ret = analyzeRecvData(recvMessage, recvData);
if(false == ret) {
return null;
}
} catch(Exception e) {
e.printStackTrace();
recvData = null;
} finally {
try {
if(reader != null) {
reader.close();
}
if(in != null) {
in.close();
}
if(out != null) {
out.close();
}
if(mHttpConnection != null) {
mHttpConnection.disconnect();
}
} catch(Exception e) {
recvData = null;
}
}

return recvData;
}

private boolean initConnection() {
// URL指定
URL url;
try {
url = new URL(SERVER_URL);

// HttpURLConnectionインスタンス作成
mHttpConnection = (HttpURLConnection)url.openConnection();

// POST設定
mHttpConnection.setRequestMethod("POST");

// HTTPヘッダの「Content-Type」を「application/octet-stream」に設定
mHttpConnection.setRequestProperty("Content-Type","application/octet-stream");

// URL 接続を使用して入出力を行う
mHttpConnection.setDoInput(true);
mHttpConnection.setDoOutput(true);

// キャッシュは使用しない
mHttpConnection.setUseCaches(false);
} catch (Exception e) {
e.printStackTrace();
return false;
}
finally {
if(mHttpConnection != null) {
mHttpConnection.disconnect();
}
}
return true;
}

private boolean analyzeRecvData(byte[] recvMessage, TransData recvData) {
try {
if(null == recvData)
{
return false;
}

recvData.data = new String(recvMessage, ENCODE);
}
catch(Exception e) {
e.printStackTrace();
return false;
}

return true;
}

}

マニフェストファイルにパーミッション追加


下記のパーミッションを追加する。



サーバ処理


サーバ側はPHPで実装する。
HTTPリクエストを取得し、受信したデータを送り返す。

<?php
// 受信データ格納
$data = file_get_contents("php://input");

echo "POST DATA RECEIVED. data[".$data."]"

?>

2014年2月3日月曜日

HTTP通信でNetworkOnMainThreadException発生

昔作成したコードを動かしてみたら、NetworkOnMainThreadExceptionが発生した。
昔は問題なく動作していたにも関わらず、だ。

原因は、Android 3.0からインターネット通信はUIスレッドでは行えなくなっている様子。

AsyncTaskか、AsyncTaskLoaderを使用しなくてはならないらしい。
Android4.0以降であれば、AsyncTaskLoaderがよいと思われる。

一時的に、下記のコードを埋め込んでおけば、例外を抑制できる。
埋め込む場所は、UIスレッドのonCreateメソッド開始直後、super.onCreateメソッド実行前。

  1. StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());  

2014年2月2日日曜日

CakePHPでMySQLデータベースのテーブルにアクセスする(scaffold)

CakePHPでデータベースのテーブルにscaffoldでアクセスする。
読み方はスキャフォールド(でよいと思う)。

scaffoldを使用すれば、手っ取り早くテーブルにアクセスすることができる。
実際のアプリケーション運用で使用することはないが、開発者がアプリケーションの動作確認を目的にデータベースの操作を行う場合に有用といえる。

2014年2月1日土曜日

CakePHPでデータベースの接続設定

CakePHPでデータベースへ接続する。database.phpを編集する。