版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/luliyuan/article/details/78269225
文章主要参考《Android实现自定义状态栏》
公司的项目目标是自己开发一个状态栏,显示时间日期,蓝牙无线等状态
核心:statusBar是SystemUI的一部分,statusBar跟正常建立的Android app不同,它不能有主Activity,需要在服务中创建窗口画面。SystemUIService是SystemUI的入口处,是被系统启动,之后通过WindowsManager创建画面显示。
1、AndroidManifest.xml文件
package="com.android.systemui"<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />/*这个可能不需要*/<uses-permission android:name="android.permission.STATUS_BAR" /><uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />/* 创建TYPE_STATUS_BAR类型窗体,需要此权限*/<service android:name="SystemUIService"android:exported="true"/>/*不能设置启动Activity*/<!--<activity android:name=".MainActivity">--><!--<intent-filter>--><!--<action android:name="android.intent.action.MAIN" />--><!--<category android:name="android.intent.category.DEFAULT" />--><!--<category android:name="android.intent.category.LAUNCHER" />--><!--</intent-filter>--><!--</activity>-->
2、 StatusIconView
public class StatusIconView extends LinearLayout {//图标private ImageView mIcon;public StatusIconView(Context context) {super(context);}public StatusIconView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public StatusIconView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context, attrs, defStyle);}private void init(Context context, AttributeSet attrs, int defStyle) {LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);inflater.inflate(R.layout.status_icon_view, this);mIcon = (ImageView) findViewById(R.id.icon);}public final void setIcon(int resId) {mIcon.setImageResource(resId);}public final ImageView getIconView(){return mIcon;}}
需要的xml文件status_icon_view
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal" ><ImageViewandroid:id="@+id/icon"android:layout_width="wrap_content"android:layout_height="@dimen/status_bar_icon_height" /><!--<TextView--><!--android:id="@+id/title"--><!--android:layout_width="@dimen/status_bar_icon_width"--><!--android:layout_height="@dimen/status_bar_icon_height" />--></LinearLayout>
3、SystemUIService
public class SystemUIService extends Service {private WindowManager wm = null;private WindowManager.LayoutParams statusBarParams = new WindowManager.LayoutParams();private LinearLayout statusBarLayout=null;private StatusBarViewHolder statusBarViewHolder = new StatusBarViewHolder();@Overridepublic void onCreate() {super.onCreate();createStatusView();registerReceiver();}@Overridepublic IBinder onBind(Intent intent) {return null;}/* 手机电池电量显示 */BroadcastReceiver phoneBatteryReceiver = new BroadcastReceiver(){public void onReceive(Context context, Intent intent) {if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){int level = intent.getIntExtra("level", 0);int scale = intent.getIntExtra("scale", 100);int curPower = (level * 100 / scale);updateIcon(getBatteryImage(curPower), statusBarViewHolder.phoneBatteryIcon);}};};private void createStatusView(){Context context = getApplicationContext();statusBarLayout = new LinearLayout(context);//statusBarLayout.setGravity(Gravity.CENTER_VERTICAL);//statusBarLayout.setLayoutParams(new android.view.ViewGroup.LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT));wm=(WindowManager)getApplicationContext().getSystemService(WINDOW_SERVICE);((LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(R.layout.status_bar, statusBarLayout);findStatusBarViews();wm.addView(statusBarLayout, getStatusViewParams());}private WindowManager.LayoutParams getStatusViewParams(){statusBarParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,(int) getResources().getDimension(R.dimen.status_bar_height),WindowManager.LayoutParams.TYPE_STATUS_BAR,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,PixelFormat.TRANSLUCENT);statusBarParams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;statusBarParams.gravity = Gravity.TOP;statusBarParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;statusBarParams.setTitle("StatusBar");statusBarParams.packageName = this.getPackageName();return statusBarParams;}private void findStatusBarViews() {statusBarViewHolder.datetimeTextView = (TextView) statusBarLayout.findViewById(R.id.datetime_textView);statusBarViewHolder.phoneUSBIcon = (StatusIconView)statusBarLayout.findViewById(R.id.usb_icon);statusBarViewHolder.phoneSDCardIcon = (StatusIconView)statusBarLayout.findViewById(R.id.sdcard_icon);statusBarViewHolder.phoneHotspotIcon = (StatusIconView)statusBarLayout.findViewById(R.id.hotspot_icon);statusBarViewHolder.phoneMobileIcon = (StatusIconView)statusBarLayout.findViewById(R.id.mobile_icon);statusBarViewHolder.phoneBluetoothIcon = (StatusIconView)statusBarLayout.findViewById(R.id.bluetooth_icon);statusBarViewHolder.phoneWifiIcon = (StatusIconView)statusBarLayout.findViewById(R.id.wifi_icon);statusBarViewHolder.phoneBatteryIcon = (StatusIconView)statusBarLayout.findViewById(R.id.battery_icon);statusBarViewHolder.phoneUSBIcon.setIcon(R.drawable.usb);statusBarViewHolder.phoneSDCardIcon.setIcon(R.drawable.sd);statusBarViewHolder.phoneBluetoothIcon.setIcon(R.drawable.btconnected);statusBarViewHolder.phoneWifiIcon.setIcon(R.drawable.wifi0);}private void updateIcon(int Icon, StatusIconView icon){icon.setIcon(Icon);}private int getBatteryImage(int battery) {int resId;if(battery > 0 && battery <= 10){resId = R.drawable.battery0;}else if(battery > 10 && battery <= 40){resId = R.drawable.battery1;}else if(battery > 40 && battery <= 60){resId = R.drawable.battery2;}else if(battery > 60 && battery <= 80){resId = R.drawable.battery3;}else if(battery > 80 && battery <= 100){resId = R.drawable.battery4;}else{resId = R.drawable.battery0;}return resId;}/*** 注册状态栏更新信息的广播*/private void registerReceiver() {registerReceiver(phoneBatteryReceiver , new IntentFilter(Intent.ACTION_BATTERY_CHANGED));}/*** 状态栏的所有图标*/private class StatusBarViewHolder{TextView datetimeTextView;StatusIconView phoneUSBIcon;StatusIconView phoneSDCardIcon;StatusIconView phoneHotspotIcon;StatusIconView phoneMobileIcon;StatusIconView phoneBluetoothIcon;StatusIconView phoneWifiIcon;StatusIconView phoneBatteryIcon;}@Overridepublic void onDestroy(){unregisterReceiver();wm.removeView(statusBarLayout);super.onDestroy();}private void unregisterReceiver(){unregisterReceiver(phoneBatteryReceiver);}public String GetSysTime() {long sysTime = System.currentTimeMillis();String time = "";boolean is24Hour = DateFormat.is24HourFormat(getApplicationContext());/** @brief Get the same time as the system. */if(is24Hour) {time = (String) DateFormat.format("yyyy-MM-dd HH:mm:ss", sysTime);}else{time = (String) DateFormat.format("yyyy-MM-dd hh:mm:ss", sysTime);}return time;}
需要的xml文件status_bar
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="@dimen/status_bar_height"><TextViewandroid:id="@+id/datetime_textView"android:layout_width="0dp"android:layout_weight="1"android:layout_height="@dimen/status_bar_date_height"android:textColor="@android:color/holo_red_dark"android:layout_gravity="center"/><LinearLayoutandroid:layout_width="0dp"android:layout_weight="1"android:gravity="right"android:layout_height="@dimen/status_bar_icon_width"><com.android.systemui.StatusIconViewandroid:id="@+id/usb_icon"android:layout_width="wrap_content"android:layout_height="@dimen/status_bar_icon_height"android:layout_gravity="center"/><com.android.systemui.StatusIconViewandroid:id="@+id/sdcard_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"/><com.android.systemui.StatusIconViewandroid:id="@+id/hotspot_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"/><com.android.systemui.StatusIconViewandroid:id="@+id/mobile_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"/><com.android.systemui.StatusIconViewandroid:id="@+id/bluetooth_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"/><com.android.systemui.StatusIconViewandroid:id="@+id/wifi_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"/><com.android.systemui.StatusIconViewandroid:id="@+id/battery_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"/></LinearLayout><!--<TextView--><!--android:id="@+id/ssidInfo"--><!--android:layout_width="match_parent"--><!--android:layout_height="400dp"--><!--android:lines="10"--><!--android:textColor="@android:color/holo_red_dark"/>--></LinearLayout>
注意:以上工程一定要替换系统的SystemUI源码,编译后烧写内核才可以
