TextViewで一部の文字列の色を簡単に変更する方法

例えば、以下の文字列を表示するとします。
日本語の場合

新品2点 \1,200より

英語の場合

2 new from \1,200

この\1,200という部分を赤くしたいのですが、英語と日本語では文字の並び順が違うので、TextViewを別々にするとかなり面倒なことになります。
これを簡単にできないかなーと思ってやってみた方法が以下です。


layoutのxml

<TextView android:id="@+id/main_textView_sample1"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" />

TextViewを定義してるだけです


string.xml
values/string.xml

<string name="test" formatted="false">%s new from %s</string>

values-ja/string.xml

<string name="test" formatted="false">新品%s点 %sより</string>

日本語と英語でそれぞれ用意します


Activity

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
        
	TextView text = (TextView)findViewById(R.id.main_textView_sample1);
	String s = String.format(getText(R.string.test).toString(), "2", "\1,200");
	text.setText(s);
}


これで表示すると当たり前ですが色は変わりません。


そこで、Html.fromHtml()というメソッドがあるようで、つかえるhtmlタグには制限があるもののfontタグは使えるようなのでこれを使用します
http://developer.android.com/intl/ja/reference/android/text/Html.html


string.xmlの文字列にfontタグを追加します
values/string.xml

<string name="test" formatted="false">%s new from &lt;font color=\"red\"&gt;%s&lt;/font&gt;</string>

values-ja/string.xml

<string name="test2" formatted="false">新品%s点 &lt;font color=\"red\"&gt;%s&lt;/font&gt;より</string>

ActivityはsetTextする箇所で、Html.fromHtml()というメソッドを使用します

text.setText(Html.fromHtml(s));


これで色が変更できました。

これを使って、取消線ができるか期待したのですがsタグは使えないみたいです。。

EC2でRuby on Railsを動かす環境を構築する

OSイメージ作成

もうすでにEC2ではRailsを動かしたりしてるのですが、新たに環境を構築する必要があったのでついでにメモとして残しておきます。
EC2のインスタンス作成後、サーバーにログインします

OSイメージはAmazon Linuxを使うことを前提です(64bit版)

Basic 64-bit Amazon Linux AMI 2011.02.1 Beta

user作成とrootパスワード変更

最初はec2-userでしかログインできなくなってるので、他ユーザーでログインしたければ、ユーザー作成後、ec2-userホームの.sshディレクトリを対象ユーザーのホームディレクトリにコピーすると次回からログインが可能になります。
ついでにrootのパスワードも変更しておくと便利です。以下で変更

sudo passwd

以降はrootで作業します。

rubyのinstallの確認

ruby -v 
ruby 1.8.7 (2010-12-23 patchlevel 330) [x86_64-linux]

デフォルトで入ってます。すばらしいですね

Apacheのinstall

yum -y install httpd

RubyGemsのinstall

下記から最新版を取得します
http://rubygems.org/pages/download

wget http://production.cf.rubygems.org/rubygems/rubygems-1.7.2.tgz
tar xvzf rubygems-1.7.2
cd rubygems-1.7.2
ruby setup.rb

yumrubygemsをinstallしてもいいです

Railsのinstal

gem install rails

rdocのところでエラーが出たので、rdocもinstallしておきます。
あと、この後のpassengerのinstallでもruby.hがない、gccがない、makeがないとか怒られるので以下もinstallします

yum -y install ruby-devel
yum -y install gcc
yum -y install make
yum -y install rdoc

passengerのinstall

gem install passenger

Apacheのmoduleをinstallするのですが、以下を実行すると

passenger-install-apache2-module

なにやらたくさんinstallしろと言われます。なので足りないものを全部installします

yum -y install gcc-c++
yum -y install zlib-devel
yum -y install httpd-devel
yum -y install openssl-devel
yum -y install curl-devel

再度実行すると、コンパイルが実行されて完了となります(結構時間かかります)

Apache設定ファイルの追加

http.confを直接いじらず、conf.d/rails.confという名前のファイルを作成します(名前は何でもいい)
中身は以下(必要に応じて設定変更は必要)

LoadModule passenger_module /usr/lib64/ruby/gems/1.8/gems/passenger-3.0.7/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib64/ruby/gems/1.8/gems/passenger-3.0.7
PassengerRuby /usr/bin/ruby


	ServerName hoge.com # サーバー名
	DocumentRoot /home/www/xxx # document rootのディレクトリ指定
	RailsEnv development
	 # document root の詳細設定
		AllowOverride None
		Options FollowSymLinks
	

Subversionのinstall

とりあえずこれで完了ですが、自分はアプリのdeployにCapistranoを使いたかったので、subversionをinstall(sqliteも必要になるのでinstallする)
sqliteのinstall

wget http://www.sqlite.org/sqlite-amalgamation-3.6.13.tar.gz
解凍後
./configure
make
make install 

subversionのinstall

wget http://subversion.tigris.org/downloads/subversion-1.6.16.tar.gz
解凍後
./configure
make
make install

※gitでソース管理している人はsubversionではなくてgitをinstallすればいいと思います


以上で構築完了です。これはステージング環境用に作ったのですが、ec2でOSイメージをコピーすれば簡単に同じ環境のインスタンスが作成されるので本番環境も簡単に作れて便利です


参考URL
http://troi.kbc-ehime.ac.jp/kj/?p=893&page=2

うま帳簿の宣伝用画像、プロモーション画像を設定しました

アンドロイドマーケットでは、任意で宣伝用画像、プロモーション画像というのを設定できます。
その画像を、うま帳簿とうま帳簿ライセンスでそれぞれ作成して設定してみました。


うま帳簿
https://market.android.com/details?id=com.iankohbo.horse&feature=search_result

うま帳簿ライセンス
https://market.android.com/details?id=com.iankohbo.horse.key&feature=search_result


PC版では宣伝用画像が使用されます。画像があると全然印象が違う感じですね。
また、高解像度アイコンも新しくしてみました。
高解像度アイコンは、今まではアプリで使っている72アイコンを引き伸ばして使ってたので、荒くなってしまってましたがこれで綺麗になりました。


携帯のマーケットの場合には、プロモーション画像を設定すると詳細画面の上に表示されます。
こちら設定してないと、アイコンが表示されます。


これらの画像は任意設定なので、設定していない人も多いとおもいますが、印象が全然ちがうので(特にPC)設定するといいかもしれません。
それにしても、PCのマーケットがどの位の割合で使われているのか気になります。。
そのうち管理画面からPC、携帯からのインストール数の割合が出るようになることを期待ですね。

Transtter Lite,Pro版をそれぞれリリースしました

以前にリリースした、Transtterというアプリがありました。
http://d.hatena.ne.jp/the_yokochi/20110217/1297939967


今回、Lite版(無料)、Pro版(有料)にわけてそれぞれリリースしました。
Lite版は登録ユーザー数が最大5人までとなっております。また広告が表示されます。
Pro版はその制限がありません。


これにあわせて、以前リリースしたTranstter(Beta版)は非公開に変更してます

# こちらは今後メンテナンスはおこなわないので、新しくリリースしたバージョンをお使いください


アプリは下記からダウンロードできます。

Transtter Lite
https://market.android.com/details?id=com.iankohbo.transtter.lite&feature=search_result

Transtter Pro
https://market.android.com/details?id=com.iankohbo.transtter.pro&feature=search_result

Androidアプリリリースしました。

新しいアプリを作りました。Transtterという名前のアプリで、Twitterに登録されている有名外国人の翻訳をおこない表示します。
Twitterのアカウントの登録は必要なく、本アプリのみで翻訳tweetを閲覧できます。閲覧できるユーザーは随時更新して、追加をおこなっていきたいと思います。

こちらからダウンロードできます
https://market.android.com/details?id=com.iankohbo.transtter


このアプリはA3用に作成したもので、何とかぎりぎり締め切り間に合い申し込みも完了しました。
また、アイコンは@y_digさんに作ってもらいました。ありがとうございます!


このアプリのbotも大活躍中です!
http://twitter.com/#!/transtter2

Android(sqlite3)のblobで保存、検索する方法

Androidではよく、画像とかをSDカードに保存とかやったりする場合があると思いますが、端末によってはSDカードがなかったりする場合もあると思います。
そういう場合には、blobで保存しておくと、結構便利だったりするのでその方法を書いてみたいと思います。


まずDBを定義します。
SQLiteOpenHelperを継承したクラスを作成します。

public class SampleDbOpenHelper extends SQLiteOpenHelper {
	private static final String DB = "sample.db";
	private static final int DB_VERSION = 1;
	
	public SampleDbOpenHelper(Context context) {
		super(context, DB, null, DB_VERSION);
	}
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(SampleDao.TABLE_SAMPLE);
	}
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}
}


テーブルを操作するクラスを作ります。

public class SampleDao {
	private static final String TABLE = "sample_table";
	
	private static final String COLUMN_ID = "id";
	private static final String COLUMN_BLOB = "object_blob";
	
	public static final String TABLE_SAMPLE =
		"create table " + TABLE + "(" +
		COLUMN_ID + " integer primary key," +
		COLUMN_BLOB + " blob);" ;
}

とりあえず、sample_tableというテーブルにid,object_blobという2つのカラムを持たせてます。


最初はinsertをおこなう方法です。
SampleDaoクラスに以下のメソッドを追加します。

	public static long insert(Context context, byte[] blob) { 
		SQLiteDatabase db = null;
		try {
			SampleDbOpenHelper helper = new SampleDbOpenHelper(context);
			db = helper.getWritableDatabase();
			ContentValues values = new ContentValues();
			values.put(COLUMN_BLOB, blob);

			return db.insert(TABLE, null, values);
		} finally {
			if (db != null) {
				db.close();
			}
		}		
	}

blobのデータはbyte配列として登録します。


次は取得方法です。
SampleDaoクラスに以下のメソッドを追加します。

	public static byte[] getBlob(Context context, String id) {
		SQLiteDatabase db = null;
		Cursor cursor = null;
		try {
			SampleDbOpenHelper helper = new SampleDbOpenHelper(context);
			db = helper.getReadableDatabase();
			String sql = String.format("select %s from %s where %s = ?", 
					COLUMN_BLOB, TABLE, COLUMN_ID);
			String[] args = {id};
			
			cursor = db.rawQuery(sql, args);
			
			if (cursor.moveToFirst()) {
				return cursor.getBlob(0);
			}
			return null;
		} finally {
			if (cursor != null) {
				cursor.close();
			}
			if (db != null) {
				db.close();
			}			
		}		
	}

上記のような感じでcursor.getBlobで取得できます。
例えば、このblobデータが画像データだったりすると以下のような感じでBitmapに変換できます。

BitmapFactory.decodeByteArray(blob, 0, blob.length); // blobはbyte[]です

結構簡単にblobが扱えるんですが、あまりでかいサイズを格納しようとすると、処理に時間がかかりエラーになったりするので、登録前にオブジェクトのサイズをみて、一定以下のサイズのみ登録って感じにしたほうがいいかもです。

PTY allocation request failed on channel 0

最近、VPS@ServersManを借りてみました。http://serversman.com/index.jsp
それで、いろいろサーバー環境構築をおこなっていたのですが、ある日sshでログイン後にこんなメッセージが表示されログインができなくなりました。
PTY allocation request failed on channel 0


ぬぬ。。特に何か設定を変えた訳でもなくなんだろう。ググって見るとVPSでよくあるような感じでも書かれているがこちらでは対応できず問い合わせてみる。


回答としては、sshのログイン制限に引っかかってログインができなくなってるとのこと。
自分は格安の\490のプランなので、最大8セッションが限界。
なぜかsshのプロセスが残ったままとなっていたので、そいつらをkillしてもらい無事ログインできるように。


プロセスが残ったままとなっている原因としては、VPSのデフォルト環境でajaxtermというブラウザからコマンドが実行できるというのが組み込まれており、こいつがきちんとログアウトしないと(ブラウザを閉じるとか)、ずーと残ったまんまとなってしまうようです。
# 自分はajaxtermからApacheを何度か再起動したのが原因っぽい。


対策としては、下記を見てプロセスを監視するとよいとのこと。

cat /proc/user_beancounters

Version: 2.5
       uid  resource     held     maxheld     barrier       limit            failcnt
       ・
       ・
              numpty         1          8                 8                8                 1383

このheldが8になるとログインできなくなる。

いちいち、こいつをチェックするのも面倒なのでcronで定期的にajaxtermを再起動することで対応することにしました。


基本的にはajaxtermは使わないで普通に端末を使うんですけど、http(s)でしか接続できない環境とかにいると結構重宝したりします。
まったく使わないのであれば、ajaxtermは無効にしておくのが無難な気がします。
こいつとかをrenameしておけばいいような気がするけど、試してません。
/etc/httpd/conf.d/proxy_ajaxterm.conf
ajaxtermをstopしておけばよいです

/etc/init.d/ajaxterm stop
chkconfig off ajaxterm


まだ、VPSはいろいろお試し中ではありますが、値段を考えると結構お得だとは思います。
実際の運用ではきびしいとは思いますが、テスト環境や簡単なバッチ処理なら全然問題ないかと