こんばんわ

あれからソースを見てて、

metaPress(META_CTRL_ON); を実行すればCTRLが押されたことに、
sendEscape(); を実行すればESCが押されたことになることがわかりました。

デバッグログにて「絵・顔・記」と「文字」のキーコードを調べました。
onkey()に渡されるとkeyCodeを表示してみると、
「絵・顔・記」キーは92、「文字」は93となりました。

	public boolean onKey(View v, int keyCode, KeyEvent event) {
		try {
			final boolean hardKeyboardHidden = manager.hardKeyboardHidden;
			String s = String.format("%d,%d ", event.getAction(), keyCode);

			Log.v(TAG,"onKey1 " +s);	//debug

			//Log.v(TAG,"onKey2");


			// Ignore all key-up events except for the special keys
			if (event.getAction() == KeyEvent.ACTION_UP) {

keyCodeの値を表示した画面

ソースを変更する箇所は、

ファイル
TerminalKeyListener.java

クラス
public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceChangeListener {
private static final String TAG = "ConnectBot.OnKeyListener";

メソッド
public boolean onKey(View v, int keyCode, KeyEvent event)


// look for special chars を処理するcase文に92と93を追加しました。

// look for special chars

			// look for special chars
			switch(keyCode) {

			case KeyEvent.KEYCODE_CAMERA:

追加したソース

			case KeyEvent.KEYCODE_DPAD_RIGHT:
				if (selectingForCopy) {
					selectionArea.incrementColumn();
					bridge.redraw();
				} else {
					((vt320) buffer).keyPressed(vt320.KEY_RIGHT, ' ',
							getStateForBuffer());
					metaState &= ~META_TRANSIENT;
					bridge.tryKeyVibrate();
				}
				return true;

			case KeyEvent.KEYCODE_DPAD_CENTER:
				if (selectingForCopy) {
					if (selectionArea.isSelectingOrigin())
						selectionArea.finishSelectingOrigin();
					else {
						if (clipboard != null) {
							// copy selected area to clipboard
							String copiedText = selectionArea.copyFrom(buffer);

							clipboard.setText(copiedText);
							// XXX STOPSHIP
//							manager.notifyUser(manager.getString(
//									R.string.console_copy_done,
//									copiedText.length()));

							selectingForCopy = false;
							selectionArea.reset();
						}
					}
				} else {
					if ((metaState & META_CTRL_ON) != 0) {
						sendEscape();
						metaState &= ~META_CTRL_ON;
					} else
						metaPress(META_CTRL_ON);
				}

				bridge.redraw();

				return true;

			case 92:	//絵・顔・記 キーをCTRLに割り当てる
				metaPress(META_CTRL_ON);
				bridge.redraw();
				return true;

			case 93:	//文字キーをESCに割り当てる
				sendEscape();
				bridge.redraw();
				return true;

			}

		} catch (IOException e) {
			Log.e(TAG, "Problem while trying to handle an onKey() event", e);
			try {
				bridge.transport.flush();
			} catch (IOException ioe) {
				Log.d(TAG, "Our transport was closed, dispatching disconnect event");
				bridge.dispatchDisconnect(false);
			}
		} catch (NullPointerException npe) {
			Log.d(TAG, "Input before connection established ignored.");
			return true;
		}

		Log.v(TAG,"onKey8");

		Log.v(TAG,"hardKeyboardHidden return");	//debug

		return false;
	}

もともと、特殊キーの入力でCTRLとESCを入力する仕組みがありましたのでそれを流用しました。
結果的に少しの修正で、記号、CTRL、ESCの入力が出来るようになりました。
これにより、SSHでログインしてOSの操作やviの操作も普通に出来るようになりました。

さくらのVPSと組み合わせることによりどこでもプログラミングやサーバ管理が出来るのがちょっと嬉しいです。

こんにちは

android端末のis01を最近、買いましたました。

http://au-is.jp/ 

ここをみてもis03が発表になってからはis01スマートフォンでは
なくなってしまいました。
OSも1.6のままで早く2.1にして欲しいです。

さくらのVPSも契約してて、SSHで接続してみたのですがConnectBotでは
Shift+数字ではファンションの入力になってしまい記号が入力出来ませんでした。
ConnectBotはソースが公開されているとのことでちょっと調べてみたらファンションキーでなく
記号入力が出来るように修正が出来ました。

修正はすごく簡単で、TerminalKeyListener.javaのファンションキーに変換してる部分を
コメントアウトするだけで対応出来ました。

まずはソースのインストール
ダウンロードしたあとEclipseへインポートしました。

http://code.google.com/p/connectbot/


調査の様子
ソースにログ表示を追加してshftを押した時の処理を探し出しました。

このif文をコメントアウトします。

				/***
				// handle pressing f-keys
				if ((hardKeyboard && !hardKeyboardHidden)
						&& (curMetaState & KeyEvent.META_SHIFT_ON) != 0
						&& sendFunctionKey(keyCode)){
					Log.v(TAG,"onKey handle pressing f-keys");	//debug
					return true;
				}
				***/

Eclipseでのソース表示

修正はコメントアウトするだけでした。
実行してサーバへ接続してコンパイル、実行してみました。

ログイン直後

vim起動

Cのソースを入力

コンパイルと実行


このようにviを終了するときの!や#includeなどが入力出来てIS01自力でコンパイルデバッグが出来ました。
ソースを見ると右と左のSHIFTキーの判別が出来るみたいなので右SHIFTキーをCTRLに割り当てようかと思って
います。
絵・顔・記も判別できるのでこれはESCに割り当ててみます。



onKey(View v, int keyCode, KeyEvent event)
onKey(View v, int keyCode, KeyEvent event) が返す値はキー1つ1つを識別できるみたいです。

public boolean onKey(View v, int keyCode, KeyEvent event) {
		try {
			final boolean hardKeyboardHidden = manager.hardKeyboardHidden;
			String s = String.format("%d,%d ", event.getAction(), keyCode);

			Log.v(TAG,"onKey1 " +s);	//debug

			//Log.v(TAG,"onKey2");

int key = keymap.get(keyCode, curMetaState);
keymap.get()はアスキーコードに対応した値みたいです。

				int key = keymap.get(keyCode, curMetaState);

				String s2 = String.format("keymap.get = %02x", key);
				Log.v(TAG,s2);	//debug

				if ((metaState & META_CTRL_MASK) != 0) {
					metaState &= ~META_CTRL_ON;
					Log.v(TAG,"META_CTRL_MASK");	//debug
					bridge.redraw();

OSが選べるようになったのでUbuntu10.04.1にしてみました。
2chで情報収集したら32bit版の方がメモリ消費が少ない
みたいなので32bitにしました。

以下はインストールした時に参照したページです。

httpd
http://www.server-world.info/query?os=CentOS_5&p=httpd

php
http://www.server-world.info/query?os=CentOS_5&p=httpd&f=2

mysql
http://www.server-world.info/query?os=CentOS_5&p=mysql

gcc
http://www10.atwiki.jp/shirayuu/pages/52.html#id_2b630f10

python
http://www10.atwiki.jp/shirayuu/pages/52.html#id_63a175da

java
http://www10.atwiki.jp/shirayuu/pages/52.html#id_a13a10f2

javaのときだけつまずきました。

sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"

これを実行すると「add-apt-repositor」がないみたいです。

http://www.arcenserv.info/mumble/murmur/12x/linux-instal/

このページによると、

    • -

10.04 のサーバ版の場合はadd-apt-repositoryがないので、それのインストールから

    • -

ということなので、

sudo aptitude install python-software-properties
sudo add-apt-repository ppa:slicer

を実行してjavaを入れました。

CentOSの場合、最新版を入れたいのならソースからってのが多くて
かなり難しかったです。

しかしUbuntuの場合、上記URLをそのまま実行するだけで
インストールできました。
運用より勉強、最新の環境に触れるのであればCentOSより
Ubuntuがいいかなと思いました。
ここも参考になりました。

http://smilelogic.jp/makoto/?p=2837

ネットでの成果を参照することで楽に構築出来ました。
参考にしたページの作者様たちにはお礼を申し上げます。

11月3日に益子の陶器市にてビール用のジョッキを買いました。
GAEを使ったビジネスをいろいろ考えていました。

まずは小さくてもやってみようと先が見えるものとして陶器の通販を思いつきました。
知り合いに陶器をやってて写真も上手い人がいたのでその人に協力をいただき、
始めることにしました。

陶器のことをあまり知らないので調度、益子で陶器市があるから行ってみれば?
と言われて勉強がてら行きました。

出来るだけ、作家さん本人がいそうなテントで気に入ったものを買いました。
結局ここに載せた5つのジョッキを買いました。

滑浩之さんの作品

表面のオレンジとフランス語の文字がいい感じ


原田省平さんの作品

こげ茶と白のコントラストに目が行って、持った感じがなかなか良い


ホソカワ カオリさんの作品

素焼きの表面にタイルをはった感じ


山田直恵さんの作品

草の模様が気に入りました


千田菜々子さんの作品

本当は赤い梅の模様がよかったのですが、なくて赤い花をイメージしたものを買いました


撮影方法です

窓際の自然光、レースのカーテン越しに光を当てました。
前面が影になるので、発泡スチロールで作ったレフ版で光を当てました。
カメラはペンタックスのK100D、レンズは200mmで背景をぼかしました。
手振れ防止もあるし、光もまあ十分だったので手持ちで撮影しました。
RAW現像の設定は、ディテール強調を100にしました。
かなり表面のざらつき感が出てると思います。

「集合場所は“地図メール”で通知する」 をキャリアとアプリによら

このニュースの機能をジオポを使って実現しました。

詳しくは昨日の記事を参照ください。
http://d.hatena.ne.jp/mk18/20090315


<現在位置を通知するメールを送信できるサイト>
http://mk18.x0.com/

使い勝手は専用アプリには及びませんが比較的簡単に実現できました。
メールはキャリアによらず使えるし、ジオポのおかげで地図表示もキャリアにもよりません。

ジオポを使って自分の位置をメール送信できるサービスを作って見ました。

今まで作ったことをまとめただけですが、携帯からアクセスし易い様に短いURLにしました。

携帯電話でアクセスして下さい。

http://mk18.x0.com/


以下サイトが大変参考になりました。
ありがとうございます。


PHPで携帯位置情報を扱うライブラリ「Geomobilejp_Converter」を作りました
http://labs.unoh.net/2008/08/phpgeomobilejp_converter.html

■携帯電話のUserAgent判定クラス
http://d.hatena.ne.jp/ya--mada/20081213/1229173330


ソースコード

<?php
mb_internal_encoding('UTF-8');
mb_http_output('SJIS-win');

require_once dirname(dirname(__FILE__)) . '/lib/Geomobilejp/Converter.php';
require_once dirname(dirname(__FILE__)) . '/lib/Geomobilejp/IArea.php';
require_once dirname(dirname(__FILE__)) . '/lib/Geomobilejp/Mobile.php';

$url = 'http://' . $_SERVER['SERVER_NAME']
     . preg_replace('/\?.+?$/', '', $_SERVER['REQUEST_URI']);
?>

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" />
  <title>mk18 携帯情報サービス</title>
</head>
<body>
<P align="center">mk18 位置情報サービス</P>
<hr>
<?php
require_once ("Keitai.class.php");
$ua =& Keitai::singleton();

if ( !$ua->isValidIp() ) { // Keitai_IP_List.class.phpが必要です
  	print "<br>携帯電話からアクセスして下さい。<br>";
	print "\n<br><br>(C)2009 <a href='http://d.hatena.ne.jp/mk18/'>mk18</a><br>\n";
  	die();
}


$id = $ua->getKeitaiId();
//print "{$id}<br>\n";

$carrier = $ua->getCarrier();/*キャリア名 DoCoMo, KDDI, SoftBank, Willcom*/
print "{$carrier}<br>\n";

$mobile = new Geomobilejp_Mobile();

if ($mobile->hasParameter()) {

    $converter = new Geomobilejp_Converter(
        $mobile->getLatitude(),
        $mobile->getLongitude(),
        $mobile->getDatum()
    );

//    $c1 = $converter->convert('wgs84')->format('dms');
    $c2 = $converter->convert('wgs84')->format('degree');
//    $c3 = $converter->convert('tokyo')->format('dms');
//    $c4 = $converter->convert('tokyo')->format('degree');

//    $area = Geomobilejp_IArea::seekArea($converter);

	$lat2 = $c2->getLatitude();
	$lon2 = $c2->getLongitude();
	
//    print"wgs84(degree)<br>";
	print"緯度:{$lat2}<br>";
	print"経度:{$lon2}<br>";
    print "<br><hr>";
	
	//ジオポ
	require_once ("geopo.php");
	$location['lat'] = $lat2;
	$location['lng'] = $lon2;
	$location['scale'] = 6;
	$geopo = geopoEncode($location);
//	print "<br>geopo={$geopo}<br>\n";
	print "<a href='http://geopo.at/{$geopo}'>ジオポで地図を表示</a>";
	print "<br>\n";
	print "<a href='mailto:xxx@xxx?subject=my location&amp;body=http://geopo.at/{$geopo}'> メールで現在位置を送信</a>";
	print "<br>\n";	
	
	
}//endif


//携帯メーカーを判定して振り分け表示する
print "<br>";

//$carrier = "DoCoMo";	//for test

$url = htmlspecialchars($url);
//print "{$url}<br>\n";

if($carrier=="DoCoMo"){
print'
    docomo<br />
    <form action="sample.php" method="get" lcs="lcs">
      <input type="submit" value="位置情報を送信" />
    </form>
    <br />
';
}

if($carrier=="KDDI"/* || $carrier=="NonMobile"*/){
print'
	au<br />
    <form action="device:gpsone" method="get">
	<input type="hidden" name="url" value=
	';
print"{$url}";
print'	
	/>
      <input type="hidden" name="datum" value="0" />
      <input type="hidden" name="ver" value="1" />
      <input type="hidden" name="unit" value="0" />
      <input type="hidden" name="acry" value="0" />
      <input type="hidden" name="number" value="0" />
      <input type="submit" value="位置情報を送信" />
    </form>
    <br />
';
}

if($carrier=="SoftBank"){
print'
	SoftBank<br />
    <a href="location:gps?url=sample.php"位置情報を送信</a>
    <br />
';
}

if($carrier=="Willcom"){
print'
	WILLCOM<br />
    <a href="http://location.request/dummy.cgi?my=<?php echo htmlspecialchars($url) ?>&pos=$location">位置情報を送信</a>
    <br />
';
}

print "\n<br><br>(C)2009 <a href='http://d.hatena.ne.jp/mk18/'>mk18</a><br>\n"
?>

</body>
</html>

こんばんわ

以前作ったauの携帯から位置情報を取得してサーバへ保存するプログラムを修正してジオポで地図表示するようにしました。


作成したサイト、auの携帯で開いてください。
http://anakureon.com/work/gpsinfo/test.php


サーバへー保存した情報を元にyahoo地図表示
http://anakureon.com/work/gpsinfo/map2.php


ジオポのサイト
http://geopo.at/


作成したPHPソース
難しいことは何もしていません。
度分秒の変換ぐらいかな?
gpsinfo.php

<HTML>
<TITLE>mk18 gps</TITLE>
<BODY>
<?php
require_once ("geopo.php");


$id = $_SERVER['HTTP_X_UP_SUBNO'];
$datum=$_GET["datum"];
$unit =$_GET["unit"];
$lat=$_GET["lat"];
$lon=$_GET["lon"];
chop($lat);//文字列の最後から空白文字を削除する
chop($lon);
$lat_s = explode(".", $lat);//ピリオド区切りで配列へデータを格納する
$lon_s = explode(".", $lon);

//echo "id = $id<BR>";
echo "time = ".$_GET["time"]."<BR>";
//取得した位置情報を経度緯度 dms 度分秒単位 で表示
echo "$lat_s[0]$lat_s[1]$lat_s[2]$lat_s[3]<BR>";
echo "$lon_s[0]$lon_s[1]$lon_s[2]$lon_s[3]<BR>";

/***
//degree 度単位で表示する
$lat_deg=$lat_s[0]+$lat_s[1]/60+$lat_s[2]/3600+$lat_s[3]/360000;
$lon_deg=$lon_s[0]+$lon_s[1]/60+$lon_s[2]/3600+$lon_s[3]/360000;
echo "degree: $lat_deg<BR>\n";
echo "degree: $lon_deg<BR>\n";
***/

//経度緯度以外の情報を表示する
//echo "GPSv ver: ".$_GET["ver"]."m<BR> \n";
//echo "高度 alt: ".$_GET["alt"]."m<BR> \n";
//echo "長軸半径誤差 smaj:".$_GET["smaj"]."<BR> \n";
//echo "短軸半径誤差 smin:".$_GET["smin"]."<BR> \n";
//echo "誤差楕円長軸角度 majaa 度:".$_GET["majaa"]."<BR> \n";
//echo "高度誤差 vert: ".$_GET["vert"]."<BR> \n";
//echo "測位方法 fm: ".$_GET["fm"]."<BR> \n";

/*ファイルへ書き込み*/

//data.csv
$fp = fopen("data,csv","a");	//追加
fwrite( $fp, $id );	//HTTP_X_UP_SUBNO
foreach ($_GET as $line) {
//	echo "$line,";
    fwrite( $fp, $line );
    fwrite( $fp, "," );
}
fwrite( $fp, "\n" );
echo "<BR>";
fclose($fp);

// data.txt
$fp = fopen("data,txt","w");	//新規
fwrite( $fp, $id );	//HTTP_X_UP_SUBNO
fwrite( $fp, "\n" );
foreach ($_GET as $key => $value) {
    fwrite( $fp, "$key=>$value" );
    fwrite( $fp, "\n" );
}
fwrite( $fp, "\n" );
fclose($fp);

//MySQLへinsert into
$cn = mysql_connect('xxx', 'xxx', 'xxx');//公開するわけにはいかないのでxxxしました。
if (!$cn) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('xxx');//公開するわけにはいかないのでxxxしました。
$sql = "insert into w1_gps_table values(";
$sql = $sql."'";
$sql = $sql.$id;
$sql = $sql. "',";
foreach ($_GET as $line) {
	$sql = $sql."'";
	$sql = $sql.$line;
	$sql = $sql. "',";
}
$sql = $sql."'y1','y2')";
//print "sql = $sql <BR>\n";
if (!(mysql_query($sql))) {
	die('query err:t: ' . mysql_error());
}
mysql_close($cn);
//
	
echo "<br>";
echo "<a href=device:gpsone?url=http://anakureon.com/work/gpsinfo/gpsinfo.php&amp;ver=1&amp;datum=0&amp;unit=0>GPSデータをサーバーへ送信</a>";//この1行を追加する
echo "<br>";

$lat2 = substr($lat,0+1,2)
		+substr($lat,3+1,2)/60
		+substr($lat,6+1,2)/60/60
		+substr($lat,9+1,2)/60/60/60;

$lon2 = substr($lon,0+1,3)
		+substr($lon,4+1,2)/60
		+substr($lon,7+1,2)/60/60
		+substr($lon,10+1,2)/60/60/10;
$location['lat'] = $lat2;
$location['lng'] = $lon2;
$location['scale'] = 6;
$geopo = geopoEncode($location);
print "geopo={$geopo}<br>\n";
print "<a href='http://geopo.at/{$geopo}'>ジオポで地図を表示</a>";
print "\n<br><br>(C)2009 <a href='http://d.hatena.ne.jp/mk18/'>mk18</a><br>\n"
?>
</body>
</HTML>

サンプルを元にエンコード関数を作成。
http://geopo.at/intl/ja/developer/sample_code.html
geopo.php

<?php

/*
 * GeoPo Encode in PHP
 * @author : Shintaro Inagaki
 * @param $location (Array) 'lat','lng','scale'の3つが必要
 * @return $geopo (String)
 */
function geopoEncode($location) {
	// 64characters (number + big and small letter + hyphen + underscore)
	$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";

	$geopo = "";
	$lat = $location['lat'];
	$lng = $location['lng'];
	$scale = $location['scale'];
	
//	print "lat={$lat} lng={$lng} scale={$scale}\n";
	
	// Change a degree measure to a decimal number
	$lat = ($lat + 90) / 180 * pow(8, 10);
	$lng = ($lng + 180) / 360 * pow(8, 10);

//	print "lat={$lat} lng={$lng} \n";
	
	// Compute a GeoPo code from head and concatenate
	for($i = 0; $i < $scale; $i++) {
		$geopo .= substr($chars, floor($lat / pow(8, 9 - $i) % 8) + floor($lng / pow(8, 9 - $i) % 8) * 8, 1);
	}
	
//	print "geopo={$geopo}\n";
	
	return $geopo;
}		

/*
* GeoPo Decode in PHP
 * @author : Shintaro Inagaki
 * @param $geopo (String)
 * @return $location (Array)
 */
function geopoDecode($geopo) {
	// 64characters (number + big and small letter + hyphen + underscore)
	$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
	// Array for geolocation
	$location = array ();

	for ($i = 0; $i < strlen($geopo); $i++) {
		// What number of character that equal to a GeoPo code (0-63)
		$order = strpos($chars, substr($geopo, $i, 1));
		// Lat/Lng plus geolocation value of scale 
		$location['lat'] = $location['lat'] + floor($order % 8) * pow(8, 9 - $i);
		$location['lng'] = $location['lng'] + floor($order / 8) * pow(8, 9 - $i);
	}

	// Change a decimal number to a degree measure, and plus revised value that shift center of area
	$location['lat'] = $location['lat'] * 180 / pow(8, 10) + 180 / pow(8, strlen($geopo)) / 2 - 90;
	$location['lng'] = $location['lng'] * 360 / pow(8, 10) + 360 / pow(8, strlen($geopo)) / 2 - 180;
	$location['scale'] = strlen($geopo);

	return $location;
}		

?>


変数の値を見るのが簡単です。
NetBeansでのデバッグ画面