T

2013年のTiIconicFont + Alloy

ウェブ上の情報が少し古くなっていたようでいくつか質問があったので、現時点で動作するサンプルをまとめておきます。あすとろなんだっけかさんの『Titanium mobile “early” Advent Calendar 2012』の18日目、@hoyo1111 さんのエントリー『【18日目】AlloyでもTiIconicFontを使いたい』を参考にしています。というかこれをほぼまるまる使っています。書き方を入門者に対応しただけですね。

TiIconicFontはサイレントヒルのひげ怪人Titaniumユーザー会ではおなじみのk0sukeyさんが公開してくれている、Font AwesomeやLigature Symbols、SS PikaのようなウェブフォントをTitaniumのLabelでも利用できるようにするモジュールです。インストール方法は次の通りです:

(1)ダウンロード

Alloyのプロジェクトはもう作成しましたね?まだなら、先に作成しておいてください。

TiIconicFontはGithubのページからZIP形式でダウンロードしたりgitでcloneして入手します。

(2)展開

Zipで落とした人はTiIconicFont-masterとかいう名前のディレクトリの下のResources/lib、cloneした人はTiIconicFont/Resouces/libを自分のAlloyのプロジェクトのapp/assets/以下にコピーします。app/assets/libディレクトリが作成されていることを確認しましょう。

(3)フォントデータの用意

TiIconicFontはそれだけでは動作しません。フォントのデータ(ttf)ファイルが必要です。例えばFont Awesomeならプロジェクトのウェブサイトからダウンロードして、展開したディレクトリのfont/fontawesome-webfont.ttfをapp/assets/fonts/以下にコピーします。app/assets/fontsディレクトリは存在しないので作成してからコピーしましょう。

app/assets以下にこれらが用意されればOKです。

app/assets/
├── fonts
│   └── fontawesome-webfont.ttf
└── lib
    ├── FontAwesome-deprecate.js
    ├── FontAwesome.js
    ├── IconicFont.js
    ├── LigatureSymbols-deprecate.js
    ├── LigatureSymbols.js
    └── ti.ss-pika.js

(4)iOS用の設定

iOSの場合は必要なファイルを生成するためにいったんビルドします。ビルドして作成されるbuild/iphone/Info.plistをプロジェクトディレクトリの直下にコピーして、コピーした方のファイルの最下部(/dictの上)に以下を追記します。Androidの場合は無視して地球の未来のことを考えます。

	<key>UIAppFonts</key>
        <array>
          <string>/fonts/fontawesome-webfont.ttf</string>
          <string>/fonts/LigatureSymbols.ttf</string>
          <string>/fonts/ss-pika.ttf</string>
        </array>

(5)動作試験用のViewを用意

app/views/index.xmlに下のような記述を用意します。

  <Label id="symbol" />

app/styles/index.tssにも適当な値を設定しておきましょうか。

"Label": {
  width: Ti.UI.SIZE,
  height: Ti.UI.SIZE,
  color: "Black"
}

(6)動作試験用のcontrollerを用意

app/controllers/index.jsに次のように記述します。

// Font Awesome
var fontawesome = require('lib/IconicFont').IconicFont({font: 'lib/FontAwesome'});
$.symbol.setFont({fontSize: 32, fontFamily: fontawesome.fontfamily()});
$.symbol.setText(fontawesome.icon('icon-thumbs-up'));

$.index.open();

Font Awesomeで利用できるアイコンの一覧はlib/FontAwesome.jsにあります。

(7)自慢

awesome_android

Androidあるある

Ti.Media.createAudioPlayerしたら。

 audioPlayer.addEventListener('error', (e)=>
    # htcだと常にこのエラーが出る
    if e.message != 'Unknown media issue'
      audio.pause()
      error_message()
    return
  )

Android 4でPicker(Titanium.UI.PICKER_TYPE_TIME)

またまたAndroid BK通信です。

Titanium Mobileは正式にはAndroid 4に対応していません。しかし、Androidもさすがにアホじゃないので下位互換性はほぼ保たれているため、ほとんどの場合は問題なく動作します。

という書き方をすればお気付きかもしれませんが、当然動かない場合もあります。今日はそのような問題のひとつ、Pickerについて報告します。

Android 4からTimerPicker.javaupdateInputStateという関数が追加されています。Titanium MobileでcreatePickerした際にtypeプロパティをTitanium.UI.PICKER_TYPE_TIMEにすると、このTimerPickerが呼び出されるのですが、実はこのupdateInputState関数には問題があって、IME経由でPickerの値を変更した場合はいいのですが、+ボタンや−ボタンで変更すると入力値のチェックが甘くNullPointerExceptionでクラッシュしてしまいます。報告が上がってはいますが、修正はされていません。

var win = Ti.UI.createWindow();
var picker = Ti.UI.createPicker({type:Titanium.UI.PICKER_TYPE_TIME});
win.add(picker);
win.open();

これだけのコードで再現しますが、Android 3以下では動作しても4からはボタンで値を更新しようとするとクラッシュします。数字をタップしてIME経由で数字を入力すると落ちません。

というわけで、Android 4に対応する必要がある方はTitanium.UI.PICKER_TYPE_TIMEは諦めて

var win = Ti.UI.createWindow();
var hours = Ti.UI.createPickerColumn({width:Titanium.Platform.displayCaps.platformWidth/2});
for(var i = 0; i <= 24; i++){
  var row = Ti.UI.createPickerRow({title:i.toString() + '時'});
  hours.addRow(row);
}
var mins = Ti.UI.createPickerColumn({width:Titanium.Platform.displayCaps.platformWidth/2});
for(var i = 0; i <= 59; i++){
  var row = Ti.UI.createPickerRow({title:i.toString() + '分'});
  mins.addRow(row);
}
var picker = Ti.UI.createPicker({width:Titanium.Platform.displayCaps.platformWidth, useSpinner:true, columns:[hours, mins]});
win.add(picker);
win.open();

とかで逃げるしかありません。

Titanium DeveloperでAndroid(4)

いろいろと発見することが多い反面、だんだんとまとまりがなくなっていくシリーズ。というか、Androidがマジで嫌いになってきましたシリーズ。

AndroidのUIWebViewが曲者だ。例えばcreateWebViewして、その中のHTMLにvideoタグを埋め込んで動画再生しようとしても、iPhoneでは動くのにAndroidでは動かない。

じゃあ、どうすればいいか?調べると、Titanium側でcreateWebViewした際にUIWebViewのインスタンスにsetPluginStateまたはsetPluginsEnabledが設定されていないので、Titanium Mobileのソースコードを眺めて、webviewの作成時にはsetPluginsEnabled(true)を呼ぶように指定してリビルドしてみたが効果がなかった。そこでさらに調べてみると、どうやらアプリ内で作成されるviewからはHTML5の機能が動作しないのが仕様らしい。

これだけならAndroid師ねで終わるのだが、驚いたことに今度はTitanium側からもキツい攻撃が。リモートのファイルを普通にcreateVideoPlayerに設定しても、例外を吐いてクラッシュする(Androidのみ。当然iPhoneでは動く)。

.......
//どこかの大自然
var media_url = 'http://www.pocketjourney.com/downloads/pj/video/famous.3gp';
var activeMovie = Titanium.Media.createVideoPlayer({
  contentURL:media_url,
});
win.add(activeMovie);
win.addEventListener('close', function(){
  alert("Window closed");
  activeMovie.stop();
});
activeMovie.play();
.......

まとめると:

(1)AndroidではvideoタグのようなHTML5の機能をアプリ内のwebviewから利用することは出来ない。これはAndroidの仕様なので、PhoneGapを使っていても同じ目に遭う

(2)Titanium Mobile (SDK 1.5)ではAndroidでcreateVideoPlayerからリモートの動画を読み込むことは出来ない。

つまり、Androidでリモートの動画を再生したければ、aタグでちょちょいとやっつけるか、PhoneGapでプラグインを作成するか、またはちゃんとJavaで書くしかない、ということ。プロジェクトをeclipseにエクスポートする機能は公式には存在しないが、いちおうスクリプトが用意されてはいる。

$HOME以下にvim7.2を設置

珍しく管理権限のない環境でプログラミングすることになり、vimがminimalしか入っていないのでそんな拷問を受けるつもりはないから$HOME以下に設置したのだが、–with-tlib=ncursesにするとどうもうまくいかなかったのでメモ。

最終的に、–with-local-dir=$HOME を追加すると動作した。途中、-tlibを指定しろと怒られ、-with-tlib=ncursesを指定すると今度はそんなものは見つからないと(–prefix指定しているのに!)怒られ続けてキャッチ22だった。

うまくいったやり方:
ncurses

$ wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.7.tar.gz
$ tar zxfv ncurses-5.7.tar.gz 
$ cd ncurses-5.7
$ configure --prefix=$HOME
$ make
$ make install

vim

$ cd
$ wget ftp://ftp.vim.org/pub/vim/unix/vim-7.2.tar.bz2
$ tar jxfv vim-7.2.tar.bz2 
$ cd vim72
$ ./configure --prefix=$HOME --with-local-dir=$HOME --disable-selinux
$ make
$ make install

shredの制限

ファイルの完全消去について調べていたらいろいろ知らないことがshredのmanに書かれていたのでメモ。

ext3の場合、rootflags=data=journalとかになっているケースではshredは期待通りの動作をしない。data=ordered(デフォルト)かdata=writebackだと問題ない。詳しくはmountのmanを参照のこと。

特定のネットワークストレージ機器やNFS3の場合、期待通りの動作をしない。

RAIDだと復元可能になることがある。

DiCEだとときどきだめみたい

細かい原因調査はまだなのだが、DiCEで管理しているDynamicDNSの更新管理がときどきうまくいかない。幸い、value-domainで取得しているドメインだとGETのリクエストで更新することができるので、それを利用することにした。

管理画面からダイナミックDNSの管理画面に遷移して、取得済みドメインを選択すると、「ダイナミックDNS設定情報」というページが表示される。そのページにある「アクセス先の例」に記載されたURLの最後のIPアドレスの部分を削って自分の持っているドメインのリストとして保存したら、接続元IPアドレスを返してくれる自分用の「確認君」を設置して、以下のスクリプトをcronで回して代用する。

require 'nokogiri'
require 'open-uri'

ip_address = ''
src = open('http://maniac.s154.xrea.com/test.php').read
doc = Nokogiri::HTML(src)
doc.search('span').each do |node|
        ip_address = node.inner_html
end
File.open('./list.txt').each do |line|
        uri = line.strip + ip_address
        tmp = open(uri).read
        puts tmp
end if ip_address != ''

まあ動いているのでこれでよし。

CentOS 5.4でもprelinkはRuby-1.9.1のバイナリを破壊する、かも

CentOS 5.4上でRuby 1.9.1を使っているのだが、インストールしてしばらくするとこんな状態になってクラッシュしてしまっていた。

$ ruby -v
compile/should not be reached: compile.c:473

で、もう一回ruby-1.9.1をmake installすると何事もなくちゃんと動作する。ということは、rubyの実行ファイルが何かしらおかしなことになっているのではないか、と思って調べていたら、ちょっと前に「CentOS 4.7 では prelink が ruby 1.9.1 のバイナリを破壊する」というページをブックマークしていたのを思い出した。

というわけで、/etc/prelink.conf.d/ruby.conf というファイルを新たに作成し、

$ cat /etc/prelink.conf.d/ruby.conf 
-b /usr/bin/ruby

という記述を加えて様子見中。

update: 2010-03-30 今のところいけてる。

findの小ネタ

Linux(ext3)にNASでマウントした領域をfindで検索するとき、普通に実行しても再帰的に検索はしてくれないのね。

実際には2階層下にファイルがある:

$ ls -R nas_mnt_point
a b c

nas_mnt_point/a
a.txt

nas_mnt_point/b
b.txt

nas_mnt_point/
c.txt

でもfindでは:

$ find nas_mnt_point
nas_mnt_point/a
nas_mnt_point/b
nas_mnt_point/c

で、symlinkと同じように-followオプションを付けると:

$ find nas_mnt_point -follow
nas_mnt_point/a
nas_mnt_point/a/a.txt
nas_mnt_point/b
nas_mnt_point/b/b.txt
nas_mnt_point/c
nas_mnt_point/c/c.txt

それだけ。

Fedora 11 on hp mini(無線LANとWillcom)

ぜんぜん更新されないhp miniのLinuxディストリビューション「MIE」に不安を覚えたのと、ネットブック風デスクトップやharbour-launcherが気に入らなかったので、Fedoraに戻ることにした。

インストールはいたって簡単で、liveusb-creatorを利用してUSBメモリにイメージを作成して、USBスロットに挿してからf9キーを押しながら起動、デスクトップに表示されるインストーラのアイコンから普通にインストール作業を進める。

ここまではいいのだが、それですべてというわけにはいかない。一番困ったのが、デフォルト状態では無線LANがうんともすんともいわないこと。

# lspci -v|grep Network
01:00.0 Network controller: Broadcom Corporation BCM4312 802.11b/g (rev 0

Broadcom社のBCM4312という製品を動作させる必要があるようだ。RPM Fusionにこれに対応したドライバがあるので以下の要領でyumで追加できるようにした。

# su -c 'rpm -Uvh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm \
http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm'
# yum install broadcom-wl

ところが、インストール時のカーネル2.6.29だと問題なく動作するのに、yum updateでカーネルを更新してしまうと動作しなかった。いろいろ調べてみたが、結局ここで見つけた手順に従い/etc/modprobe.d以下の適当なところで

# yum install wl-kmod
# echo "install ssb /sbin/modprobe wl;/sbin/modprobe --ignore-install ssb" >> /etc/modprobe.d/dist-oss.conf

として再起動したところ、無事に動作した。

それから、外出先でWillcomのUSBモデムNS001U(netIndex)を使いたかったのでこちらも設定したが、特に難しいこともなく、普通に「システム」→「管理」→「ネットワーク」から新しいハードウェアとして一般的なモデムを選択し、USBモデムが/dev/ttyACM0として認識されていたのでモデムデバイスとして指定、それからデバイスとしてプロバイダ情報にあれこれ書き込み、「Willcom」として保存すると、/etc/sysconfig/network-scripts以下にifcfg-willcomというファイルが出来上がっていて、/etc/ppp/peers/willcomもさっくり用意されるので、あとは

# ifup willcom

で接続できた。めでたしめでたし。