FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム » Android »【Android】【Java】テーマ(スタイル)等のリソースID(int値)を文字列から取得する

【Android】【Java】テーマ(スタイル)等のリソースID(int値)を文字列から取得する  


 Android Studio 内で完結するアプリなら必要ないかも知れないが、外部とのアプリ連携やプラグインのような別のシステムから、何らかのリソースを利用したいこともある。その場合、文字列からリソースID("android.R.~" や アプリ内の "R.~" の int値)を取得して適用することによって、Android 内のリソースを利用することができる。そのリソースID取得の方法を簡単にまとめておこう。なお今回は「テーマ(スタイル)の ID」と書いてはあるが、汎用的に使えそうなメソッドも提供しておくので、"mipmap" や "drawable", "string" なども応用すれば使える。その例もいくつか挙げておこう。


(※) Android Studio 3.1.2 / Galaxy S7 Edge (Android 7.0) / Windows10(x64) で確認



■テーマ(スタイル)の ID(int値)を文字列から取得する

 通常、Android Studio 内で開発している分には、スタイル(テーマ)は「android.R.style.Theme_DeviceDefault_Light_Dialog_Alert」(またはアプリ独自の場合「(パッケージ名).R.~」)のように、システムが用意した定数をハードコーディングしておけば事足りる。しかし動的に変更したり、何らかで ID(int値)が必要になった場合(Android のシステム関数の場合、リソースIDが引数になってるものも多い)、文字列から ID に変換できると便利だ。ちなみに私は Unity から Android のネイティブダイアログを使えるプラグインをリリースしているが、このダイアログにスタイル(テーマ)を適用するのにこの方法を用いている。基本的に Android システム以外からリソースID(int値)を利用することはわかりずらいので(アプリ固有の場合、ビルドでも変わるので)、動的に取得する方が適切だろう。なお、ID 取得に失敗したときは0になる(無い場合もエラーにはならない)。

●テーマ(スタイル)の ID(int)を取得する(関数定義)
import android.content.Context;

public static final int getStyleID(final Context context, final String name) {
if (name != null && name.length() > 0)
return context.getResources().getIdentifier(name, "style", context.getPackageName());
return 0; //取得失敗
}

●使用例(メインでのコードなど)
import android.util.Log;

//※アクティビティでの使用例
String holo_s = "android:Theme.Holo.Light.Dialog";
int holo_i = getStyleID(this, holo_s); //this は context
int holo_r = android.R.style.Theme_Holo_Light_Dialog;

String devDef_s = "android:Theme.DeviceDefault.Light.Dialog.Alert";
int devDef_i = getStyleID(this, devDef_s); //this は context
int devDef_r = android.R.style.Theme_DeviceDefault_Light_Dialog_Alert;

String mat_s = "android:Theme.Material.Light.Dialog.Alert";
int mat_i = getStyleID(this, mat_s); //this は context
int mat_r = android.R.style.Theme_Material_Light_Dialog_Alert;

Log.d("DebugTag", "holo_s = " + holo_s);
Log.d("DebugTag", "holo_i = " + holo_i);
Log.d("DebugTag", "holo_r = " + holo_r);
Log.d("DebugTag", "devDef_s = " + devDef_s);
Log.d("DebugTag", "devDef_i = " + devDef_i);
Log.d("DebugTag", "devDef_r = " + devDef_r);
Log.d("DebugTag", "mat_s = " + mat_s);
Log.d("DebugTag", "mat_i = " + mat_i);
Log.d("DebugTag", "mat_r = " + mat_r);

holo_s = android:Theme.Holo.Light.Dialog
holo_i = 16973939
holo_r = 16973939
devDef_s = android:Theme.DeviceDefault.Light.Dialog.Alert
devDef_i = 16974546
devDef_r = 16974546
mat_s = android:Theme.Material.Light.Dialog.Alert
mat_i = 16974394
mat_r = 16974394

 引数に与えてる文字列("_s" の付くもの)と Android システムの定数("_r" の付くもの)の名前を比較してみると、定数名:"android.R.style.Theme" → 文字列定数:"android:Theme" に置き換え、それ以降のアンダーバー("_")をドット(".")に置き換えれば相互変換できるとわかる。実際にはデベロッパーサイトの資料でもシステム固有値は掲載されているが、文字列から変換できると、ユーザー指定など色々便利である。特にアプリ固有の ID「(パッケージ名).R.~」の場合は、ビルドによって値が変わることもあるので、文字列から動的にIDを取得すれば、外部から利用したいときなども適切に処理できる。

(Android システムでの固有値)
Theme(テーマ[スタイル])



■リソースの種類を指定して ID(int値)を文字列から取得する

 内容的には「テーマ(スタイル)の ID(int値)取得」と同じなのだが、もう少し汎用的にリソースの種類を指定して ID(int値)を取得する関数を書いておこう。どちらかというとこっちが主役で「テーマ(スタイル)」などは種類別に書いておくと良いと思う。また文字列が空であるか否かを調べる関数も定義しておけば、かなりすっきりしたものになる。その例を挙げておこう。

●リソースの種類を指定して ID(int値)を取得する+空文字のチェック(関数定義)
import android.content.Context;

//リソースID(int値)を取得する
public static final int getResourceID(final Context context, final String type, final String name) {
if (!isNullOrEmpty(name) && !isNullOrEmpty(type))
return context.getResources().getIdentifier(name, type, context.getPackageName());
return 0; //取得失敗
}

//文字列が null または空のとき真を返す
public static final boolean isNullOrEmpty(final String str) {
return (str == null || str.length() == 0);
}

●使用例(メインでのコードなど)
import android.util.Log;

//※アクティビティでの使用例
int ic_lancher = R.mipmap.ic_launcher;
int ic_launcher_background = R.drawable.ic_launcher_background;

int app_name = R.string.app_name;
int mipmapID = getResourceID(this, "mipmap", "ic_launcher"); //this は context

int drawableID = getResourceID(this, "drawable", "ic_launcher_background"); //this は context
int stringID = getResourceID(this, "string", "app_name"); //this は context

Log.d("DebugTag", "ic_lancher = " + ic_lancher);
Log.d("DebugTag", "mipmapID = " + mipmapID);
Log.d("DebugTag", "ic_launcher_background = " + ic_launcher_background);
Log.d("DebugTag", "drawableID = " + drawableID);
Log.d("DebugTag", "app_name = " + app_name);
Log.d("DebugTag", "stringID = " + stringID);

ic_lancher = 2131361792
mipmapID = 2131361792
ic_launcher_background = 2131099732
drawableID = 2131099732
app_name = 2131427357
stringID = 2131427357

 ここでは例として "mipmap" や "drawable", "string" などを挙げているが、Android Studio を使っているなら、"R." を書いた後に出てくる入力補完に色々出てくるものが種類(ここでは引数の type)に相当すると考えて良いだろう。名前(name)は種類の "." 以降のものである。また Android システム自身が持っているリソースは "android:XXX~" と書けば良い(エディタ上で [Ctrl+B] を押せば参照できることがある[xml など])。


 以上の説明を踏まえて、前述した「テーマ(スタイル)の ID(int値)取得」や "mipmap", "drawable", "string" などを種類別に書いても良いだろう("string" の場合は "app_name" [アプリ名] などと組み合わせた関数を作ると楽かも知れない)。例えば以下のような関数を作っても良い。

●"mipmap", "drawable", "string" などのID(int値)を文字列から取得する
import android.content.Context;

//・・・(前述の関数定義は略)・・・

//テーマ(スタイル)のリソースIDを取得 [※種類別に書き換えた例]
public static final int getStyleID(final Context context, final String name) {
return getResourceID(context, "style", name);
}

//Mipmap画像("res/mipmap~")のリソースIDを取得(API 11)
public static final int getMipmapID(final Context context, final String name) {
return getResourceID(context, "mipmap", name); //API 11
}

//画像("res/drawable~")のリソースのIDを取得
public static final int getDrawableID(final Context context, final String name) {
return getResourceID(context, "drawable", name);
}

//文字列のリソースIDを取得
public static final int getStringID(final Context context, final String name) {
return getResourceID(context, "string", name);
}

//アプリ名のリソースIDを取得
public static final int getAppNameID(final Context context) {
return getResourceID(context, "string", "app_name"); //※デフォルトの場合
}

//アプリ名を取得
public static final String getAppName(final Context context) {
final int id = getAppNameID(context);
if (id != 0)
return context.getResources().getString(id);
return ""; //取得失敗。"app_name" 以外?(無いものもある)
}

 "string" 等の場合はIDから「String str = getResources().getString(stringID);」(アクティビティ上)のようにすれば文字列を取得することもできる。ただし、ID 取得に失敗したときは0になるので注意しよう(無い場合もエラーにはならない)。なお、デフォルトの場合 "app_name" にアプリ名が書かれたりするが(リソースの "res/values/string.xml")、アプリによっては書かれてないものもあるので気をつけて欲しい(そもそも xml を定義してないもの[サービスアプリとか]もある)。その場合は「PackageManager」からアプリ名を取得する方法もあるが、それはまた次の記事を見て欲しい。

 よく利用するものだけでも作っておけば便利なので、色々やってみると良いだろう。





(関連記事)
【Android】【Java】アプリ名、バージョン番号(versionCode)、バージョン名(versionName)などをコードで取得する(PackageManager を利用)
【Android】【Java】アプリ名 app_name タグをコードで取得する
【Android】【Java】画像リソースIDをコードで取得する
【Android】【Java】リソース名で、res/drawable-~ フォルダから、画像を読み込む(Bitmap)
【Android】【Java】リソース名で、res/drawable-~ フォルダから、画像を読み込む(Drawable)
【Android】【Java】res/raw リソースフォルダからテキストファイルを読み込む


関連記事
スポンサーサイト



category: Android

thread: プログラミング

janre: コンピュータ

tag: Androidライブラリ  Java 
tb: 0   cm: --


トラックバック

トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/302-5cfa8f0d
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop