tetsu31415.log

androidなどのことを書き綴っていこうと思います。

auLTEのCellIDを収集してバンドとの関係性を調べてみた

はじめに

金沢駅から大阪駅までローカル線の旅をしてきたのでauLTEのCell IDを集めてきました。

Cell IDは基地局のセクターやバンド(周波数帯)ごとにユニークに割り当てられているようなので接続中のCell IDとバンドを紐付けすればバンドを確認できない端末でもCell IDを取得して間接的に接続しているバンドがわかるのではないかと思ったので収集してみました。

※GALAXY、一部のLG機種、iPhoneなどはメーカーが独自に実装したメニューを開くことで接続中のバンドを確認することができます。

収集方法

Cell ID取得方法

Android4.2から追加されたCellIdentityLte#getCi()で取得します。
AndroidManifestに以下の2つのパーミッションを追加して、
Activityを継承したクラス内にこんな感じで書くと取得出来ます。(適当ですいません)

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
private TelephonyManager telephonyManager;

@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
}

@Override
protected void onResume() {
    super.onResume();
    telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CELL_INFO);
}

@Override
protected void onPause() {
    super.onPause();
    telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}

PhoneStateListener phoneStateListener = new PhoneStateListener(){

    public void onCellInfoChanged(java.util.List<android.telephony.CellInfo> cellInfoList) {
        for (CellInfo cellInfo : cellInfoList) {
            if (cellInfo instanceof CellInfoLte) {
                CellInfoLte cellInfoLte = (CellInfoLte)cellInfo;
                CellIdentityLte cellIdentityLte= cellInfoLte.getCellIdentity();
                int ci = cellIdentityLte.getCi();
                Log.d("TestApp", "Cell ID is "+ci);
            }
        }
    };
};

また、CellIdentityLte#getCi()はリファレンスで次のように書いてあります。

public int getCi ()

Added in API level 17
Returns
28-bit Cell Identity, Integer.MAX_VALUE if unknown

というわけで28bitのCell IDが取得できるようです。

バンド取得方法

SCL22でダイアルから*#0011#を使ってサービスモードを起動してバンドを確認します。
SCL22はBand 1(2.1GHz), Band 11(1.5GHz), Band 18(800MHz)の3バンドに対応しています。
Band 41(2.5GHz)は対応端末を持っていなかったので収集できませんでした。

収集結果

250件ほどのCell IDとBandの組み合わせを収集できました。
Cell IDを昇順でソートしたものを一部を抜粋するとこのような感じです。
※ 左からCell IDの10進数、Cell IDの16進数、バンドとなっています。
f:id:tetsu31415:20141005181425p:plain

このようにバンドごとにCell IDが固まっているように見えます。

また、移動通信方法及び無線基地局
【0011】にはこう書かれています。

なお、E-CGIの下位28ビットは、Cell ID(図10に示す情報要素「Cell Identity」に設定されるCell Identityに対応)によって構成されており、ハンドオーバ先候補無線基地局が、無線基地局HeNBである場合、Cell IDは、Home eNB IDによって構成されており、ハンドオーバ先候補無線基地局が、無線基地局eNBである場合、Cell IDは、20ビット長のMacro eNB IDと8ビットの無線基地局HeNB配下のセルの識別情報とによって構成されている。

この取得した28bitは20bitと8bitに分けられるみたいです。
実際に収集したCell IDの下位8bitはすべて0x00から0x03の範囲に収まっていました。
この下位8bitはセクターごとに変わると考えて良さそうです。

北陸エリア編

金沢市街、金沢駅から敦賀駅にかけての区間のCell IDは0x3000000台になっていて
Cell IDを昇順でソートするとBand18,Band1,Band11の順に並びます。
北陸エリアで収集したCell IDのバンドごとの最小値、最大値は次のようになりました。
f:id:tetsu31415:20141005211623p:plain

この結果から0x3000000台がBand18, 0x3300000台がBand1,0x3400000台,0x3500000台がBand11というように上位8bitで判別できるかなという仮説を立てましたが関西エリアに入って調べるとそんなこともありませんでした…

関西エリア編

敦賀駅で乗換えし、滋賀県に入ってからはCell IDが0x5000000台になりました。
こちらも北陸エリアと同じようにCell IDを昇順でソートするとBand18,Band1,Band11の順に並んでいます。
関西エリアで収集したCell IDのバンドごとの最小値、最大値は次のようになりました。
f:id:tetsu31415:20141005212907p:plain

まとめ

今回収集したauLTEのCell IDについてまとめてみると…

  • Cell IDを収集して昇順でソートするとBand 18,Band 1,Band 11の順にバンドごとに固まって割り振られている。
  • Cell IDの各バンドの正確な区切りはどこかわからない。
  • エリアが変わるとCell IDが大きく変わる。

という感じになります。

今回集めたCell IDの各バンドごとの最小値と最大値の範囲内はそのバンドと判別しても良さそうな感じがします。

これを解明していくためには地道に広い範囲のCell IDを収集していくしかない気がします。

おまけ

今回の収集結果をもとにバンドを確認するサンプルを作るとこんな感じになりました。

Android4.4でGoogle日本語入力の辞書をインポートする方法

はじめに

AndroidIMEGoogle日本語入力」がAndroid4.4(KitKat)で辞書インポートができないという話を聞いたので少し調べてみました。

※長々と説明していますが時間がない方はベージの最後の方にあるアプリを使えばAndroid4.4でも辞書インポートが楽にできるのでぜひお使いください。

環境

検証

外部ストレージ直下に辞書ファイルを配置します。
※ わかりづらいですがここでいう外部ストレージはSDカードとは限りません。
最近の端末では内部ストレージ内にあることが多いです。
大抵の場合 /sdcard でアクセスできると思います(適当)

ESファイルエクスプローラで辞書データを開きます。
f:id:tetsu31415:20140719224333p:plain
するとこのように「ファイルを読み込めません。」とトーストが表示されます。

確かに辞書のインポートができません。

原因

この原因はKitKatで外部ストレージの仕様が変更されたことにあります。
以前は外部ストレージの読み込みには権限が不要でしたが、
KitKatで「READ_EXTERNAL_STORAGE」というパーミッションが正式対応され、
この権限がないと外部ストレージのデータを読み込むことはできなくました。
その代わりに外部ストレージの一部領域が権限なしで読み書きできるようになりました。

外部ストレージの仕様の変化は以下のとおりです。

  • Android4.3(Jelly Bean)まで

読み込みには権限が不要
書き込みには「WRITE_EXTERNAL_STORAGE」が必要

読み込みには「READ_EXTERNAL_STORAGE」が必要
書き込みには「WRITE_EXTERNAL_STORAGE」が必要
ただし外部ストレージの以下の領域は権限なしで読み書きが可能

[外部ストレージ]/Android/data/[パッケージ名]/ 

※「WRITE_EXTERNAL_STORAGE」は「READ_EXTERNAL_STORAGE」を内包しているので読み込みも可能です。

ここでGoogle日本語入力の権限を見てみます。
f:id:tetsu31415:20140719231842p:plain
Google日本語入力の権限には「READ_EXTERNAL_STORAGE」や「WRITE_EXTERNAL_STORAGE」は含まれていません。
よってAndroid4.4のGoogle日本語入力では外部ストレージの読み込みはできません。

解決策

先ほど説明した外部ストレージにあるアプリが権限なしで読み書き可能な領域にインポートしたい辞書データを置くとアプリがデータを読み込むことができます。

実際に試してみます。
以下の場所に辞書データを置きます。(zipでも可)

[外部ストレージ]/Android/data/com.google.android.inputmethod.japanese/[辞書データ].txt

そのファイルをESファイルエクスプローラーから辞書データを開きます。
f:id:tetsu31415:20140719232804p:plain
すると、ファイルが読み込まれ、インポート先の辞書を選択するダイアログが表示され…
f:id:tetsu31415:20140719232954p:plain
辞書データが読み込まれました!!
(内容は適当です)

これでKitKatでもGoogle日本語入力の辞書インポートができました。

ツール化

ここで終わっても良かったのですが辞書をインポートするたびここにデータを置くのは面倒だなと思ったのでアプリ化してみました。
このツールでは選択されたデータを先ほど説明したGoogle日本語入力が読み書きできる領域にコピーしそれを開くということをやっています。

いずれGoogle日本語入力のほうでこの問題は解決されると思うので野良アプリにしました。
しばらく改善されない感じなので結局Playストアにアップロードしました。
ご自由にお使いください。

DicImportTool.apk
(ICS以降の端末に対応しています)

使い方は「ファイルを選択」からファイルを選択し、「辞書データを読み込み」を押すだけです。
f:id:tetsu31415:20140719235101p:plain

適当に作ったのでバグが有る可能性が高いです。
何かあれば@tetsu31415までお願いします。