2010年10月21日木曜日

Androidの標準ブラウザで開いたHTMLから自作アプリを起動してみた

通常のアプリのように見えて、
かつ、
ブラウザーからもアプリを起動できるようにするためには、
アクティビティにintent-filterを追加すればよい。

AndroidManifest.xml
<activity
    android:name=".MyActivity"
    android:label="@string/app_name"
    >
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="hello" android:host="world"/>
    </intent-filter>
</activity>

HTMLには
<a href="hello://world/">起動</a>
こんなリンクを用意する。

ブラウザーから起動された場合、getIntent().getData()でUriを取得することができる。
アクティビティが普通に起動されたときには、getData()はnullを返す。


2010年8月31日火曜日

画像でボタンを作る方法

これまでスタイルで指定する方法を使っていたけれど、よりよい方法を見つけた。
スタイルで指定するとEclipseのLayoutエディタではプレビューできなかった。
でも、以下の方法ならばプレビューもちゃんとできる。

まず、画像を3つ用意する。
  • 通常時の画像。
  • トラックパッドなどで選択されている時の画像。
  • タッチされている時の画像。
例えばこんな感じ。
res/drawable/normal.png
res/drawable/focused.png
res/drawable/pressed.png

次に、ボタンの状態に応じて表示するものが変わるdrawableをxmlで作成する。

drawable/button.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/focused" android:state_focused="true"/>
    <item android:drawable="@drawable/pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/normal"/>
</selector>


そしてボタンに適用する。

layoutファイルにて
<Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@drawable/button"/>

自作Viewのカスタム属性

MyViewという名前で自作Viewを作り、カスタム属性helloを作る方法のメモ。

まず res/values/attrs.xml を作って属性を定義する。

res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="MyView">
    <attr name="hello" format="string"/>
  </declare-styleable>
</resources>

これで、R.styleable.MyViewとR.styleable.MyView_helloというフィールドが自動生成される。

次に、MyViewのコンストラクタでカスタム属性を読むコードを書く。

MyView.java
public MyView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);

  TypedArray a = context.obtainStyledAttributes(
    attrs, R.styleable.MyView, defStyle, 0);
  this.hello = a.getString(R.MyView_hello);
  a.recycle();
}

MyViewを使う時は、属性のために名前空間を宣言する。

layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:takumak="http://schemas.android.com/apk/res/[Rクラスのパッケージ名]"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <com.blogspot.takumakei.lib.MyView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    takumak:hello="hello world"/>
</LinearLayout>

参考にした情報

2010年8月30日月曜日

Galaxy Sは魅力的な端末だった

たまたま実機に触れるチャンスがあった。
反応が速くて素敵。
有機ELディスプレイも綺麗だし。
すごい魅力的。

2010年8月18日水曜日

SIMとICCIDとIMSIとIMEI

ICCIDとはIC Card IDのこと。SIMカード固有の番号。
SIMカードとはSubscriber Identity Module Cardのこと。
加入者識別番号モジュールカード。

android.telephony.TelephonyManager#getSimSerialNumberでICCIDを取得可能。

IMSIとはInternational Mobile Subscriber Identityのこと。

国際移動体加入者識別番号。
キャリアがSIMに割り当てた識別番号。
携帯電話の通信ではIMSIが電話番号の役割を担う。
IMSIは再利用される可能性がある。
IMSIは滅多に送信されることがないらしい。

IMEIはInternational Mobile Equipment Identifierのこと。
国際移動体装置識別番号。
端末に割り当てられた番号。
*#06#と入力すると携帯電話の画面に表示できる。


TelephonyManagerのインスタンスは、
READ_PHONE_STATEパーミッションが必要。

2010年8月17日火曜日

みたことあるAndroid端末のUser Agentたち

HT-03A
Mozilla/5.0 (Linux; U; Android 1.6; ja-jp; Docomo HT-03A Build/DRD08) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1

X06HT Desire
Mozilla/5.0 (Linux; U; Android 2.1-update1; ja-jp; HTC Desire Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17

SO-01B XPERIA
Mozilla/5.0 (Linux; U; Android 1.6; ja-jp; SonyEricssonSO-01B Build/R1EA018) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1

IS01
Mozilla/5.0 (Linux; U; Android 1.6; ja-jp; IS01 Build/S7070) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1

2010年7月18日日曜日

JavaでXPathを使ってみた

Sample.java
import java.io.FileInputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class Sample {
    public static void main(String[] args) throws Exception {
        Document document =
            DocumentBuilderFactory
            .newInstance()
            .newDocumentBuilder()
            .parse(new FileInputStream("books.xml"));
        XPathExpression xpath =
            XPathFactory
            .newInstance()
            .newXPath()
            .compile("//book[@year='2000']/title/text()");
        Node node = (Node)xpath.evaluate(document, XPathConstants.NODE);
        if (null != node)
            System.out.println(node.getNodeValue());
        else
            System.out.println("not found");
    }
}
books.xml
<?xml version="1.0" encoding="utf-8"?>
<inventory>
    <book year="2000">
        <title>Snow Crash</title>
        <author>Neal Stephenson</author>
        <publisher>Spectra</publisher>
        <isbn>0553380958</isbn>
        <price>14.95</price>
    </book>
    <book year="2005">
        <title>Burning Tower</title>
        <author>Larry Niven</author>
        <author>Jerry Pournelle</author>
        <publisher>Pocket</publisher>
        <isbn>0743416910</isbn>
        <price>5.99</price>
    </book>
</inventory>

そもそも、AndroidでXMLしたくて調べたのだけれど、
XPathはAPI Level 8 (Android 2.2) でプラットフォームに取り込まれた。
最近ターゲットにしているAPI Level 4 (Android 1.6) では標準ではなかった。

参考: Java XPath API