ようへい

2013年12月10日火曜日

Nexus 7(2012) を KRT16S(4.4) から KOT49H(4.4.2) にアップデートした時のroot再取得メモ

Nexus 7(2012) を KRT16S(4.4) から KOT49H(4.4.2) にアップデートした時のroot再取得メモ
Nexus 7 (2012)をKRT16S から KOT49H にした際に rooted から unroot な環境になってしまったので、後々同じことでアタフタしないようにメモ。

再びrootを取る準備

まずは、OEM Unlockが済んでいること。まぁ、もともとrootが取れていた環境なら問題ないはず。
あとは、以下のファイルを準備。
SuperSU
http://forum.xda-developers.com/showthread.php?t=1538053f
TWRP
TWRP 2 - Nexus 7 page
いずれも最新版をダウンロードする。 SuperSUはダウンロード後、Nexusの内部ストレージにコピーしておく。
TWRPは、C:\TEMPなどに置く。
以下の手順では、C:\TEMPに置いたことを想定して進める。

root取得作業

  1. 電源が切れた状態で、電源ボタンとボリュームダウンボタンを押しながら起動し、bootloaderモードにする。
  2. bootloaderモードの状態でPCと接続
  3. カスタムリカバリ導入
    > fastboot flash recovery C:\TEMP\openrecovery-twrp-2.6.3.1-grouper.img
    sending 'recovery' (7766 KB)...
    OKAY [  0.941s]
    writing 'recovery'...
    OKAY [  0.577s]
    finished. total time: 1.518s
  4. リブートし、bootloaderモードへ
    > fastboot reboot-bootloader
    rebooting into bootloader...
    OKAY [  0.020s]
    finished. total time: 0.020s
  5. Recovery modeを選択しTWRPを起動
  6. TWRPでinstallを選択し、SuperSUのインストール
  7. Reboot SystemでNexus 7をリブート
  8. Titanium Backupなどが起動することを確認
以上

まぁ、コレまでと一緒の手順ですね。
関連記事

2013年11月25日月曜日

Nexus 7(2012) を JWR66Y(4.3) から KRT16S(4.4) にアップデートした時のroot再取得メモ

Nexus 7(2012) を JWR66Y(4.3) から KRT16S(4.4) にアップデートした時のroot再取得メモ
KitKatリリース!!
Nexus 7 (2012)をJWR66Y から KRT16S にした際に rooted から unroot な環境になってしまったので、後々同じことでアタフタしないようにメモ。

再びrootを取る準備

まずは、OEM Unlockが済んでいること。まぁ、もともとrootが取れていた環境なら問題ないはず。
あとは、以下のファイルを準備。
SuperSU
http://forum.xda-developers.com/showthread.php?t=1538053f
TWRP
TWRP 2 - Nexus 7 page
いずれも最新版をダウンロードする。 SuperSUはダウンロード後、Nexusの内部ストレージにコピーしておく。
TWRPは、C:\TEMPなどに置く。
以下の手順では、C:\TEMPに置いたことを想定して進める。

root取得作業

  1. 電源が切れた状態で、電源ボタンとボリュームダウンボタンを押しながら起動し、bootloaderモードにする。
  2. bootloaderモードの状態でPCと接続
  3. カスタムリカバリ導入
    > fastboot flash recovery C:\TEMP\openrecovery-twrp-2.6.3.1-grouper.img
    sending 'recovery' (7766 KB)...
    OKAY [  0.937s]
    writing 'recovery'...
    OKAY [  0.487s]
    finished. total time: 1.424s
  4. リブートし、bootloaderモードへ
    > fastboot reboot-bootloader
    rebooting into bootloader...
    OKAY [  0.020s]
    finished. total time: 0.020s
  5. Recoveryを選択しTWRPを起動
  6. TWRPでinstallを選択し、SuperSUのインストール
  7. Reboot SystemでNexus 7をリブート
  8. Titanium Backupなどが起動することを確認
以上

まぁ、コレまでと一緒の手順ですね。
関連記事

2013年10月26日土曜日

Android でパケットキャプチャしてみる

Android でパケットキャプチャをしてみたので、忘れないようにメモ。
Unix OS 等でtcpdumpに触れたことがある方向けに書くので、わからない方はスルーしてください。

準備

  1. Android端末のroot取得
  2. Android Virtual Devices ManagerにてAndroid端末と同じバージョンの仮想端末を作成する
※以下から落とした tcpdump でも使えます。
Android tcpdump Downloads
https://www.androidtcpdump.com/android-tcpdump/downloads

キャプチャしてみよう

  1. Android Virtual Devices Manager (以下AVD)にて、Android端末と同バージョンの仮想端末を起動。
  2. 仮想端末からtcpdumpを取得。
    > adb -e pull /system/xbin/tcpdump C:\temp
    737 KB/s (652964 bytes in 0.865s)
  3. Android端末とPCをつなぎます。
  4. 認識しているか確認。
    > adb devices
    List of devices attached
    xxxxxxxxxxxxxxxxx    device
  5. エミュレータから取得したtcpdumpを端末に入れます。
    > adb push C:\temp\tcpdump /sdcard/tcpdump
    3021 KB/s (652964 bytes in 0.211s)
  6. /system にtcpdumpをおけるよう、rwモードでリマウント。
    > adb shell
    shell@android:/ $ su
    su
    root@android:/ # mount -o remount,rw /dev/block/mtdblock0 /system
    mount -o remount,rw /dev/block/mtdblock0 /system
  7. tcpdumpが無いことを確認。
    root@android:/ # ls /system/xbin/tcpdump
    ls /system/xbin/tcpdump
    /system/xbin/tcpdump: No such file or directory
  8. tcpdumpのコピーと実行権付与。
    root@android:/ # cp /sdcard/tcpdump /system/xbin/tcpdump
    cp /sdcard/tcpdump /system/xbin/tcpdump
    root@android:/ # ls -l /system/xbin/tcpdump
    ls -l /system/xbin/tcpdump
    -rw-rw-r-- root     root       652964 2013-10-26 11:46 tcpdump
    root@android:/ # chmod 755 /system/xbin/tcpdump
    chmod 755 /system/xbin/tcpdump
    root@android:/ # ls -l /system/xbin/tcpdump
    ls -l /system/xbin/tcpdump
    -rwxr-xr-x root     root       652964 2013-10-26 11:46 tcpdump
  9. tcpdumpコマンド発行。
    root@android:/ # tcpdump -s 0 -vv -w /sdcard/tcpdump_20131026.pcap
    tcpdump -s 0 -vv -w /sdcard/tcpdump_20131026.pcap
    tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
  10. Android端末でキャプチャしたいアプリなど起動する。
  11. Ctrl+Cでキャプチャを終了
  12. Wiresharkなどでキャプチャしたファイルを開く
tcpdump導入済みであればこんな感じ。
> adb shell
shell@android:/ $ su
su
root@android:/ # tcpdump -s 0 -vv -w /sdcard/tcpdump_20131026.pcap
tcpdump -s 0 -vv -w /sdcard/tcpdump_20131026.pcap
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
インタフェースを調べてキャプチャする場合は以下
shell@android:/ # tcpdump -D
1.dummy0 [Up, Running]
2.wlan0 [Up, Running]
3.rmnet_usb0 [Up, Running]
4.lo [Up, Running, Loopback]
5.any (Pseudo-device that captures on all interfaces) [Up, Running]
6.nflog (Linux netfilter log (NFLOG) interface) [none]
7.nfqueue (Linux netfilter queue (NFQUEUE) interface) [none]
8.sit0 [none]
9.usb0 [none]
10.rmnet_data0 [none]
11.r_rmnet_data0 [none]
12.rmnet_data1 [none]
13.r_rmnet_data1 [none]
14.rmnet_data2 [none]
15.r_rmnet_data2 [none]
16.rmnet_data3 [none]
17.r_rmnet_data3 [none]
18.rmnet_data4 [none]
19.r_rmnet_data4 [none]
20.rmnet_data5 [none]
21.r_rmnet_data5 [none]
22.rmnet_data6 [none]
23.r_rmnet_data6 [none]
24.rmnet_data7 [none]
25.r_rmnet_data7 [none]
26.r_rmnet_data8 [none]
shell@android:/ # tcpdump -i 2 -vv -w /sdcard/tcpdump_20131026.pcap
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 262144 bytes
ちなみに私が使用した仮想端末に入っていたtcpdumpのバージョンは以下。
root@android:/ # tcpdump --help
tcpdump --help
tcpdump version 3.9.8
libpcap version 0.9.8
Usage: tcpdump [-aAdDeflLnNOpqRStuUvxX] [-c count] [ -C file_size ]
                [ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]
                [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
                [ -W filecount ] [ -y datalinktype ] [ -Z user ]
                [ expression ]
関連記事

2013年10月18日金曜日

S-OFF済みのHTL22を Android 4.2.2 (2.15.970.1) にアップデートしてみた

S-OFF済みのHTL22を Android 4.2.2 (2.15.970.1) にアップデートしてみた
私が所有するスマフォで初のHTC機となるHTL22
S-OFFとか、独特の仕様があってナカナカとっつきにくい。
初のHTC機という事でビビッていたというのと、HTC速報Devさんで提供していただいている初期の自作RUUに不具合があったというので、アップデートをためらっていたのだが、アップデート通知がうるさくなってきたのでアップデートしてみた。

前提条件

  • ビルド 1.07.970.4 の時点でS-OFFを行ってあること
  • ClockworkModなどのカスタムリカバリが導入済みであること

準備するもの

HTC速報さん提供の4.2.2対応ClockworkMod (recoverycwm2.img)
au HTL22 HTC J One 2.15.970.1のアップデートの現在状況と、更新ファイル(CWM/RUU)等を公開した件について (HTC速報Dev) | HTC速報
http://htcsoku.info/htcsokudev-news/au-m7wlj-2159701/
HTC速報さん提供の 4.2.2 のRUU (RUU_M7_WLJ_JB422_SENSE50_MR_KDDI_JP_2.15.970.1_Radio_1.23.11.0829_NV_3.39_01C_unsigned_htcsoku_PN07IMG.zip)
au HTL22 HTC J One 2.15.970.1のアップデートの現在状況と、更新ファイル(CWM/RUU)等を公開した件について (HTC速報Dev) | HTC速報
http://htcsoku.info/htcsokudev-news/au-m7wlj-2159701/
SuperSU (現時点ではUPDATE-SuperSU-v1.65.zip)
SuperSU - xda-developers
http://forum.xda-developers.com/showthread.php?t=1538053

アップデート

基本的にはHTC速報Devさんに書かれている手順通り
  1. RUUのzipからsystem.imgを抽出し、SDカードに入れる
  2. RUUのzipをPN07IMG.zipにリネームし、SDカードに入れる
  3. SuperSUをSDカードに入れる
  4. HTL22の電源OFF
  5. 電源+ボリュームダウンを押してFASTBOOT起動
  6. recoveryでCWM起動
  7. mounts and storage -> mount /exrernal_sd
  8. PCと接続し、コマンドプロンプトにてHTC速報Devさんに書かれているコマンドを発行
    >adb shell
    ~ # dd if=/external_sd/system.img of=/dev/block/mmcblk0p38
    dd if=/external_sd/system.img of=/dev/block/mmcblk0p38
    4587518+0 records in
    4587518+0 records out
    2348809216 bytes (2.2GB) copied, 1046.241385 seconds, 2.1MB/s
    ~ # reboot bootloader
    reboot bootloader
    system.imgの書き込みに約20分かかった
  9. FASTBOOTから、HBOOT起動
  10. すると、自動でRUUが始まる
  11. しばらく待つ
  12. Do you want to start update? <VOL UP> Yes <VOL DOWN> Noと表示されることを確認。
  13. ボリュームアップを押してアップデート
  14. system.imgのみFail-scになることを確認
  15. ここまででアップデート完了
  16. 再度FASTBOOT起動
  17. PCと接続し、コマンドプロンプトにてCWMをフラッシュ
    > fastboot flash recovery recoverycwm2.img
    > fastboot reboot-recovery
  18. CWMにてinstall zip from sdcard -> choose zip from external sdcard -> SuperSUのzipを選択しインストール
だいたいこんな感じです。
あとはBusyBox入れたり。
設定 -> バージョン情報 -> ソフトウェア情報 -> その他 -> ビルド番号を7回タップして、開発者向けオプションを出すのを忘れずに。
関連記事

2013年9月30日月曜日

Nexus 7(2012) を JWR66V から JWR66Y にアップデートした時のroot再取得メモ

Nexus 7 (2012)をJWR66V から JWR66Y にした際に rooted から unroot な環境になってしまったので、後々同じことでアタフタしないようにメモ。

再びrootを取る準備

まずは、OEM Unlockが済んでいること。まぁ、もともとrootが取れていた環境なら問題ないはず。
あとは、以下のファイルを準備。
SuperSU
http://forum.xda-developers.com/showthread.php?t=1538053f
TWRP
TWRP 2 - Nexus 7 page
いずれも最新版をダウンロードする。 SuperSUはダウンロード後、Nexusの内部ストレージにコピーしておく。
TWRPは、C:\TEMPなどに置く。
以下の手順では、C:\TEMPに置いたことを想定して進める。

root取得作業

  1. 電源が切れた状態で、電源ボタンとボリュームダウンボタンを押しながら起動し、bootloaderモードにする。
  2. bootloaderモードの状態でPCと接続
  3. 認識できているか確認
    > adb devices
    List of devices attached
    xxxxxxxxxxxxxxxxx    device
  4. カスタムリカバリ導入
    > fastboot flash recovery C:\TEMP\openrecovery-twrp-2.6.2.0-grouper.img
    sending 'recovery' (7992 KB)...
    OKAY [  0.965s]
    writing 'recovery'...
    OKAY [  0.612s]
    finished. total time: 1.577s
  5. リブートし、bootloaderモードへ
    > fastboot reboot-bootloader
    rebooting into bootloader...
    OKAY [  0.019s]
    finished. total time: 0.020s
  6. Recoveryを選択しTWRPを起動
  7. TWRPでinstallを選択し、SuperSUのインストール
  8. Reboot SystemでNexus 7をリブート
  9. Titanium Backupなどが起動することを確認
以上

ほかの端末も、このくらい簡単にroot取れたらいいんだけどなぁ。
関連記事

2013年8月6日火曜日

Rubyで、パスに特殊文字を含むファイルの存在確認を行う

ファイルがあるのに「No such file or directory」

Windows上でRubyを使っていると、ファイルパスに特殊文字を含んだファイルを扱う事がある。
e.g.,
».htm
®.htm
™.htm
これらのファイルをRubyスクリプトの引数で渡してもファイル名が化けてしまったりしてうまく扱えない。
こんなRubyスクリプトに渡してみる。
#!ruby
# -*- coding: utf-8 -*-

puts File.basename( ARGV[0] )
puts File.exist?( ARGV[0] )
puts File.exist?( ARGV[0].dup.force_encoding( 'utf-8' ) )
puts ARGF.path
環境はWindows 7、Ruby 1.9.3、Encoding.locale_charmapCP932。 このスクリプトに先のファイル名を与えると以下のような結果になる。
».htm
≫.htm
false
false
file_check.rb:7:in `path': No such file or directory - ≫.htm (Errno::ENOENT)
 from file_check.rb:7:in `<main>'
®.htm
R.htm
false
false
file_check.rb:7:in `path': No such file or directory - R.htm (Errno::ENOENT)
 from file_check.rb:7:in `<main>'
™.htm
R.htm
false
false
file_check.rb:7:in `path': No such file or directory - R.htm (Errno::ENOENT)
 from file_check.rb:7:in `<main>'
UTF-8のバイナリで表すと、以下のように文字が変化してしまっている。
».htm -> ».htm (0xC2 0xBB -> 0xE2 0x89 0xAB)
®.htm -> R.htm (0xC2 0xAE -> 0x52)
™.htm -> R.htm (0xC2 0xE2 0x84 0xA2 -> 0x52)
どーしたらいいんでしょうか。

できる対処法

とりあえず、Rubyをキックするバッチを作って、その中でテンポラリディレクトリにファイルを複製、リネームして、そのファイルをRubyスクリプトに与えることで対処。
こんなかんじ。
SET FDATE=%date:~2%
SET FTIME=%time:.=-%
SET FTIME=%FTIME: =%
SET TEMP_F="%TEMP%\%FDATE:/=-%_%FTIME::=-%%~x1"

COPY %1 %TEMP_F%
C:\Ruby193\bin\ruby file_check.rb %TEMP_F%
DEL %TEMP_F%
Rubyの中で、オリジナルのパス名が必要なら、こんなカンジ。
SET FDATE=%date:~2%
SET FTIME=%time:.=-%
SET FTIME=%FTIME: =%
SET TEMP_F="%TEMP%\%FDATE:/=-%_%FTIME::=-%%~x1"

COPY %1 %TEMP_F%
C:\Ruby193\bin\ruby file_check.rb %TEMP_F% %1
DEL %TEMP_F%
とりあえずファイル読めるようになる。
もっと効率良い方法あると思うので、教えてください。
関連記事

2013年7月18日木曜日

非推奨になった Mutation events を Mutation Observers に置き換えよう

前からDOM3(黒い三連星じゃないよ)で実装されたDOMAttrModifiedや、DOMNodeInsertedをGreasemonkeyスクリプト内で使用していたのだが、これらのMutation eventsが非推奨となってしまったらしい。
じゃあ何を使ったらいいの?ということで、Mutation ObserversというAPIが提供されているらしい。 Mutation Observersの利用方法をまとめてみた。

ちょっと読んでみよう

使う前に、どうやって使うかなど、ちょっと頭に入れておこう。
Mozillaのページにまとめて書いてあるので、そちらを見れば大丈夫かと。
MutationObserver - Web API リファレンス | MDN
https://developer.mozilla.org/ja/docs/Web/API/MutationObserver MutationObserverにメソッドを与えてインスタンスを作成。
インスタンスメソッドのobserve実行時のオプションで、監視する種類などを設定すると。フムフム。

MutationObserverはこう使う

コードを見た方が速いので、まずは使い方から。
たとえば、DOMAttrModifiedMutationObserverに置き換えるとこんな感じ。
$('#hoge').bind('DOMAttrModified',function(event){
  console.dir(event);
});
var mo = new MutationObserver(function(mutationRecords){
  console.dir(mutationRecords);
});
mo.observe($('#hoge').get(0), {attributes: true});
変更前の値も欲しいならこう
var mo = new MutationObserver(function(mutationRecords){
  console.dir(mutationRecords);
});
mo.observe($('#hoge').get(0), {attributes: true, attributeOldValue: true});

Mutation eventsからMutationObserverへ移行しよう

こんな感じかな。
Mutation events Mutation Observers
DOMAttrModified observe( Node target, {attributes: true, attributeOldValue: true} );
DOMNodeInserted observe( Node target, {childList: true} );
DOMNodeRemoved observe( Node target, {childList: true} );
DOMCharacterDataModified observe( Node target, {characterData: true, characterDataOldValue: true} );
DOMSubtreeModified observe( Node target, {subtree: true} );
そして Firefox、Chromeは実装しているけど、Internet Explorerは未実装らしい。さすがやで!期待を裏切らない。それでこそIE。
IEは消費電力で勝負ですもんね。
よいこのみんな!夏は消費電力を抑えるためにIEを使おうね (オイ)
Internet Explorer 10の消費電力はChromeやFirefoxより18%低い, とMicrosoftは主張 | TechCrunch Japan
http://jp.techcrunch.com/2013/06/06/20130605microsoft-internet-explorer-10-is-the-most-energy-efficient-browser-uses-up-to-18-less-power-than-chrome-and-firefox/
関連記事

2013年6月21日金曜日

Firefoxでの HTML5 Notifications (デスクトップ通知) 設定変更方法

Firefox 22から実装されているHTML5 Notifications APIですが、権限がリクエストされた時にこんなポップアップが表示されます。
Firefoxでの HTML5 Notifications (デスクトップ通知) 設定変更方法
Firefoxでの HTML5 Notifications (デスクトップ通知) 設定変更方法
ここで、デスクトップ通知の許可/拒否を設定します。
常に通知を表示する」か「通知をブロックする」に設定した場合、以後はポップアップが表示されません。
許可されると、こんなカンジでデスクトップ通知を受けれます。
Firefoxでの HTML5 Notifications (デスクトップ通知) 設定変更方法
のちのち、この設定を変更したいという場合、どうやったら変更できるのか調べてみました。

設定に無い!

まずオプション画面を一通り見たのですが、該当の設定がありませんでした。
こりゃ困った。
どっかには保存されているだろうと、Firefoxのprofileを覗いてみる。
permissions.sqliteに、typedesktop-notificationとなっているレコードを発見。hostの値も合っているし、これっぽい。
最悪、ここから変更はできそう。
でも、さすがに設定画面が用意されていない事は無いだろう。ということで、Firefoxの画面を一通り調べてみた。

こんなところにあった

ありましたよ。分かりにくいけど。
Firefoxのメニューから、ツール»ページの情報をクリックして、サイト別設定タブを開く。
すると、サイトからの通知の表示というのがあるので、ここから設定できます。
Firefoxでの HTML5 Notifications (デスクトップ通知) 設定変更方法
Firefoxでの HTML5 Notifications (デスクトップ通知) 設定変更方法
一括管理できる画面欲しいなぁ・・・。
FirefoxでのHTML5 Notifications API 通知方法 - ログろいど
関連記事

FirefoxでのHTML5 Notifications API 通知方法

Firefox 22からHTML5 Notifications APIがサポートされるという事で早速使ってみた。 とりあえずこんな感じで使える。
function notifyReq(){
  Notification.requestPermission(function(permission){
    console.debug("Notification permission: "+permission);
    if(Notification.permission == "granted"){
      notify();
    }
  });
};
function notify(){
  switch(Notification.permission){
    case "granted":
      new Notification("デスクトップ通知テスト", {
        icon:"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixMhqVE-KPC4uFvSew7A5jZ64O0oJVsUXtBJVwv6JTF0BRIV_dI0hyYUh8qEGR6pdJ-WJaYd9xk97foeo_VCFIXc1O6vI8wWbl6grHGpbItKdrIMbn4tU8w4Zeaqj05ynBJdbhEHtkyWgE/s220/logroid_150.png",
        body:"デスクトップ通知のテストです",
        tag:"notification-test",
      });
      break;
    case "default":
      notifyReq();
      break;
    case "denied":
      console.warn("デスクトップ通知が拒否されています");
      break;
  }
};
notify();
こんなカンジで通知されます。
FirefoxでのHTML5 Notifications API 通知方法
Notification.permissionで現在の権限を見ることができる。
デフォルト状態(ポップアップ表示)なら"default"、許可されていれば"granted"、拒否されていれば"denied"の文字列が返される。
表示が許可されていない場合はNotification.requestPermissionで、権限をリクエストする。こんなポップアップが表示される。
FirefoxでのHTML5 Notifications API 通知方法
FirefoxでのHTML5 Notifications API 通知方法
その後、new Notificationにタイトルとオプションを設定したハッシュを渡す。
ハッシュの中のiconはURLでも良いし、base64の文字列でも良い。
tagを設定すると、デスクトップ通知が多重表示されるのを防げる。
という感じ。
また、new Notificationで得られるインスタンスには、oncloseonclickonerroronshowイベントが登録できる。
onclick時に得られるEventのtargetはNotificationオブジェクトとなっている。
通知クリックで、該当のウィンドウ(タブ)をアクティブ化とかできれば楽しそうだったけど、無理っぽい。

デモ

Firefoxでの HTML5 Notifications (デスクトップ通知) 設定変更方法 - ログろいど
関連記事

2013年6月14日金曜日

HTC J butterfly(HTL21)、 HTC J One(HTL22) スペック比較

OTAアップデートされたHTL21、新しく発売になったHTL22、ともにS-OFFが出来るようになったということで、そろそろ購入を検討。
値下がりしてカラーバリエーションもあるHTL21もいいけど、新しいHTL22も良い。
どっちにしようかという事でスペック比較してみました。
HTL21 HTL22
発売日 2012/12/9 2013/6/1
OS Android 4.1 Android 4.1
CPU Qualcomm Snapdragon S4 Pro APQ8064 1.5GHz Qualcomm Snapdragon 600 APQ8064T 1.7GHz
CPU コア数 4 4
RAM 2GB 2GB
ROM 16GB 32GB
ディスプレイ
サイズ
5インチ 4.7インチ
ディスプレイ
解像度
1920×1080 1920×1080
メインカメラ
画素数
800万(F値2.0) 400万(F値2.0)
microSD 最大2GB 最大2GB
microSDHC 最大32GB 最大32GB
microSDXC - 最大64GB
バッテリー容量 2020mAh 2300mAh
連続通話時間 約750分 約820分
連続待受時間
(LTE)
約270時間 約370時間
連続待受時間
(3G)
約360時間 約450時間
充電時間 約170分 約150分
サイズ 約143 × 71 × 9.1 mm 約138 × 69 × 10.5 mm
質量 約140 g 約157 g
S-OFF 可(2013/06/13現在) 可(2013/06/13現在)
HTL22はHTL21よりコンパクトだけど、ちょっと重いんですね。なんでだろう。
HTL22の決定打が少ないんだよなぁ。
せめてレッドとかあれば惹かれたんですけど。
とはいえ、長く使うと思うのでHTL22のブラックにするかなぁ。
HTL22が3つボタンだったら良かったのになぁ・・・。
関連記事

2013年5月2日木曜日

Mozilla Firefox のアイコンを変更しよう (Firefox 21対応)

Mozilla Firefoxでは、以下のような手順でカンタンにブラウザアイコンを変更する事が可能です。

手順

ディレクトリ作成
Firefoxインストールパスに以下のようなディレクトリを作ります。
Firefox インストールパス(e.g., C:\Program Files\Mozilla Firefox)
└─browser
    └─chrome
        └─icons
            └─default
※Firefox 21で、ディレクトリ構成が変更になったので注意です。
アイコン配置
defaultディレクトリ内に、アイコンを置きます。
アイコンのファイル名は、アイコンを変えたいウィンドウに合わせて変更する必要があります。
main-window.ico
メインウィンドウ
places.ico
履歴とブックマークの管理
downloadManager.ico
ダウンロードマネージャ
CookiesDialog.ico
Cookie
PermissionsDialog.ico
例外サイト - 画像の読み込み/Cookie フィルタ/許可サイト - アドオンのインストール/オフラインデータ
SignonViewerDialog.ico
保存されているパスワード
certmanager.ico
証明書マネージャ
devicemanager.ico
デバイスマネージャ
全てのウィンドウのアイコンを変えたい場合は、main-window.icoplaces.icodownloadManager.icoCookiesDialog.icoPermissionsDialog.icoSignonViewerDialog.icocertmanager.icodevicemanager.icoという名前でアイコンをdefaultディレクトリ内に置いてください。
確認
Firefoxを起動してみましょう。
(起動中の場合は再起動しましょう)

アイコンは変わりましたか?

私はFirefoxのいろんなチャンネルを使っているので、stable版とbeta版のアイコンが同じで見にくかったので、beta版のFirefoxのアイコンを変更してみました。
before
Firefox のアイコンを変更しよう (Firefox 21対応)
どっちがbetaかワカラナイ・・・
after
Firefox のアイコンを変更しよう (Firefox 21対応)
一目瞭然
う~ん。わかりやすくなりましたね。
関連記事

2013年3月26日火曜日

セール情報の記事について

セール情報を毎日お届けしておりましたが、記事内にURLが多いため、GoogleのBotによって、スパムブログ扱いされてしまったようで、先日Googleによってブログが無効にされてしまいました。

ということで、このブログではセール情報をお届けするのは難しそうです。
リクエストが多ければ、ほかの場所で情報をお届けできる方法を考えてみようと思います。
関連記事

2013年2月20日水曜日

[AV-TEST] 2013年 Android向けウィルス対策ソフト テストレポートが公開されました

AV-TESTから、2013年 Android向けウィルス対策ソフトのレポートが公開されました。
AV-TEST - The Independent IT-Security Institute: Android
http://www.av-test.org/en/tests/mobile-devices/android/
AV-TEST - The Independent IT-Security Institute: Jan 2013
http://www.av-test.org/en/tests/mobile-devices/android/jan-2013/ 検出率、操作性トップは、無料アプリのTrustGo Inc.アンチウイルス&モバイルセキュリティ
あまり聞いたこと無いベンダーだが、CNET等からも評価されているようだ。
トレンドマイクロや、シマンテックは無料ソフトに検出率、操作性で負けるという結果に・・・。
検出率上位4アプリは以下
アプリ名評価価格マーケットリンク
アンチウイルス&モバイルセキュリティ
Antivirus & Mobile Security
★★★★★
★★★★★
4.7
46930
無料
AVL
★★★★★
★★★★★
4.3
82
無料
ウイルス対策セキュリティアプリ Lookout
Lookout Security & Antivirus
★★★★★
★★★★★
4.5
400463
無料
Mobile Security & Antivirus
★★★★★
★★★★★
4.4
5462
無料
  • アプリ名のカッコ内の文字は英名のアプリ名
  • 評価のカッコ内の数値は評価数
  • 価格は記事投稿時のストア価格(アプリ内課金の価格を除く)
試しにアンチウイルス&モバイルセキュリティ入れてみた。
最初にユーザ登録を行う。
メールアドレスと、パスワードを入れて登録すると、メールアドレス認証URLが書かれたメールが届くので認証する。
ところどころ日本語がおかしいが、動作も軽く問題無さそう。
あとはバッテリーをどの程度消費するか・・・。
数日経過を見たいと思います。
2013年 Android向けウィルス対策ソフト テストレポート
メイン画面
2013年 Android向けウィルス対策ソフト テストレポート
2013年 Android向けウィルス対策ソフト テストレポート
メモリ消費は30MB弱
関連記事

2013年2月19日火曜日

[GAE/J] Google App Engine Java SDK 1.7.5 がリリースされました

Google App Engine Java SDK 1.7.5 がリリースされました。 リリースノートは以下。
  • New instance classes F4_1G and B4_1G are now available. These instances have compute capacity equal to F4/B4 but with a maximum of 1G RAM instead of 512MB.
  • The DataNucleus plugin has been upgraded to 2.1.2.
  • The deprecated classes AddException, AddResponse, ListException, ListIndexesException, ListIndexesRequest, ListIndexesResponse, ListRequest, ListResponse, and RemoveException were removed from the Search API in the SDK. If your app references any of these classes, you must deploy a new version without these references before the next release of App Engine. If you do not do this, your app may stop working in production.
  • The Conversion API, which was decommissioned last release, has been removed from the SDK. In a future release, the API will be removed from the runtime and applications that attempt to use it may stop working. Applications in production that import the library should be fixed as soon as possible.
  • We are making Java 7 available as an experimental feature. We strongly encourage local and production testing for all existing applications. For more information, please visit: http://developers.google.com/appengine/docs/java/java7
  • The Channel API now has the ability to send channel messages from any app version or backend regardless of where the channel was created.
  • The URL Fetch service now supports PATCH method requests.
  • The Mail API can now send mail bounce notifications to the app. The notification will be delivered to /_ah/bounce if mail_bounce inbound services are enabled.
  • The Blobstore service now returns the created filename instead of the blobKey when using Cloud Storage
  • Fixed an issue with Datastore callback annotations not working when running locally on Windows.
SdkForJavaReleaseNotes - googleappengine - Google App Engine Java SDK Release Notes - Google App Engine - Google Project Hosting
http://code.google.com/p/googleappengine/wiki/SdkForJavaReleaseNotes
実験的ではあるようですが、Java 7ランタイムがサポートされたようです。
試しに、Javaコンパイラーの準拠レベルを1.7にしてdeployしてみましたが、問題なく動いているようです。
Java 7ランタイムを有効にすると、deploy時にコンソールにUsing java7 runtime: trueと出力されました。
Java 7 Considerations - Google App Engine — Google Developers
https://developers.google.com/appengine/docs/java/java7
関連記事

2013年2月13日水曜日

[GAE/J] Version not ready. でデプロイが失敗する場合

2013/2/2 GAEにプロジェクトをdeployしようとしたらVersion not ready.というエラーで失敗した。
今までデプロイできていたプロジェクトだったのだが、ソースに手を加えていたので、前回デプロイした時の状態にソースをrollbackしてdeployしてみた。
しかし、結果は変わらず。
以下のようなダイアログが表示される。
See the deployment console for more details
Unable to update app: Version not ready.
eclipseのコンソールには以下のメッセージが出力されていた。
------------ Deploying frontend ------------

Preparing to deploy:
 Created staging directory at: 'C:\Users\Logroid\AppData\Local\Temp\appcfg5512351679699059483.tmp'
 Scanning for jsp files.
 Scanning files on local disk.
 Initiating update.
 Cloning 37 static files.
 Cloning 117 application files.

Deploying:
 Uploading 0 files.
 Initializing precompilation...
 Deploying new version.

Verifying availability:
 Will check again in 1 seconds.
 Will check again in 2 seconds.
 Will check again in 4 seconds.
 Will check again in 8 seconds.
 Will check again in 16 seconds.
 Will check again in 32 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
 Will check again in 60 seconds.
  on backend null.
java.lang.RuntimeException: Version not ready.

Debugging information may be found in C:\Users\Logroid\AppData\Local\Temp\appengine-deploy1109906141324865915.log
コンソールに表示されたログの中身は以下
Unable to update:
java.lang.RuntimeException: Version not ready.
 at com.google.appengine.tools.admin.AppVersionUpload.commit(AppVersionUpload.java:572)
 at com.google.appengine.tools.admin.AppVersionUpload.doUpload(AppVersionUpload.java:143)
 at com.google.appengine.tools.admin.AppAdminImpl.doUpdate(AppAdminImpl.java:371)
 at com.google.appengine.tools.admin.AppAdminImpl.update(AppAdminImpl.java:53)
 at com.google.appengine.eclipse.core.proxy.AppEngineBridgeImpl.deploy(AppEngineBridgeImpl.java:433)
 at com.google.appengine.eclipse.core.deploy.DeployProjectJob.runInWorkspace(DeployProjectJob.java:148)
 at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:38)
 at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
その後も試行錯誤してみたが、他のプロジェクト(前回デプロイ時からソース等、無変更)もデプロイに失敗する事から、この事象はGoogle App Engine サーバ側の問題であると考えた。
Twitter等で検索しても、他にも同じような状態になっている人もいるようだった。
また、Google グループのフォーラムにも同じ状態になっている人が居た。
Eclipseのプラグインでアプリケーションをアップロードしていたのですが、2013/02/02の午後からアップロードができなくなりました。
Eclipseの環境の問題かもしれないとAppcfgに切り替えてアップロードを再度試みたのですがやはり同じ結果です。
エラー内容:
...
99% Will check again in 60 seconds.
2013/02/03 1:46:39 com.google.appengine.tools.admin.AppVersionUpload commit
致命的: Version still not ready to serve, aborting.
99%  on backend null.

java.lang.RuntimeException: Version not ready.
Unable to update app: Version not ready.

こちらの問題ではなくApp-Engin側のような気がします。
同じ現象が発生した方はいらっしゃいますか?
アップロードができない - Google グループ
https://groups.google.com/forum/#!topic/google-app-engine-japan/qeVkTzjqKbU
翌日、改めてdeployしたら、今度はすんなりdeployできました。
という事で、どうやらサーバ側の一時的な障害だったようです。

Version not ready.となったら、サーバ側が回復するのを待ちましょう。
関連記事

[Twitter4J] Authentication credentials が発生する場合の対処

Twitter4JでTwitter APIを利用したアプリを作っていてハマったのでメモ

発端

これまでいくつもTwitter4Jを利用したアプリは作っていたので、今回もTwitterのAccess tokenを取得したり、プログラムを作るところはすんなり進んだ。
テストのため、Twitter4Jからつぶやいてみた。
しかし、以下のエラーが発生し、つぶやかれない。
Error: 401:Authentication credentials (https://dev.twitter.com/pages/auth) were missing or incorrect. Ensure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync. message - Error processing your OAuth request: Read-only application cannot POST code - 89 Relevant discussions can be found on the Internet at: http://www.google.co.jp/search?q=******** or http://www.google.co.jp/search?q=******** TwitterException{exceptionCode=[********-********], statusCode=401, message=Error processing your OAuth request: Read-only application cannot POST, code=89, retryAfter=-1, rateLimitStatus=null, version=3.0.3}
access token作った時、Access levelRead and writeにしたよなぁ・・・と思い、My applicationsでYour access tokenのAccess levelを確認したところ、Read-onlyになってました。
access token作った際の手順を思い出してみました。
おそらく、Access levelがRead-onlyの状態でaccess tokenを作って、その後Read and writeに設定したと思われます。

Twitterアプリ作成時の手順

失敗を繰り返さないように、備忘録として手順を整理します。
  1. SettingsでAccess levelRead and writeに設定
  2. access tokenの発行
  3. Detailsで、Your access tokenのAccess levelRead and writeであることを確認
関連記事

2013年1月30日水曜日

[SyntaxHighlighter] Windowsバッチファイル用Brush

Windowsバッチファイル用のSyntaxHighlighter用Brushを作ってみましたので、公開します。
Brushのエイリアスは、batcmdcomです。
このBrushを使うと、Windowsバッチファイルが以下のようにハイライトされます。
@echo off
setlocal enabledelayedexpansion
for /F "usebackq delims=" %%A in (`reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"`) do (
  set PDN=
  call :findPDN %%A
  rem ParentDisplayNameが見つかった場合は、ParentDisplayNameへのパッチファイルとみなし、一覧出力しない
  if "!PDN!" EQU "" call :echoDN %%A
)
setlocal disabledelayedexpansion
pause
exit

:findPDN
rem find ParentDisplayName
for /F "tokens=2,*" %%B in ('reg query "%*" /f ParentDisplayName /c /e ^| findstr "ParentDisplayName"') do set PDN=%%C
exit /b

:echoDN
rem find DisplayName
for /F "tokens=2,*" %%B in ('reg query "%*" /f DisplayName /c /e ^| findstr "DisplayName"') do echo %%C
exit /b
以下で実際に確認することが可能です。
SyntaxHighlighter用タグ 変換/生成ツール - ログろいど

ダウンロード

非圧縮版(2.52KB)
https://sites.google.com/site/logroid/syntaxhighlighter/shBrushBat.js
圧縮版(1.98KB)
https://sites.google.com/site/logroid/syntaxhighlighter/shBrushBat.min.js
関連記事

2013年1月28日月曜日

Firefox で BFCache によるキャッシュを無効化する方法

発端

Firefox で開発をしていると、サーバのJavaScriptを変更してもFirefoxがキャッシュしているJavaScriptを使用してしまっていたりすることがある。
これがJavaScriptだけならまだCtrl+Shift+Rで強制読み込みさせて回避できるのだが、JSONの戻りまでキャッシュされてしまう事がある。
キャッシュされたリクエストをFirebugのネットタブで表示すると、以下のようになる。
※google.co.jpを表示した例
Firefox で BFCache によるキャッシュを無効化する方法
レスポンスヘッダを見ると、以下のメッセージが
キャッシュから直接リクエストが解決されたため、サーバからのレスポンスはありません。キャッシュされているレスポンスについては下を参照してください。
これは、Firefox 15から搭載されている、BFCache(Back-Forward Cache)という機能によるものだ。
Firefox 1.5 ではウェブページ全体をその JavaScript の状態も含めてメモリ内にキャッシュし、1 つのブラウザセッションとして使用します。訪問したページ間の戻る、進むという動作にページのロードが不要になり、JavaScript の状態も保存されます。この機能によってページナビゲーションが非常に高速化します。この機能は bfcache("Back-Forward Cache" のこと)と呼ばれることもあります。このキャッシュ状態はユーザがブラウザを閉じるまで保存されます。
Firefox がページをキャッシュしない場合があります。ページがキャッシュされないプログラム的な理由でよくあるものをいくつか以下に示します。
  • ページが unload ハンドラを使用している
  • ページが "cache-control: no-store" をセットしている
  • ページが "cache-control: no-cache" をセットしていて、サイトが HTTPS である
  • ページが完全にはロードされないまま、ユーザがそのページから去るナビゲートをする
  • トップレベルのページにキャッシュ不可能なフレームがある
  • ページがフレーム内にあり、ユーザがそのフレーム内に新しいページをロードする(この場合、ユーザがそのページから去るナビゲートをするとそのフレームに最後にロードされたコンテンツがキャッシュされる)
この新しいキャッシュ機能により、ページロードの挙動が変わります。ウェブ作者は次のことをしたいと思うことがあるでしょう。
  • ナビゲートされたことがあるページであることを知ること(そのページがユーザのキャッシュからロードされるとき)
  • ユーザがそのページを去るときのページの挙動を定義すること(ページがキャッシュされるようになっている間)
ブラウザの 2 つの新しいイベントによってウェブ作者はそのどちらもできるようになります。
JSONのレスポンスが保存されるのは、以下の記載によるものであると思われる。
ウェブページの標準的な挙動は次のとおりです。
  1. ユーザがページにナビゲートする。
  2. ページロード時にインラインスクリプトが実行される。
  3. ページがロードされると onload ハンドラが実行される。
4 ステップ目があるページもあります。ページが unload ハンドラを使用していると、ユーザがそのページから去るナビゲートをするときにそれが実行されます。unload ハンドラが存在しているとそのページはキャッシュされません。 ユーザがキャッシュされたページにナビゲートしたとき、インラインスクリプトと onload ハンドラは実行されません(ステップ 2 および 3)。ほとんどの場合、これらのスクリプトの効果が保存されているためです。

BFCache を無効にしてみる

開発を行う上で、JavaScriptや、JavaScriptの結果、JSONがキャッシュされてしまうのはかなり迷惑。
という事でBFCacheを無効にしてみます。
※ブラウジングのパフォーマンスに影響する可能性があるため、開発用のプロファイル等を作成し、そのプロファイルでのみBFCacheを無効にする事をお勧めします。
  1. about:configにアクセスする
  2. network.http.use-cacheと入力する
  3. 値をfalseに設定する
  4. Firefoxを再起動する
Firefox で BFCache によるキャッシュを無効化する方法

確認

google.co.jpにアクセスしてみる。
Firefox で BFCache によるキャッシュを無効化する方法
何回もページをリクエストしてみたが、Firefoxでキャッシュが行われないようになった。
関連記事

2013年1月25日金曜日

[SyntaxHighlighter] JavaScript用Brush

SyntaxHighlighterにデフォルトで入っているBrushに、予約オブジェクトを追加したBrushを作りました。
document.title="hoge";
window.open("http://example.com");
console.info("info message");
location.href="http://example.com";
以下で実際に確認することが可能です。
SyntaxHighlighter用タグ 変換/生成ツール - ログろいど

ダウンロード

共に、3.0.83専用です。
他のバージョンでの動作は未確認です。
非圧縮版(1.80KB)
https://sites.google.com/site/logroid/syntaxhighlighter/shBrushJScript
圧縮版(1.32KB)
https://sites.google.com/site/logroid/syntaxhighlighter/shBrushJScript.min.js
関連記事

[SyntaxHighlighter] jQuery用Brush (jQuery 1.9対応版)

jQuery 1.9対応のSyntaxHighlighter用Brushを作ってみましたので、公開します。
Brushのエイリアスは、jqjqueryです。
このBrushを使うと、jQuery APIが以下のようにハイライトされます。
$(document).ready(function(){
  // #hogeに#fugaを追加
  $('#hoge').append($('<div>').prop('id','fuga').attr('key','bar').text('baz'));
  $('input[type="radio"]:checked').click(
    function(){
      alert($(this).val());
      $('#hogehoge').addBack('.hoge').text($(this).val());
    }
  );
});
jQuery 1.9時点でdeprecated/removedとなったメソッドは色を分けています。
1.9で削除された.live().die()メソッドの例
$('.live').live('click', liveFunction);
$('.live').die('click', liveFunction);
また、deprecated/removedとなっていても、同名のメソッドがdeprecated/removedではない場合は、通常のjQuery APIとしてハイライトされます。
.toggle()メソッドの例
$('.target').toggle();
$('#target').toggle(function() {
  alert('First handler for .toggle() called.');
}, function() {
  alert('Second handler for .toggle() called.');
});
以下で実際に確認することが可能です。
SyntaxHighlighter用タグ 変換/生成ツール - ログろいど

jQuery 1.9でのjQuery APIに対応しています。
1.9以下のバージョンでも正常にハイライトされると思います。
ただし、前述のとおり、jQuery 1.9時点でdeprecated/removedとなったメソッドは色分けされます。

ダウンロード

共に、3.0.83専用です。
他のバージョンでの動作は未確認です。
非圧縮版(4.45KB)
https://sites.google.com/site/logroid/syntaxhighlighter/shBrushJQuery.js
圧縮版(3.30KB)
https://sites.google.com/site/logroid/syntaxhighlighter/shBrushJQuery.min.js
関連記事

2013年1月24日木曜日

jQuery 1.9に移行してハマったこと

jQuery 1.9へのアップグレードガイドはこちら (英語)
jQuery Core 1.9 Upgrade Guide | jQuery
http://stage.jquery.com/upgrade-guide/1.9/ そのうち(機械翻訳を駆使して)翻訳するかもしれません。

TypeError: $(...).live is not a function

jQuery 1.9では.live()が削除されている。同じように、.die()も削除されている。
.live()を、jQuery 1.9で使用しようとすると、以下のようなエラーが出力される。
TypeError: $(...).live is not a function
.live().on()に、.die().off()にそれぞれ置き換えられている。
以下のように書き直すことで、1.9へ移行する事ができる。
$('.live').live('click', liveFunction);
$('.live').die('click', liveFunction);
$(document).on('click', '.live', liveFunction);
$(document).off('click', '.live', liveFunction);

Error: Syntax error, unrecognized expression

$()にHTML文字列を渡して解析していたのだが、jQuery 1.9ではエラーになった。
jQuery 1.9からは、$()に渡す文字列の最初が<以外の場合はセレクタとしてみなされるようになったためだ。
HTML文字列が<で始まっていない場合、以下のようなエラーが出力される。
Error: Syntax error, unrecognized expression:
この場合、$.parseHTML()を用いることで解析することが出来る。
以下のように書き直すことで、1.9へ移行する事ができる。
var html_string_1="<div>hoge</div>",
html_string_2=" <div>HOGE<div>FUGA</div></div>";
console.dirxml($(html_string_1).get(0));
console.dirxml($(html_string_2).get(0));
var html_string_1="<div>hoge</div>",
html_string_2=" <div>HOGE<div>FUGA</div></div>";
console.dirxml($($.parseHTML(html_string_1)).get(0));
console.dirxml($($.parseHTML(html_string_2)).get(0));
あれ、思ったような結果にならない・・・
という事でこんな感じにしました。
var html_string_1="<div>hoge</div>",
html_string_2=" <div>HOGE<div>FUGA</div></div>";
console.dirxml($($.parseHTML(html_string_1)).get(0));
console.dirxml($($.parseHTML(html_string_2.trim())).get(0));
または
var html_string_1="<div>hoge</div>",
html_string_2=" <div>HOGE<div>FUGA</div></div>";
console.dirxml($($.parseHTML(html_string_1)).get(0));
console.dirxml($($.parseHTML(html_string_2.replace(/^[^<]+/,''))).get(0));
もうちょっと調べる必要があるな・・・
関連記事