Android 系統 Service

Android 系統級別的Service有好多,可以通過getSystemService(@ServiceName @NonNull String name)方法得到(通過@Service注解限定參數范圍)。
系統Service主要有:

  • WINDOW_SERVICE(android.view.WindowManager)
  • LAYOUT_INFLATER_SERVICE(android.view.LayoutInflater)
  • ACTIVITY_SERVICE(android.app.ActivityManager)
  • POWER_SERVICE(android.os.PowerManager)
  • ALARM_SERVICE(android.app.AlarmManager)
  • NOTIFICATION_SERVICE(android.app.NotificationManager)
  • KEYGUARD_SERVICE(android.app.KeyguardManager)
  • LOCATION_SERVICE(android.location.LocationManager)
  • SEARCH_SERVICE(android.app.SearchManager)
  • SENSOR_SERVICE(android.hardware.SensorManager)
  • STORAGE_SERVICE(android.os.storage.StorageManager)
  • VIBRATOR_SERVICE(android.os.Vibrator)
  • CONNECTIVITY_SERVICE(android.net.ConnectivityManager)
  • WIFI_SERVICE(android.net.wifi.WifiManager)
  • AUDIO_SERVICE(android.media.AudioManager)
  • MEDIA_ROUTER_SERVICE(android.media.MediaRouter)
  • TELEPHONY_SERVICE(android.telephony.TelephonyManager)
  • TELEPHONY_SUBSCRIPTION_SERVICE(android.telephony.SubscriptionManager)
  • CARRIER_CONFIG_SERVICE(android.telephony.CarrierConfigManager)
  • INPUT_METHOD_SERVICE(android.view.inputmethod.InputMethodManager)
  • UI_MODE_SERVICE(android.app.UiModeManager)
  • DOWNLOAD_SERVICE(android.app.DownloadManager)
  • BATTERY_SERVICE(android.os.BatteryManager)
  • JOB_SCHEDULER_SERVICE(android.app.job.JobScheduler)
  • NETWORK_STATS_SERVICE(android.app.usage.NetworkStatsManager)
  • HARDWARE_PROPERTIES_SERVICE(android.os.HardwarePropertiesManager)

WindowManager

經常看直播的小伙伴們會發現現在退出直播頁之后會有一個懸浮窗在直播列表上,方便用戶在查看其它直播的時候仍然可以看到之前的直播內容,這個通過WindowManager就可以實現。WindowManager繼承自ViewManager,ViewManager里邊有添加刪除更新View的方法

public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);

其中LayoutParams中可以定義View的坐標,type(window類型),flag(顯示特性),softInputMode,gravity,horizontalMargin,verticalMargin,format,windowAnimations(系統資源),alpha等屬性。只要在調用這三個方法就可以了。

LayoutInflater

LayoutInflater比較常用,尤其在Adapter中經常會用到

LayoutInflater.from(context).inflate(R.layout.item, parent, false)
這里注意一下后兩個參數,parent一般不推薦傳null,如果上邊這種形式返回的是實例化出來的View,如果false改為true,返回的為第二個參數parent,這點可以從源碼中得到答案。

// We are supposed to attach all the views we found (int temp)
                    // to root. Do that now.
                    if (root != null && attachToRoot) {
                        root.addView(temp, params);
                    }

                    // Decide whether to return the root that was passed in or the
                    // top view found in xml.
                    if (root == null || !attachToRoot) {
                        result = temp;
                    }

root為傳進來的parent,result開始初始化為root,最后返回result。

ActivityManager

ActivityManager的很多方法是通過ActivityManagerNative實現的,ActivityManagerNative繼承了Binder并實現了IActivityManager接口。ActivityManager里常用方法:

//跟當前app有關系的任務列表
public List<ActivityManager.AppTask> getAppTasks()

//當前運行的Service列表
public List<RunningServiceInfo> getRunningServices(int maxNum) throws SecurityException

//得到內存信息
public void getMemoryInfo(MemoryInfo outInfo)

//設備配置信息
public ConfigurationInfo getDeviceConfigurationInfo()

//獲取系統運行進程
public List<RunningAppProcessInfo> getRunningAppProcesses()

AlarmManager

AlarmManager 可以在未來的一個時間點調起app,到了時間點是如果app沒有啟動,系統會廣播之前設定的Intent,自動啟動app。
AlarmManager常用方法

/** @param type {ELAPSED_REALTIME}, {ELAPSED_REALTIME_WAKEUP},
     *        {RTC},  {RTC_WAKEUP}中的一個,喚醒方式.
     * @param triggerAtMillis 設定的時間點,type方式不同,表示的時間不同
     * @param operation執行的Intent.
public void set(int type, long triggerAtMillis, PendingIntent operation)

//重復Alarm,intervallMillis表示兩次的間隔
public void setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation) 

//API 19開始上邊兩個方法設定的時間變得不準確,系統添加了下邊兩個方法保證嚴格傳遞。
public void setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation) 

public void setExact(int type, long triggerAtMillis, PendingIntent operation)

設置完之后要在工程內創建接受Intent的Activity、Broadcast或者Service處理邏輯。

NotificationManager

NotificationManager比較常見,用來發送消息通知.

notifyManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
builder = new Notification.Builder(context);
builder.setContentTitle(context.getString(R.string.offline_package_download, mission.getName()))
                    .setContentText(context.getString(R.string.start_download))
                    .setSmallIcon(android.R.drawable.stat_sys_download).setProgress(100, 0, true)
                    .setTicker(context.getString(R.string.start_download)).setAutoCancel(true);
notifyManager.notify(missionId, builder.getNotification());

LocationManager

提供設備地理位置信息的Service。


LocationManager manager = (LocationManager)getSystemService(LOCATION_SERVICE);
//需要確認權限ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION一個粗精度,一個精確精度,至少一個
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 50.0f, new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
});

另外,LocationManager里邊還可以獲取并設置GPS、NetWork等提供獲取位置的方式,這里不在贅述。

SearchManager

實際開發中,并不需要直接與SearchManager交互,因為Activity和Intent(ACTION_SEARCH) 中已經提供了搜索的方法。

SensorManager

使用SensorManager時要注意傳感器的釋放,避免耗電,鎖屏時系統會自動釋放傳感器。

public class SensorActivity extends Activity implements SensorEventListener {
    private final SensorManager mSensorManager;
    private final Sensor mAccelerometer;

    public SensorActivity() {
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    }

    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    public void onSensorChanged(SensorEvent event) {
    }
}

Vibrator

需要權限:android.Manifest.permission#VIBRATE
Vibrator使用起來比較簡單,兩個常用方法:
//振動milliseconds毫秒
public void vibrate(long milliseconds)
//pattern控制振動的開關,數組內第一個元素表示等待多長時間開始振動,第二個元素表示振動多長時間,依次類推。repeat表示從數組內開始重復振動的索引,傳-1表示不重復。
public void vibrate(long[] pattern, int repeat)
//停止振動
public abstract void cancel();

ConnectivityManager

ConnectivityManager提供網絡連接狀態查詢,并在網絡狀態改變時通知App。
主要作用:

  • 監聽網絡連接(Wi-fi,GPRS,UMTS,等)
  • 網絡連接改變時發送廣播
  • 網絡丟失時試圖故障轉移到另一個網絡
  • 提供查詢大致或精確可用網絡狀態的API
  • 提供查詢并選定數據傳輸網絡的API
//網絡是否可用
ConnectivityManager conManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conManager.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());

//判斷Wifi狀態
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return manager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;

//注冊廣播,接受網絡狀態變化,
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(NetworkReceiver, filter);

WifiManager

WifiManager管理各種Wi-fi連接,提供打開、關閉Wi-fi,連接、斷開連接、添加網絡,瀏覽接入點,獲取連接網絡信息的API。通過Context.getSystemService(Context.WIFI_SERVICE)獲取實例時應該使用application context,避免內存泄漏。

AudioManager

AudioManager管理音量和鈴聲模式。

//獲取鈴聲模式AudioManager.RINGER_MODE_NORMAL、AudioManager.RINGER_MODE_SILENT、AudioManager.RINGER_MODE_VIBRATE
public int getRingerMode()

//設置鈴聲模式
public void setRingerMode(int ringerMode)

//獲取流最大音量
public int getStreamMaxVolume(int streamType) 

//獲取流最小音量
public int getStreamMinVolume(int streamType)

//獲取流當前音量
public int getStreamVolume(int streamType)

//調整最相關的流的音量
//direction ADJUST_LOWER、ADJUST_RAISE、ADJUST_SAME、ADJUST_MUTE、ADJUST_UNMUTE
public void adjustVolume(int direction, int flags)

//設備音量是否鎖定
public boolean isVolumeFixed()

TelephonyManager

通過TelephonyManager可以獲取手機卡、運營商、當前網絡、國家代碼等信息。

TelephonyManager manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
Log.e("getDeviceId",manager.getDeviceId());//deviceID
Log.e("getNetworkOperatorName",manager.getNetworkOperatorName());//運營商名稱
Log.e("isNetworkRoaming",manager.isNetworkRoaming()+"");//是否漫游
Log.e("getNetworkCountryIso",manager.getNetworkCountryIso());//國家代碼
Log.e("getNetworkType",manager.getNetworkType()+"");//當前網絡類型,2G\3G\4G
Log.e("getSimState",manager.getSimState()+"");//默認SIM卡狀態
Log.e("getSimOperator",manager.getSimOperator());//SIM卡經營者
Log.e("getSimOperatorName",manager.getSimOperatorName());//SIM卡經營者名稱
Log.e("getSimCountryIso",manager.getSimCountryIso());//SIM卡經營者所在國家代碼
Log.e("getSimSerialNumber",manager.getSimSerialNumber());//SIM卡序列號
Log.e("getLine1Number",manager.getLine1Number());//手機號
... ...

InputMethodManager

InputMethodManager用來管理軟鍵盤。常用方法包括hide,show,toggle.

InputMethodManager manager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        switch (view.getId()) {
            case R.id.hide:
            //隱藏軟鍵盤
                manager.hideSoftInputFromWindow(editText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
                break;
            case R.id.show:
               //顯示選擇輸入法懸浮窗
                manager.showInputMethodPicker();
                //顯示軟鍵盤
                manager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
                break;
            case R.id.toggle:
               //軟鍵盤開關
                manager.toggleSoftInputFromWindow(editText.getWindowToken(), InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
                break;
        }

UiModeManager

UiModeManager管理設備夜間模式和車載模式,常用方法:

UiModeManager manager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
        switch (view.getId()){
            case R.id.car_mode_yes:
//              開啟車載模式
                manager.enableCarMode(0);
                break;
            case R.id.car_mode_no:
//              關閉車載模式
                manager.disableCarMode(0);
                break;
            case R.id.night_mode_yes:
//              開啟夜間模式,注意setNightMode只有在開啟車載模式時才起作用
                manager.setNightMode(UiModeManager.MODE_NIGHT_YES);
                Log.e(TAG, String.valueOf(manager.getNightMode()));
                break;
            case R.id.night_mode_no:
//              關閉夜間模式
                manager.setNightMode(UiModeManager.MODE_NIGHT_YES);
                Log.e(TAG, String.valueOf(manager.getNightMode()));
                break;
        }
        ((Button)view).setText(String.valueOf(manager.getCurrentModeType()));

DownloadManager

DownloadManager用于處理下載長時間下載操作。DownloadManager會在后臺下載,監聽HTTP連接并在下載失敗或者系統重啟或者連接變化是重新下載。請求下載是應該注冊broadcast receiver處理Notification點擊和下載完成后的操作。


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download_manager);

        IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);

        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
//              reference對應startDownload中manger.enqueue的返回值。
                long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
                Log.e(TAG, "onReceive: "+reference);
            }
        };
        registerReceiver(receiver, filter);
    }

    public void onClick(View view){
        switch (view.getId()){
            case R.id.download_start:
                startDownload();
                break;
        }
    }

    private void startDownload() {
        DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        DownloadManager.Request down = new DownloadManager.Request(Uri.parse(PATH));
        down.setDescription("test  test");
        down.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        down.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_MOVIES,"test.mp4");
        long l = manager.enqueue(down);
        Log.e(TAG, "startDownload: "+l);
    }

BatteryManager

BatteryManager包涵了ACTION_BATTERY_CHANGED這個Intent的常量和字符串,提供了查詢電量和充電屬性的API。

IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, filter);
//你可以讀到充電狀態,如果在充電,可以讀到是usb還是交流電
 
// 是否在充電
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;
 
// 怎么充
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;

另外除去上述常見Service之外還有PowerManager、KeyguardManager、StorageManager、MediaRouter、SubscriptionManager、CarrierConfigManager、JobScheduler、NetworkStatsManager、HardwarePropertiesManager后續補全。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容