UbuntuでKVMの作業メモ
環境
- ThinkPad X200s
- Ubuntu 11.04
やったこと
# kvmインストール $ sudo apt-get install kvm $ sudo apt-get install virt-manager # Ubuntu再起動が必要らしい(必要だったか確認してない) # /dev/kvm がkvmグループになっていることを確認 $ ls -l /dev/kvm crw-rw----+ 1 root kvm 10, 232 Jan 29 19:33 /dev/kvm # KVMを使うユーザをkvmグループに追加 $ sudo adduser speg03 kvm ユーザ `speg03' をグループ `kvm' に追加しています... ユーザ speg03 をグループ kvm に追加 終了。 # KVMが有効かどうか確認 $ lsmod | grep kvm kvm_intel 56851 0 kvm 367707 1 kvm_intel # 実行してみる $ kvm -monitor stdio kvm: pci_add_option_rom: failed to find romfile "pxe-rtl8139.bin" QEMU 0.14.0 monitor - type 'help' for more information (qemu) info kvm kvm support: enabled (qemu) quit # libvirtdデーモンの起動確認 $ pgrep -lf libvirtd 2920 /usr/sbin/libvirtd -d # GUIで仮想マシンを作る $ sudo virt-manager # CUIで仮想マシンを作る $ sudo virt-install --connect qemu:///system \ --name testvm1 \ --ram 512 \ --disk path=/media/ext/kvm/testvm1/testvm.img,size=2 \ --network network=default,model=virtio \ --vnc \ --cdrom /media/ext/isos/CentOS-6.0-x86_64-minimal.iso # こんなん出た WARNING Unable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package. # 言われるとおりにインストールする $ sudo apt-get install virt-viewer
TextViewのテキストサイズ指定
TextViewなどのテキストサイズをJavaのコードから動的に変更しようとして、はまりそうだったのでメモ。
ちなみに今回の実行環境はAndroid 2.2 (API Level 8)を使った。この環境だとデフォルトで以下のようなAndroidManifest.xmlの設定が有効になっていることになる。
<supports-screens android:anyDensity="true" />
Android 1.6 (API Level 4)よりも低い場合はanyDensityのデフォルト値がfalseになる。anyDensityの値がfalseの場合はまた話が変わってくるので注意が必要。
このあたりの話は以下を参考に。
テキストサイズの定義と取得方法
このページのDimensionの項を見るとテキストサイズの定義とXMLファイルでの取得方法、Javaコードでの取得方法がわかる。以下のような感じ。
テキストサイズの定義
<resources> <dimen name="font_size">16sp</dimen> <resources>
XMLファイルでのテキストサイズの取得方法
@dimen/font_size
Javaコードでのテキストサイズの取得方法
Resources res = getResources();
float fontSize = res.getDimension(R.id.font_size);
試してみる
XMLファイルでの指定とJavaコードでの指定のそれぞれについて2種類のテキストサイズを指定してみる。
res/values/dimens.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="font_size_small">16sp</dimen> <dimen name="font_size_large">32sp</dimen> </resources>
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 小さいテキスト(XML指定) --> <TextView android:id="@+id/smallTextXml" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/font_size_small" android:text="Small Text (XML)" /> <!-- 小さいテキスト(コード指定) --> <TextView android:id="@+id/smallTextCode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Small Text (Code)" /> <!-- 大きいテキスト(XML指定) --> <TextView android:id="@+id/largeTextXml" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/font_size_large" android:text="Large Text (XML)" /> <!-- 大きいテキスト(コード指定) --> <TextView android:id="@+id/largeTextCode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Large Text (Code)" /> </LinearLayout>
XML指定と書いてあるTextViewはtextSize属性に先ほど定義したテキストサイズを指定している。コード指定と書いてあるTextViewはJavaコードからテキストサイズを指定するためここでは指定していない。
TextSizeSampleActivity.java (間違ったコード)
import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; import android.widget.TextView; public class TextSizeSampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Resources res = getResources(); float fontSizeSmall = res.getDimension(R.dimen.font_size_small); float fontSizeLarge = res.getDimension(R.dimen.font_size_large); // 小さいテキストのテキストサイズを指定 TextView smallTextCode = (TextView) findViewById(R.id.smallTextCode); smallTextCode.setTextSize(fontSizeSmall); // 大きいテキストのテキストサイズを指定 TextView largeTextCode = (TextView) findViewById(R.id.largeTextCode); largeTextCode.setTextSize(fontSizeLarge); } }
先ほどの例にしたがってテキストサイズを取得。setTextSizeメソッドでテキストサイズを指定している。
実行結果(間違ったコード)
修正
正しいコードは以下のようになる。
TextSizeSampleActivity.java (正しいコード)
import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; import android.util.TypedValue; import android.widget.TextView; public class TextSizeSampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Resources res = getResources(); float fontSizeSmall = res.getDimension(R.dimen.font_size_small); float fontSizeLarge = res.getDimension(R.dimen.font_size_large); // 小さいテキストのテキストサイズを設定 TextView smallTextCode = (TextView) findViewById(R.id.smallTextCode); // ※ 設定値の単位を指定するようにした smallTextCode.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSizeSmall); // 大きいテキストのテキストサイズを設定 TextView largeTextCode = (TextView) findViewById(R.id.largeTextCode); // ※ 設定値の単位を指定するようにした largeTextCode.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSizeLarge); } }
実行結果(正しいコード)
何が問題だったか
- TextView | Android Developers
- Resources | Android Developers
- platform_frameworks_base/Resources.java at master · aosp-mirror/platform_frameworks_base · GitHub
要するに
Resources res = getResources();
float fontSize = res.getDimension(R.id.font_size);
このコードで取得できるテキストサイズはpx単位なのに
TextView#setTextSize(float)
これで指定するテキストサイズがsp(scaled pixel)単位だったのが問題だった。
sp単位は160dpiを1として実際の解像度に合わせた比率で実際のpx単位を求める。なので、sp単位の値を受け取るsetTextSizeメソッドが計算済みのpx単位の値を受け取ったので大きさがずれてしまっていた。
HVGAの場合で問題がなかったのはHVGAの仮想デバイスを作成するときデフォルトで解像度が160dpiになっているためだった。
参考
Gmailの受信通知インテントを受け取ってみた
Android端末でGmailのメール受信通知を受け取ってアレコレしたかったので調べたよ。
メール受信時のインテント
端末をPCにつないでLogCatで眺めるだけ。以下のようなインテントを見つけられる。
06-12 20:51:00.550: INFO/Gmail(10262): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://gmail-ls/unread/^iim (has extras) } 06-12 20:51:00.589: INFO/Gmail(10262): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://gmail-ls/unread/^i (has extras) }
PROVIDER_CHANGEDはandroid.content.Intentのリファレンスによるとブロードキャストなのでブロードキャストレシーバを作って受け取ってみた。
メール受信時のブロードキャストレシーバ
以下のような感じ。extrasの中身も見てみる。
AndroidManifest.xmlの一部
<receiver android:name=".Receiver" android:label="receiver"> <intent-filter> <action android:name="android.intent.action.PROVIDER_CHANGED" /> <data android:scheme="content" android:host="gmail-ls" android:path="/unread/^i" /> </intent-filter> </receiver>
Receiver.java
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class Receiver extends BroadcastReceiver { private static final String TAG = "Receiver"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "You've Got Mail!!"); for (String key : intent.getExtras().keySet()) { Log.d(TAG, key + ": " + intent.getExtras().get(key)); } } }
実行結果
こんな感じ。
06-12 20:51:00.550: INFO/Gmail(10262): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://gmail-ls/unread/^iim (has extras) } 06-12 20:51:00.589: INFO/Gmail(10262): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://gmail-ls/unread/^i (has extras) } 06-12 20:51:00.601: DEBUG/Receiver(10248): You've Got Mail!! 06-12 20:51:00.601: DEBUG/Receiver(10248): count: 1 06-12 20:51:00.601: DEBUG/Receiver(10248): account: speg03@gmail.com 06-12 20:51:00.601: DEBUG/Receiver(10248): tagLabel: ^^unseen-^i 06-12 20:51:00.601: DEBUG/Receiver(10248): getAttention: true
メールの件数とアカウント名は分かるようだけどタイトルや本文まで取れるのかはわからなかった。2つあるインテントの違いもよくわからない。extrasもtagLabelの末尾にimが付いているかどうかの違いしかなく、他の値は同じようだった。
あと、通知を受信したあとでPC側からそのメールを既読にすると、その変更も同じインテントで通知される。以下がそれ。
06-12 20:53:11.054: INFO/Gmail(10262): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://gmail-ls/unread/^iim (has extras) } 06-12 20:53:11.082: INFO/Gmail(10262): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://gmail-ls/unread/^i (has extras) } 06-12 20:53:11.093: DEBUG/Receiver(10248): You've Got Mail!! 06-12 20:53:11.093: DEBUG/Receiver(10248): count: 0 06-12 20:53:11.093: DEBUG/Receiver(10248): account: speg03@gmail.com 06-12 20:53:11.093: DEBUG/Receiver(10248): tagLabel: ^^unseen-^i 06-12 20:53:11.093: DEBUG/Receiver(10248): getAttention: false
countが減っているのとgetAttention(通知動作を行うかどうかかな?)が変わっている。
UnityでEclipseのメニューが表示されない
Chromiumのフォント設定
ホームの日本語ディレクトリを英語にする
日本語環境だとホームディレクトリにドキュメントやらダウンロードやら日本語名のフォルダが並んでいるのでこれを英語名に変えたいとき。
$ LANG=C xdg-user-dirs-gtk-update
このままだと次回ログイン時に元に戻すか聞かれてしまうので聞かれないようにする。
システムの設定 > 自動起動するアプリケーション > ユーザ・フォルダの更新
のチェックを外す。
Ubuntu 11.04でXmodmapしてるとテーマが崩れる
どうしてこうなるのか結局よくわからないのだけど、ログイン時にXmodmapでキーマップを変更しているとウィンドウテーマが崩れる。崩れるという表現も合ってるのかわからないけど、要は以下のような感じになる。
崩れたというか古めかしい感じのスタイルになってしまう。~/.Xmodmapを消してみると正しい表示になった。
なおった、なおった。めでたし、めでたし。……というわけには当然いきませんで。Xmodmap使えないのは困るのです。
ちなみに.Xmodmapの中身は以下。
keycode 102 = Alt_L
Xmodmapをどう呼ぶか
xmodmapコマンドには直接式を指定して実行するオプションがあるので、それを実行するスクリプトを書いて自動起動するアプリケーションに追加した。
こんなやつ
#!/bin/sh xmodmap -e 'keycode 102 = Alt_L'
自動起動するアプリケーションの登録はシステムの設定から。
なんだかちょっと気になるやり方だけどまぁうまくいっているので良いことにしてる。
追記 2011-05-12 19:54
どうにもちょくちょくうまくいってない時があるみたい。タイミングが悪いのかしら。
また調べているといろいろ見つかりました。
.Xmodmapじゃなくて.xmodmaprcだったら大丈夫とのこと。実際、大丈夫のようだったのでしばらくこれで様子見ます。
で、一度テーマが変わってしまってからだと以下のようにすれば戻るみたい。
$ sudo gnome-settings-daemon
以下を参考にしました。