Do You PHP はてな このページをアンテナに追加 RSSフィード Twitter

2014-07-25

[]HTC One(M7/801n)を修理に出した

愛用していたHTC One(M7)ですが、先日修理に出したのでログ的にまとめておきます。

やらかした経緯

ポーチに入れてエナメルバッグに入れといたんですが、気付いたらフロントガラス(ゴリラガラス)が割れていました。。。

f:id:shimooka:20140725091718j:image

クモの巣状ではなく、画面下1/3ぐらいのところに真横に1本。よく見てみると、何か固いものがえぐるように当たったっぽく、そこから割れたような感じでした。フロントガラスの保護フィルムはHTC J One用のものを買ったのですが、大きさが微妙に違っていたので、貼っていませんでした。裏のカメラ部分には貼ってあります。

で、しばらくはそのまま使ってたんですが、スワイプしていると指を切ってしまいそうな感じがしたのと、割れたガラスの反射でディスプレイが見づらくなったので、意を決して修理に出すことに。

とは言え、iFixitの評価で最低の”1”を付けられた端末。。。YouTube等で分解動画がいくつか上がっていますが、正直「こりゃぁ無傷で修理は無理だろ」というレベル。少々のことは覚悟の上です。どうせなら、HTC One(M7)界隈で有名な紫カメラ問題について、カメラモジュール交換もお願いしたいところ。

ちなみに、M7の紫カメラ問題はググればいろいろと出てきますが、簡単に言うと、搭載されているカメラモジュール自体の問題(排熱がうまくできない設計だったとかいろいろ言われてます)で、写真が紫(赤とか青もあるようです)がかってしまう現象のことです。

f:id:shimooka:20140326182404j:image

感覚的には、端末が冷えている状態ならあまり発生しないんですが、アプリや何やらを動作させて端末温度が上がってくるとひどくなる感じ。以下、拙作のアプリTemperature Layerでバッテリー温度を確認して約40℃の状態。

f:id:shimooka:20140326190646j:image

さすがに、このカメラにだけは愛想が尽きてました。。。:-(

見積り依頼〜依頼先決定

国内で修理依頼できそうなところがないかWebで検索し、いくつか見つけてそれぞれ無料見積りを取ることに。見積り条件としては、次のような感じで考えてました。

  • 国内
  • 予算は20K程度(それ以上ならM8買うわ)
  • できればカメラモジュールの交換も

依頼内容はこんな感じ。

フロントガラス(ゴリラガラス)にヒビが入ってしまったため、交換をお願いしたいのですが可能でしょうか?

ヒビは画面下1/3のあたりに真横に1本入っています(クモの巣状ではないです)。


別件で、M7の「紫カメラ問題」がありますが、カメラモジュールの交換は可能でしょうか?可能なようであれば、別見積でいただければありがたいです。

依頼してからのレスポンスって、初めてそのショップを利用するユーザーからすると結構重要なんじゃないですかね。こちとら結構切羽詰まっているので、修理可否や費用は早く知りたい状況であることが多い気がします。中には、全然レスポンスがないショップもあり、「Webサイトは綺麗なのに、残念感半端ない」というところもありました:-(


閑話休題

見積り依頼からのレスポンスが早かったMOUMANTAIさんからカメラモジュール交換OKとの連絡が。おおお。。。お値段もそんなに(思ったよりも)高くない。

HTC One M7 フロントパネル修理のお見積りを申し上げます。

HTC One M7 フロントパネルASSY シルバー パーツ代 10,800円

・技術料 4,320円

・返送代 600円

・合計 15,720円

以上となります。

パーツはお取り寄せとなりますので、発注より12日ほどで入荷をいたします。

パーツ入荷後1−3営業日で修理完了を予定しております。

なおカメラモジュールですが、HTC純正ROMの4.3以上でないと適合いたしません。

カスタムROMを導入されたり、4,3以下の場合は対策されたモジュールに交換をしてもカメラ起動いたしません。

カメラモジュールは3,000円 となります。フロントパネルと同時交換の場合は技術料は不要です。

その後、いろいろと質問などやりとりし、全体的に好印象だったMOUMANTAIさんにお願いすることに。Blogを見ると、いろいろな端末の修理をやっている様子を公開しているようですし。


発送準備〜発送

修理先が確定したので発送!。。。という訳にもいきません。

まずは、データのバックアップUSBマウントし、データを母艦にコピー。また、ROMをClockwokModリカバリを使ってバックアップ&母艦に退避。

次に、一番面倒だった代替機の準備。今回は、4年落ちのHTC Desire(X06HT)にをKitKat4.4.4化して使用しました。インストールしたROMはKitKANG v.0.11。A2SDを使っても容量が少ないので、必要最小限のアプリだけインストールしました。にしても、まさかDesireでKitKat4.4.4が動くとは思わなんだ。。。

最後に、発送する端末にROMクリーンインストール。今回はsdcard領域もフォーマットし、CyanogenMod11-20140701-NIGHTLYを新規インストールしました。

あとは、適当な大きさの箱とクッション材に端末を入れて発送。

カメラモジュールとCyanogenMod

で、ここで『HTC純正ROMの4.3以上でないと適合いたしません』と見積りにあるのに、なぜわざわざCyanogenModなのか?

まあ、ずっとCyanogenMod系を使ってるというのもあるんですが、いろいろと調べたところ、

  • カメラモジュールは現行で2種類(ST Microelectronics社のVD6869とOmnivision社のOV4688)がある
  • 交換後のカメラモジュールは、OV4688になるらしい
  • 2014/01/23以降のROMには、OV4688用のライブラリ郡が含まれるようになった
  • カメラモジュール交換済みのM7ユーザーがCyanogenMod11でカメラの動作報告をしている

という情報を見つけていたことで、わざわざSense系ROMに入れ替える必要もないか、という判断です。まあ、現時点で対応していなくても、結構大きな問題なので、いずれ対応されるだろうという思惑もありました。

無事帰還!

発送が2014/07/02、先方に到着したのが翌3日。それから20日。。。修理完了の連絡が23日。翌24日、無事戻ってきました!支払いは代引きで、修理費用・送料・代引き手数料込みで19,044円。当初の予算内に収まりました:-)

f:id:shimooka:20140724110522j:image

中も丁寧に梱包されてました。

f:id:shimooka:20140724110823j:image

早速取り出してみると、フロントパネル綺麗になってました。20日間ずっとDesireを使っていたので、久しぶりに触るとやっぱりでかい!

f:id:shimooka:20140724111409j:image

ちなみに、「全くの無傷」というわけにはやはりいかないようで、マイクロUSB端子の周りのカバーが若干欠けたり、下のフロントスピーカー部分が微妙に浮いてたりしますが、目立つわけでもなく、使用上特に問題になるようなこともなさそうです。

また、端末だけじゃなく、交換前のフロントパネルとカメラモジュールも送られてきました。こっちがフロントパネル。

f:id:shimooka:20140725091728j:image

カメラモジュールも。

f:id:shimooka:20140725091750j:image

あと、割ってしまった教訓から、保護フィルムを購入して貼り付け(汗)今度はちゃんとM7用のフィルムを用意しました。f:id:shimooka:20140725002512j:image

返送連絡が来てからAmazonで注文。こっちも良いタイミングで到着。フィルムのサイズも(当たり前だけど)バッチリです。

あとは、バックアップしたROMイメージやデータを書き戻し、ClockwokModリカバリからROMをリストア。その後、最新のNIGHTLYに更新して軽く動作確認。カメラも無事起動しました:-)

カメラモジュール交換の効果は?

早速会社のベランダから夜景を撮ってみました。HDRなしとありの2枚です。

f:id:shimooka:20140724213209j:image

f:id:shimooka:20140724213150j:image

うーん。全然問題ない。修理前だと、カメラを起動しっぱなしにすると温度が上がり、5分もしないうちに全体が紫っぽくなっていたんですが、交換後は10分経ってもそういう現象が全く見られません。

M7で唯一気に入らなかった点が改善されて、今まで使うのを躊躇していたカメラもようやく使い倒せそうです。

まとめ

もうホントね、『フロントパネルの保護フィルムはちゃんと貼りましょう』ということを声を大にして言いたい(笑)

いくらゴリラガラスでも、小さな傷が付いてしまえば、そこ一点に集中して力が加わった際に割れる可能性があるので、できるだけ傷がついていないうちに貼っといたほうが良い、ということを見に染みた感じです。みなさんも気をつけましょう:-)

最後に、今回お世話になったMOUMANTAIさん、ホントにありがとうございました!フロントパネルはもとより、カメラモジュールの交換ができたことは、個人的には結構大きかったです。

次回も何かあればお願いしようと思います(が、何もない事を祈るのが先決。。。:-p)

2014-05-28

[][]Temperature Layerをバージョンアップした

約1年間絶賛放置プレーだったAndroidアプリTemperature Layer」を久々にアップデートしました。最新は、ver.1.0.4です。

Temperature Layerとは?

Temperature Layerはバッテリー温度を表示するだけのシンプルなAndroidアプリケーションです。ステータスバー上のアイコンウィジェットとして温度を表示するではなく、画面上に透明なレイヤをかぶせて表示しますので、HOME画面や他のアプリの邪魔になりません。

Temperature LayerはGoogle Playから入手できます。

旧バージョンやβ版も含めたAPKファイルのアーカイブこちらからどうぞ。

また、ソースコード(eclipseプロジェクト形式)はGitHubで公開しています。ライセンスApache License, Version 2.0です。

特徴

色付きの部分は、今回のアップデートで追加した機能です。

  • Android2.0以降に対応
  • バッテリー温度を画面上の任意の位置に表示(ステータスバーの上も可能)
  • 端末起動時の自動起動
  • 通知領域に温度通知を表示(切り替え可能)
  • ステータスバー上のアイコンの非表示 (Android 4.2以降対応)
  • 単位は摂氏(°C)、華氏(°F)から選択
  • テキストのフォント、サイズ、色(透明度も含む)をカスタマイズ可能
  • 高温時のアラート機能(通知音、バイブレーション)
  • メッセージは英語と日本語
  • 無料です!

画面キャプチャ

f:id:shimooka:20140528133324p:image (大きいサイズ)

その他の画面キャプチャはこちらからどうぞ

表示位置の変更について

  • 設定メニューの表示位置をタップすると、編集モードになります
  • 編集モードでは、温度表示は常に赤色で表示されます。
  • スワイプすると表示位置を移動できます
  • 編集モードの終了は、二本指でタッチもしくはダブルタップします

表示位置の変更時の制限

ステータスバーに移動させると下に隠れてしまいますがこれは仕様です。編集モード終了後は正しく表示されます。

具体的には、以下の様な感じです。

  • 通常モードでの温度表示にはWindowManager.LayoutParams.TYPE_SYSTEM_OVERLAYを使用。これならステータスバーの上にも表示可能だが、MotionEvent(MotionEvent.ACTION_MOVEなど)を受け取れない。
  • やむを得ず、編集モードでの温度表示にはWindowManager.LayoutParams.TYPE_SYSTEM_ALERTを使用(MotionEventを受け取れる)。ただし、ステータスバーの上には表示できない

その他制限

AndroidOSの[設定]→[アプリ]メニューで、Temperature Layerの「通知を表示」のチェックを外している場合、ステータスバーへの通知や表示位置編集時の説明トーストは表示されません。

2014-05-27

[][]console.log()でFirebugのコンソールに出力されない

環境

  • Firefox29.0.1
  • Firebug1.12.8

現象

よくある

console.log(data);

というJavaScriptを実行しても、Firebugのコンソールに出力されない。Firefox28(29?)までは問題なかった。また、Firefox29から復活したWeb開発ツールのコンソールには正しく出力される。

原因

対処

Greasemonkeyの「ユーザースクリプトの管理」メニューから、「ユーザースクリプトを実行しないページ」に当該サイトを追加したところ、Firebugのコンソールに正しく出力されるようになった。

おまけ

2014-05-08

[][]CyanogenMod11-nightlyが更新できない

現在HTC One(m7ul)にCyanogenMod11-nightlyを入れて遊んでいるんですが、今月(2014年5月)からCMUpdaterでのROM更新でエラーになるようになりました。一応解決したのでまとめときます。以下、自己責任で;-)

環境

  • HTC One (m7ul)
  • CWM(ClockworkMod) 6.0.4.6-touch(m7ul)

現象

CyanogenMod11-nightlyをOTA、もしくは、別途ダウンロード後、/sdcardにコピーしてCWMリカバリから更新しようとすると、インストール開始直後にstatus 0 installation abortedとメッセージが表示され更新できない。

原因

CyanogenModのブログフォーラムにもアナウンスが出ていますが、

Beginning with nightly 20140501, an updated recovery that has kernel support for by-name partitions is required to install/update CyanogenMod on certain devices.

The following devices are affected:

  • m7 – HTC One [GSM]
  • m7spr – HTC One [Sprint]
  • m7vzw – HTC One [Verizon]

PSA: HTC Devices recovery updates | CyanogenMod

ということで、どうやらCWMを新しいカーネルに対応したバージョンに更新する必要があるようです。

対応

アナウンスに「Wikiを参照してね」と書かれているので確認してみると、CWMの新バージョンへのリンクがあります。今回はHTC One(無印)向けの6.0.4.8-touchをダウンロードしました。

イメージファイルをダウンロード後、端末をfastbootモードで起動しUSBに接続。fastbootコマンドからCWMを起動して問題ないか確認します。

$ fastboot boot recovery-clockwork-touch-6.0.4.8-m7.img
     :
$ adb devices
     : (接続した端末が認識されているか確認しておく)
$ 

問題がなければ端末をfastbootモードで再起動し、CWMをflashします。

$ fastboot flash recovery recovery-clockwork-touch-6.0.4.8-m7.img
     :
$ 

あとは、端末をrecoveryモードで再起動し、CyanogenModのROMインストールしてみます。CMUpdaterでダウンロード済みであれば、

/sdcard/0/cmupdater

の直下にzipファイルがあるはずです。

2014-04-22

[][]PHPからCloudera Impalaに繋いでみた

最近ビッグデータ()系のサーバに対してあれこれやってるんですが、ひょんなことから調べる必要が出てきたのでざっくりまとめてみました。

間違ってる所があれば、指摘をお願いします;-)

基本的な環境

  • CentOS 6.2(x86_64)
  • PHP 5.5.11
  • CDH 4.6+Cloudera Impala 1.2.4(別途構築済み)

CDHとは

CDH(Cloudera's Distribution Including Apache Hadoop)は、Cloudera社から提供されているオープンソースApache Hadoopディストリビューションの1つで、Apache HadoopApache HBase、Apache Hive、Apache Pigなどのパッケージが含まれています。

とりあえず、CDHについては以下のページをざっと読むと良いかと。

今回テストでCDH 4.6を使いましたが、最近CDH5がリリースされたようです。

また、Cloudera社のサイトからVMイメージ(Cloudera QuickStart VM)もダウンロードできます。

Cloudera Impalaとは

Cloudera Impalaは、CDHと同様、Cloudera社から提供されているHiveの上位互換のSQLが利用できる分散クエリエンジンです。

Impalaについては以下のページをざっと読むと良いかと。

CDH 5からCDHに組み込まれるようになったようです。

PHPからの接続

PHPからCloudera Impalaへの接続方法は、以下の2通りがあるようです。

ODBC経由でCloudera Impalaに接続する

Cloudera社からCloudera Impala用のODBCドライバダウンロードできますが、それだけだとPHPから利用できないので、今回はドライバマネージャとしてiODBCを使い、Cloudera ODBC Driver 2.5 for Impalaで接続してみました。

1. iODBCのインストール

ダウンロード後、いつも通りのconfigure/make/make installでOKです。

$ wget http://downloads.sourceforge.net/project/iodbc/iodbc/3.52.9/libiodbc-3.52.9.tar.gz
$ sudo tar zxf libiodbc-3.52.9.tar.gz
$ cd libiodbc-3.52.9/
$ configure
$ make
$ sudo make install
$ 
2. Cloudera ODBC Driver 2.5 for Impalaのインストール

Cloudera ODBC Driver 2.5 for Impalaの方ですが、rpm形式で提供されているので、rpmコマンドでインストールします。cyrus-sasl系やopenssl系など依存関係にあるパッケージは別途yumなどでインストールしておいてください。

$ sudo rpm -ivh ClouderaImpalaODBC-2.5.13.1013-1.el6.x86_64.rpm
$ 

また、ODBC接続に必要なiniファイルもrpmパッケージに含まれていますので、確認しておきます。

$ ls /opt/cloudera/impalaodbc/Setup/
cloudera.impalaodbc.ini  odbc.ini  odbcinst.ini
$ 
3. ODBCの設定

基本的な流れにはインストールガイド(pdf)にある通りです。

今回はテスト用ディレクトリを作ってそこにiniファイルを配置してみます。

$ mkdir test
$ cd test/
$ cp /opt/cloudera/impalaodbc/Setup/*.ini .
$

デフォルトだと、カレントディレクトリにある各iniファイルを読みに行かないので、環境変数を設定しておきます。iniファイルの検索順序の詳細については、インストールガイド(pdf)を参照してください(p.10の終わり頃から)。

$ export ODBCINI=`pwd`/odbc.ini # フルパスの必要あり
$ export ODBCSYSINI=`pwd`/
$ export SIMBAINI=`pwd`/cloudera.impalaodbc.ini # フルパスの必要あり
$

続いて、接続用のDSNを定義します。コピーしたodbc.iniにも定義されていますので、それを使っても良いと思います。最低限、

  • HOST(Cloudera Impalaが稼働しているサーバIPアドレスもしくはホスト名)
  • PORT(ODBC接続の場合は21050)
  • Driver(libclouderaimpalaodbc64.soへのフルパス)

を定義しておけばOKです。まあ、接続時に指定してもいいんですけどね。。。今回は以下の内容をodbc.iniの最後に追加しました。

[Impala]
HOST=localhost
PORT=21050
Driver=/opt/cloudera/impalaodbc/lib/64/libclouderaimpalaodbc64.so
4. LD_LIBRARY_PATHの設定

ドライバマネージャであるiODBCとODBCドライバであるCloudera ODBC Driver 2.5 for Impalaの各ライブラリへのパスをLD_LIBRARY_PATHに設定します。

$ export LD_LIBRARY_PATH=/usr/local/lib:/opt/cloudera/impalaodbc/lib/64/
$ 
5. PHPスクリプトを作成

基本的にはODBC関数を使ったコードであれば良いはずです。今回は次のようなテーブル一覧を出力するスクリプト(test.php)を作ってみました。

<?php
$connection = odbc_connect("DSN=Impala;", '', '');
$query = "show tables";
$rs = odbc_exec($connection, $query);
while ($row = odbc_fetch_array($rs)) {
    echo (isset($row['name']) ? $row['name'] : null) . PHP_EOL;
}
odbc_free_result($rs);
odbc_close($connection);

PDO ODBCの場合は次のような感じで。

<?php
try {
    $dbh = new PDO('odbc:DSN=Impala;', '', '');
    foreach($dbh->query('show tables') as $row) {
        echo (isset($row['name']) ? $row['name'] : null) . PHP_EOL;
    }
    $dbh = null;
} catch (PDOException $e) {
    die($e->getMessage());
}
6. 実行してみる

PHPodbc拡張が組み込まれていることを確認して実行します。今回はconfigure時に

--with-iodbc=shared --with-pdo-odbc=shared,iODBC

を付けてbuildしたPHPを使いました。これで作成したテーブル一覧が表示されればOKです。

$ /path/to/php -ddate.timezone=Asia/Tokyo -dextension=/path/to/odbc.so test.php
  :
$

PDO ODBCの場合。

$ /path/to/php -ddate.timezone=Asia/Tokyo -dextension=/path/to/pdo.so -dextension=/path/to/pdo_odbc.so test.php
  :
$

あとは、SELECT文をいろいろ試してみましょう:-)

ThriftでCloudera Impalaに接続する

先日のHBaseへの接続の際にも使用したThriftですが、Cloudera Impalaにも接続できます。ポート番号は21000です。

GitHubにいくつかライブラリが公開されているようなので、今回は次の2種類を試してみました。

a. PHP+php_impala_pharでCloudera Impalaに接続する

まずは、コード一式をダウンロードして展開します。

$ wget https://github.com/rmcfrazier/php_impala_phar/archive/master.zip -O php_impara_phar-master.zip
$ unzip php_impara_phar-master.zip
$ cd php_impara_phar-master/
$ 

直下にtest.phpがありますので、ホスト名の部分('<impala_host>')を適宜修正して実行します。以下の様な内容が出力されればOKです。

$ perl -i -p -s -e "s/<impala_host>/localhost/g" test.php
$ /path/to/php -ddate.timezone=Asia/Tokyo test.php
object(Results)#10 (5) {
  ["ready"]=>
  bool(true)
  ["columns"]=>
  array(1) {
    [0]=>
    string(6) "string"
  }
  ["data"]=>
     :
  }
  ["start_row"]=>
  int(0)
  ["has_more"]=>
  bool(false)
}
$ 
b. PHPphp-impalaでCloudera Impalaに接続する

php_impara_pharと同様、コード一式をダウンロードして展開します。

$ cd ../
$ wget https://github.com/RJMetrics/php-impala/archive/master.zip -O php-impala-master.zip
$ unzip php-impala-master.zip
$ cd php-impala-master/
$ 

やはり直下にtest.phpがありますので、ホスト名の部分(127.0.0.1)とポート番号(50000)を適宜修正して実行します。同様に、以下の様な内容が出力されればOKです。なお、返されるオブジェクト名前空間が、php_impara_pharとは異なることに注意です。

$ perl -i -p -s -e "s/50000/21000/g" test.php
$ /path/to/php -ddate.timezone=Asia/Tokyo test.php
object(Beeswax\Results)#10 (5) {
  ["ready"]=>
  bool(true)
  ["columns"]=>
  array(1) {
    [0]=>
    string(6) "string"
  }
  ["data"]=>
     :
  }
  ["start_row"]=>
  int(0)
  ["has_more"]=>
  bool(false)
}
$ 

thriftファイルからPHPコードを出力したい

php-impalaにはthriftファイルが含まれています(zipファイルを展開した直下にthriftディレクトリ)ので、Thriftに食わせてPHPコードを生成することができます。手順はPHP+Thrift+HBaseを試してみた - Do You PHP はてなにもありますが、以下の様な感じになります。

$ for fn in php-impala-master/thrift/*.thrift; do thrift --gen php $fn; done
$ 

直下にgen-phpディレクトリが作成されますので、中身を確認します。

まとめ

またまた「繋げられましたよー」で終わっちゃいます。。。(汗)

Cloudera ImpalaはUPDATEやDELETEなどデータを更新する機能はないので使いどころが問題になってくると思いますが、HBaseと異なり、SQLっぽいクエリ(ほぼSQL)を投げられますのでHBaseよりは親近感がわきますね(笑)。また、100万件レベルの検索でもかなりパフォーマンスが良いです(サーバ構成等に依存するとは思いますが)。データがもうちょっと溜まってきた時(億単位以上)にどうなるかは見てみたいですね。

PHPからも意外と手軽に接続できますし、SQLを投げられる=ORM使ってモデルクラスやアクセスクラスなどの自動生成も可能じゃないかと思います。

2014-02-17

[]svn: E155036: Please see the 'svn upgrade' command

今頃引っかかりました。。。

svnの操作で

$ svn update
svn: E155036: Please see the 'svn upgrade' command
svn: E155036: Working copy '/path/to/webapp' is too old (format 10, created by Subversion 1.6)
$

となる場合、ワーキングコピーをアップグレードする必要があるようです。

実際のアップグレード手順は以下のような感じ。

$ svn update
svn: E155036: Please see the 'svn upgrade' command
svn: E155036: Working copy '/path/to/webapp' is too old (format 10, created by Subversion 1.6)
$
$ svn upgrade
svn: E155019: Can't upgrade '/path/to/webapp' as it is not a pre-1.7 working copy root, the root is '/path/to'
$
$ cd /path/to
$ svn upgrade
   :
$

Subversionリポジトリを作成したsvnバージョンとsvnクライアントのバージョンが不一致の場合に起こるエラーのようです。今回は

という組み合わせでエラーになりました。

2014-02-12

[]Google HangoutsでSoftBankMMSを送受信する

何かと面倒くさいAndroidSoftBank MMSですが、Google HangoutsでもMMSを送受信できたのでメモ代わりに書いておきます。

あくまで検証なので動作保証はありません。また、何をやっているか分からない方はやめといた方が良いです。ご自分で試される際は自己責任で:-p

検証環境

概要

  • SoftBankMMS網は、クライアントアプリのUser-Agentでアクセス制限をしている(らしい)
  • Google HangoutsのUser-Agentは当然上記にマッチしないので接続自体不可
  • 調べてみると、Google HangoutsのUser-Agentは、Android API Level 19から導入されたandroid.telephony.TelephonyManager#getMmsUserAgentを使っているっぽい
  • android.telephony.TelephonyManager#getMmsUserAgent自体はリソースからUser-Agent文字列を取得しているだけ
  • リソースはframework-res.apkに含まれているので、apktoolを使って一度バラしてUser-Agentなどを書き直し、再度framework-res.apkをbuildしてオリジナルと差し替える

手順

端末をリカバリモードで再起動し、USB接続後cygwinから以下の様な感じで。

$ export PATH=/path/to/jre7/bin:/path/to/android-sdk-windows/build-tools/19.0.0/:$PATH
$ 
$ adb shell mount -a
$ 
$ # fetch framework-res.apk
$ adb pull /system/framework/framework-res.apk
$ 
$ # backup
$ \cp -pf framework-res.apk framework-res.apk_
$ java -jar apktool_2.0.0b9.jar d -advance framework-res.apk 
$ 
$ # modify user-agent, uaprofile in resources
$ cp -p framework-res/res/values/strings.xml strings.org.xml
$ perl -i -p -s -e 's#http://www.google.com/oha/rdf/ua-profile-kila.xml#http://www.apple.com/mms/uaprof.rdf#g' framework-res/res/values/strings.xml
$ perl -i -p -s -e 's#<string name="config_mms_user_agent">CyanogenMod</string>#<string name="config_mms_user_agent">iPhoneOS/3.0 (7A341)</string>#g' framework-res/res/values/strings.xml
$ find . -iname \*.bak -delete
$ 
$ # install as 127.apk
$ java -jar apktool_2.0.0b9.jar if framework-res.apk_
$ 
$ # build framework-res.apk
$ java -jar apktool_2.0.0b9.jar b -advance framework-res 
$ 
$ # update resources.arsc only
$ cp -p framework-res/build/apk/resources.arsc .
$ 7z u -tzip -mx0 framework-res.apk resources.arsc
$ 
$ # push framework-res.apk
$ adb push framework-res.apk /system/framework/framework-res.apk
$ adb shell chmod 644 /system/framework/framework-res.apk
$ 

あとは端末を再起動し、HangoutsからMMSを送受信してみる。logcatで以下のような感じになっていれば多分大丈夫。

$ adb logcat | grep MmsConfig
V/MmsConfig( 3219): mnc/mcc: 44020
V/MmsConfig( 3219): tag: bool value: enabledMMS - true
V/MmsConfig( 3219): tag: int value: maxMessageSize - 307200
V/MmsConfig( 3219): tag: int value: maxImageHeight - 1944
V/MmsConfig( 3219): tag: int value: maxImageWidth - 2592
V/MmsConfig( 3219): tag: int value: defaultSMSMessagesPerThread - 10000
V/MmsConfig( 3219): tag: int value: defaultMMSMessagesPerThread - 1000
V/MmsConfig( 3219): tag: int value: minMessageCountPerThread - 10
V/MmsConfig( 3219): tag: int value: maxMessageCountPerThread - 5000
V/MmsConfig( 3219): tag: string value: uaProfUrl - http://www.apple.com/mms/uaprof.rdf
V/MmsConfig( 3219): tag: int value: recipientLimit - -1
V/MmsConfig( 3219): tag: bool value: enableMultipartSMS - true
V/MmsConfig( 3219): tag: bool value: enableSplitSMS - false
V/MmsConfig( 3219): tag: int value: smsToMmsTextThreshold - -1
V/MmsConfig( 3219): tag: bool value: enableSlideDuration - true
V/MmsConfig( 3219): tag: int value: maxMessageTextSize - -1
V/MmsConfig( 3219): tag: string value: userAgent - iPhoneOS/3.0 (7A341)||<
            :
$ 

その他

  • TelephonyManagerが返す値そのものを変更しているので、どこに影響が出るかは未検証;-)
  • 仕組み上、Hangoutsのstrings.xmlを書き直しても良いと思うんだけど、OS起動時のapkチェックで弾かれます。