2011年7月20日水曜日

HTML5のpushState

HTML5には、
HistoryオブジェクトにpushState()とreplaceState()というメソッドが追加されました。

pushStateというのは、
Historyのリストに新しくエントリを追加してしまいます。
ページ遷移をしていなにのに、Hisotryが追加されるのです。

下記にコードを示します。
<html>
<head>
<script>
function push_history() {
  history.pushState("", "", "/example");
}
</script>
</head>
<body>
Hello, World!
<form>
<input type="button" value="button" onclick="push_history()" />
</body>
</html>

これにより、
現在のページが "http://foo.com/hello/index.html " だった場合、
ボタンをクリックするとURLが第3引数により、"http://foo.com/example" に変化しており、
戻るのリストをみると、1個Historyが追加されているのがわかります。
実際に戻るをクリックすると、URLバーが
"http://foo.com/hello/index.html "
に戻ります。

これで、ページを遷移していないのに、
Historyにエントリを追加して、URLを変更することができます。

Ajaxとこれを組み合わせた技術を "Pjax" と呼びますが、
これは別途まとめようと思います。

twitterのOAuth認証

OAuthっていうのは、
APIを使用する認証を行うための仕様のことで、
パスワードを第3者に教えることなく、トークンのやり取りだけで認証が行えるしくみのことです。

OAuthってなんなのかは、
ゼロから学ぶOAuthが参考になるとおもいます。

で、実際にtwitterでOAuth認証をおこなって、
つぶやくためのスクリプトを書きました。

まず、
http://dev.twitter.com/apps/
でアプリケーション登録を行います。
(登録には、twitterアカウントが必要です。)
で。Consumer Keyと Consumer Scretを取得します。

で、rubyのOAuthライブラリを使って、
下記のコードを書きました。

#!/usr/bin/ruby
require 'rubygems'
require 'oauth'

consumer = OAuth::Consumer.new(
  "Consumer Key",
  "Consumer Secret",
  :site => "http://twitter.com"
)
token = consumer.get_request_token
puts token.authorize_url #リダイレクト先のURL
pin = gets.chop
access_token = token.get_access_token(:oauth_verifier => pin)
puts access_token.token #アクセストークン のtoken
puts access_token.secret # アクセストークンの secret

token.authorize_url のURLをブラウザに貼付けてページ遷移すると、
リダイレクト先にpinコードが書いてあるので、
それをコピーして入力します。

そうすると、Accessトークンを取得することができます。

CosumerトークンとAccessトークン
あとは、twitterライブラリあたりで、
twitter APIを叩けばOKです。
以下は、ただ、"Hello, World" をつぶやくスクリプトです。

#!/usr/bin/ruby
require 'rubygems'
require 'twitter'
require 'twitter/console'

Twitter::Client.configure do |conf|
  conf.oauth_consumer_token = "Consumer Key",
  conf.oauth_consumer_secret =   "Consumer Secret",
end

twitter_client = Twitter::Client.new(:oauth_access => {
  :key => "Access Token Key",
  :secret => "Access Token Secret"
})

twitter_client.status(:post, "Hello, World");

2011年6月14日火曜日

ATECで発表してきました。

大分前になってしまいますが、
ATEC(Android テスト部)で発表してきました。

ATECでやっているテストをつくるためのAndroidアプリである
testterに関してです。
@nowsprintingさんと共同でやってきました。

以下がプレゼン資料です。


@nowsprintingさんの資料も下記に載せておきます。


もし興味がある方は、是非、ATECにご参加ください。
https://sites.google.com/site/androidtestclub/

2011年5月2日月曜日

Objective-Cを学ぶ

以前Objective-Cについて書きましたが、
改めてObjective-Cの書き方をざっとまとめてみます。
下記がわかれば、だいたいソースコードを読めるのではないかと・・・自身ないけど。

.hファイル
@interface クラス名 : 親クラス名 {
    int member1;
    (メンバ変数)
}
- (返り値)メソッド1;
- (返り値)メソッド2:(引数型)引数
- (返り値)メソッド3_1:(引数型)引数1 メソッド3_2:(引数型)引数2
@end
.mファイル

@implements クラス名
- (返り値)メソッド1
{
  メソッド1の処理
}

- (返り値)メソッド2:(引数型)引数
{
  メソッド2の処理
}

- (返り値)メソッド3_1:(引数型)引数1 メソッド3_2:(引数型)引数2
{
  メソッド3の処理
}
@end

メソッドの呼び出しは、
[オブジェクト名 メソッド名:引数];
です。

他には、
ヘッダーの読み込み(includeではなくimport)
#import <UIKit/UIKit.h>
他の場所で定義されたクラスの名前
@class クラス名
があります。

また、アクセッサとして、.hに
@property (nonatomic, retain) UIWindow *window;
.mに
@synthesize window;
と書けば、getter/setterメソッドを自動生成してくれます。


@property (nonatomic, retain) UIWindow *window;
の nonatomic は atomicじゃないので、非同期処理は対応しない、 retainは代入したときに参照カウントを1増やして解放されないようにする、っていう意味っぽいです。

2011年1月25日火曜日

Erlangで行頭に行番号をつけるプログラムをつくってみた。

なんとなくつくってみただけ。
Erlangを普段の業務とかでどれだけ使えるかのテストをかねて。

file_number.erl

-module(file_number).
-export([add_file_number/2]).

add_file_number(Readfile, Writefile) ->
  {OK, S} = file:open(Readfile, read),
  {OK, T} = file:open(Writefile, write),
  X = 1,
  read_line(S, T, X),
  file:close(T),
  file:close(S).

read_line(S, T, X) ->
  case io:get_line(S, '') of
    eof ->
      ok;
    Line ->
      io:format(T, "~w~s~s", [X, " ", Line]),
      read_line(S, T, X+1)
  end.

実行してみる

1> c(file_number).
{ok,file_number}
2> file_number:add_file_number("test.dat", "test2.dat").
ok

一応
行番号がつくこと確認。

そんだけ。

2011年1月13日木曜日

[android]Adapterって何?

Androidでは
ListViewやGallery等で
ArrayAdapterのようなXXXAdapterというものを使用しますが、
このAdapterとは、いったい何なんでしょうか?

AdapterというのはViewとデータの橋渡し役で、
Viewに必要なデータを渡してあげる役割があります。
例えば、
getCount()は、Viewに必要なitemの数、
getItem()は、対応するObjectを返す関数です。
getViewは、Listのアイテムのように、それぞれのitemに対応するView
を作って返します。

以下は、AKB48の総選挙の結果を7位までリスト表示するプログラムです。

HelloListActivity.java

package jp.android.hellolist;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class HelloListActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ListView view = (ListView)findViewById(R.id.list_view);
        HelloListAdapter adapter = new HelloListAdapter(this);
        view.setAdapter(adapter);
    }
}

HelloListAdapter.java

package jp.android.hellolist;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class HelloListAdapter extends BaseAdapter {
    private LayoutInflater inflater;
    private AKBData data;

    public HelloListAdapter(Context context) {
        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        data = new AKBData();
    }

    @Override
    public int getCount() {
        return data.getSize();
    }

    @Override
    public Object getItem(int position) {
        return data.getItem(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.list, null);
            TextView tv1 = (TextView)convertView.findViewById(R.id.TextView01);
            tv1.setText(Integer.toString(position + 1));
            TextView tv2 = (TextView)convertView.findViewById(R.id.TextView02);
            tv2.setText(data.getItem(position));
        }
        return convertView;
    }

}

AKBData.java

package jp.android.hellolist;

import java.util.ArrayList;

public class AKBData {
    private ArrayList list;

    public AKBData() {
        list = new ArrayList();
        list.add("大島優子");
        list.add("前田敦子");
        list.add("篠田麻里子");
        list.add("板野友美");
        list.add("渡辺麻友");
        list.add("高橋みなみ");
        list.add("小嶋陽菜");
    }
    
    public int getSize() {
        return list.size();
    }

    public String getItem(int index) {
        return list.get(index);
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<ListView  
 android:id="@+id/list_view"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    />
</LinearLayout>

list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
 android:id="@+id/LinearLayout01"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="horizontal"
 xmlns:android="http://schemas.android.com/apk/res/android">
 <TextView 
  android:text="@+id/TextView01"
  android:id="@+id/TextView01"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_marginRight="10dip" />
 <TextView
  android:text="@+id/TextView02"
  android:id="@+id/TextView02"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" />
</LinearLayout>

実行結果

2011年1月10日月曜日

[android]androidのアプリをHTMLで作れるようにする

androidのアプリケーションから
ローカルに保存してあるHTMLを表示させるアプリのサンプルを作ってみました。
WebViewのaddJavascriptInterface()をつかえば、
Javascript から Androidのメソッドを呼び出すこともできます。

ローカルにおくためのHTMLは、
assetsフォルダに保存しておけば、file: でアクセスできます。
(assets/index.htmlだったら、file://android_asset/index.htmlでアクセスできる)

サンプルです。
HelloHTMLActivity.java

package jp.android.hellohtml;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.Log;
import android.webkit.WebView;
import android.widget.Toast;

public class HelloHTMLActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WebView wv = new WebView(this);
        wv.getSettings().setJavaScriptEnabled(true);
        MyJSObj jsobj = new MyJSObj(this);
        wv.addJavascriptInterface(jsobj, "myobj");
        setContentView(wv);
        
        wv.loadUrl("file:///android_asset/index.html");
    }
    
    class MyJSObj {
     private Context context;
     
     public MyJSObj(Context c) {
      this.context = c;
     }
     
     public void showToast(String str) {
      Log.d("tag", str);
      Toast.makeText(context, str, Toast.LENGTH_LONG).show();
     }
     
     public void vibration() {
      Vibrator vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
      vibrator.vibrate(2000);
     }
    }
}
addJavascriptInterface()は第1引数はjavascriptにバインドしたいオブジェクト、
第2引数はjavascriptでアクセスするオブジェクトの名前を指定します。

今回は、MyJSObjのメソッドにアクセスできるようにします。
showToast() はただのtoastの表示、
vibration() は2秒間振動します。

Vibratorを使うときは、
android.permission.VIBRATE
の設定を忘れずに。

index.html

<html>
<head>
<title>test content</title>
<script type="text/javascript">
  function showText() {
    myobj.showToast("test");
  }
  function vibration() {
    myobj.vibration();
  }
</script>
</head>
<body>
<div>hello</div>
<input type="button" value="toast" onclick="showText();" />
<input type="button" value="vibe" onclick="vibration();" />
</body>
</html>

実行結果

実行結果はただのHTMLですが、
toastをクリックすればtoastがでて、
vibeをクリックすれば、きちんと2秒間振動することを確認しました。