がんばってみました。
Xperia X10 のステータスバーは濃い青

ステータスバーのレイアウトを指定している xml がこれです。
frameworks/base/core/res/res/layout/status_bar.xml
これを見ると、
- <com.android.server.status.StatusBarView xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@drawable/statusbar_background"
- android:orientation="vertical"
- android:focusable="true"
- android:descendantFocusability="afterDescendants"
- >
- <LinearLayout android:id="@+id/icons"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="horizontal">
- <com.android.server.status.IconMerger android:id="@+id/notificationIcons"
- android:layout_width="0dip"
- ...
- />
- </LinearLayout>
- </com.android.server.status.StatusBarView>
com.android.server.status.StatusBarView というカスタムビューを
使っています。
ここで、背景画像を設定しています。
android:background="@drawable/statusbar_background"
ちなみにこの画像は Android Open Source Project のここ
で見られます。
こんなやつ

com.android.server.status.StatusBarView を生成しているのが、
com.android.server.status.StatusBarService です。
こいつ
frameworks/base/services/java/com/android/server/status/StatusBarService.java
StatusBarService.java はこことかでみられます。
StatusBarView.java はこのへんで。
この StatusBarService は変数として、StatusBarView
(mStatusBarView)を保持しています。
- public class StatusBarService extends IStatusBar.Stub
- {
- ...
- final Context mContext;
- final Display mDisplay;
- StatusBarView mStatusBarView;
- ...
- /**
- * Construct the service, add the status bar view to the window manager
- */
- public StatusBarService(Context context) {
- mContext = context;
- mDisplay = ((WindowManager)context.getSystemService(
- Context.WINDOW_SERVICE)).getDefaultDisplay();
- makeStatusBarView(context);
- mUninstallReceiver = new UninstallReceiver();
- }
- ....
- // ================================================================================
- // Constructing the view
- // ================================================================================
- private void makeStatusBarView(Context context) {
- Resources res = context.getResources();
- mRightIconSlots = res.getStringArray(com.android.internal.R.array.status_bar_icon_order);
- mRightIcons = new StatusBarIcon[mRightIconSlots.length];
- ExpandedView expanded = (ExpandedView)View.inflate(context,
- com.android.internal.R.layout.status_bar_expanded, null);
- expanded.mService = this;
- StatusBarView sb = (StatusBarView)View.inflate(context,
- com.android.internal.R.layout.status_bar, null);
- sb.mService = this;
- // figure out which pixel-format to use for the status bar.
- mPixelFormat = PixelFormat.TRANSLUCENT;
- Drawable bg = sb.getBackground();
- if (bg != null) {
- mPixelFormat = bg.getOpacity();
- }
- mStatusBarView = sb;
- ...
つまり、この mStatusBarView を取得して getBackground すれば
背景画像がとれちゃうわけです。
今回もリフレクションしますw
*注! この方法は Reflection で内部クラスを使っているので、SDKのアップデートなどで使えなくなる可能性があります。
ステータスバーの背景画像を取得する
- private Drawable getStatusBarBackground() {
- try {
- ClassLoader cl = getClassLoader();
- Class<!----> clazz;
- clazz = cl.loadClass("com.android.server.status.StatusBarService");
- Constructor<!----> constructor = clazz.getConstructor(Context.class);
- Object obj = constructor.newInstance(this);
- Class<!----> c = obj.getClass();
- Field field;
- //field = c.getDeclaredField("com.android.server.status.StatusBarService.mStatusBarView");
- field = c.getDeclaredField("mStatusBarView");
- if(!field.isAccessible()) {
- field.setAccessible(true);
- }
- ViewGroup vg = (ViewGroup) field.get(obj);
- Drawable d = vg.getBackground();
- return d;
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- return null;
- } catch (SecurityException e) {
- e.printStackTrace();
- return null;
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- return null;
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- return null;
- } catch (InstantiationException e) {
- e.printStackTrace();
- return null;
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- return null;
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- return null;
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- return null;
- }
- }
注: AndroidManifest.xml に
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
を入れないと、Homeキーを押したときに落ちます
おまけ:
取得した Drawable は BitmapDrawable ではなく、
NinePatchDrawable です。
なので、
"Bitmap, Drawableに変換 - hyoromoの日記"
の方法では、Bitmap に変換できませんでした。
そこで一回ImageViewに突っ込んでから、DrawingCache で Bitmap を
取得しました。
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Drawable d = getStatusBarBackground();
- if(d != null) {
- ImageView iv = ((ImageView)findViewById(R.id.imageview));
- iv.setImageDrawable(d);
- }
- }
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- super.onWindowFocusChanged(hasFocus);
- ImageView iv = (ImageView)findViewById(R.id.imageview);
- iv.setDrawingCacheEnabled(true);
- iv.buildDrawingCache();
- Bitmap b = iv.getDrawingCache();
- if(b != null) {
- int x = b.getWidth() / 2;
- int y = b.getHeight() / 2;
- int c = b.getPixel(x, y);
- ((TextView)findViewById(R.id.textview)).setText("
- "alpha: " + Color.alpha(c) +
- " red: " + Color.red(c) +
- " green: " + Color.green(c) +
- " blue: " + Color.blue(c));
- }
- else {
- ((TextView)findViewById(R.id.textview)).setText("no drawing cache");
- }
- }
かっとなって、アプリを公開しちゃいました。
GetStatusBarColor AndroidOnly → http://goo.gl/WT24
標準だと灰色なんだけど

HTC Hero は黒でした。

0 件のコメント:
コメントを投稿