Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之廣播與服務(一)

Android之廣播與服務(一)

編輯:關於Android編程

前言:作為四大組件成員--廣播和服務,雖然在用戶使用時它們通常是隱身的,但是好多地方都有它們的身影,如:發送短信,狀態欄通知,夜間模式,後台音樂播放等等....

 

One ----------- 廣播:

一,基本知識:

(1)名字:BroadcastReceiver

(2)作用:用於監聽系統全局的廣播消息,以便實現系統中不同組件之間的通信

(3)經常用途:飛行模式,後台音樂播放(與Service結合),電池電量,短信收接,電源斷接,apk裝卸,內存,拍照,開機自啟等

二,基本用法:

(1)創建需要啟動的BroadcastReceiver的Intent(可以設置Intent的相關屬性)

(2)調用Context的sendBroadcast()或sendOrderedBroadcast()方法來啟動指定的廣播

例子:

在主類中:

 

    Intent intent = new Intent();   //創建要啟動廣播的Intent
    intent.setAction("com.maiyu.action.MAIYU_BROADCAST");   //為Intent設置相關屬性,這裡采用自定義動作(需要去注冊)
    intent.putExtra("msg" , "自定義的廣播");
        sendBroadcast(intent);
自定義廣播接收器,一般是繼承:

 

 

public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context , "接收到的Action為:" + intent.getAction()
                + "\n消息內容是:" + intent.getStringExtra("msg") ,Toast.LENGTH_SHORT).show();
    }
}

然後在Manifest中注冊:

 

 


            
                
            
        

 

三,廣播的分類:

Normal Broadcast ---- 普通廣播:同時被接受,無法傳遞接收處理後的結果,無法終止傳播

-------用sendBroadcast()方法發送

Ordered Broadcast------ 有序廣播:按等級傳播,高--低(可用IntentFilter.setPriority()設置,低於的不能接收到,高的接收後,

可以終止繼續傳播

-------- 用sendOrderedBroadcast()方法發送

四,另一種常用用法(常用此方法)

使用registerReceiver()來注冊,步驟如下:

(1)自定義廣播接收器,一般采用繼承,然後重寫onReceive()方法(可在裡面判斷動作):

如開機自啟設置:

 

    //自定義開機自啟廣播接收器:
    class BootCompleteReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            /*Intent.ACTION_BOOT_COMPLETED:是系統開機自啟的動作*/
            if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
                //FourActivity為當前Activity
                Intent  newIntent = new Intent(context , FourActivity.class);
                newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(newIntent);
            }
        }
    }

 

然後在FourActivity中,創建該廣播接收器,並去注冊:

在onCreate方法中:

 

BCreceiver  =   new BootCompleteReceiver();
在需要的監聽代碼中:

 

 

                //開機自啟動的設置
                case R.id.startAfterBoot :
                    //下面三行可概括為:
                    // registerReceiver(BCreceiver , new IntentFilter("android.intent.action.BOOT_COMPLETED"));
                    IntentFilter inf = new IntentFilter();
                    inf.addAction(Intent.ACTION_BOOT_COMPLETED);
                    registerReceiver(BCreceiver , inf);
                    Toast.makeText(FourActivity.this , "開機自啟已經完成" , Toast.LENGTH_SHORT).show();
                    break;
                case R.id.nostartAfterBoot :
                    if(BCreceiver != null){
                        unregisterReceiver(BCreceiver); //取消注冊
                        Toast.makeText(FourActivity.this , "開機自啟已經取消" , Toast.LENGTH_SHORT).show();
                    }
                    break;
記得添加自啟動權限:

 

 

由此可見:registerReceiver():接收兩個參數,

 

------參數1:自定義的廣播接收器對象

------參數2:IntentFilter對象

五,12個例子:拍照啟動,耳機插入,電量電池低,電源斷開與接入,

牆紙改變,手機重啟,APK安裝與卸載,SD卡插入與拔出,

系統與區域改變的設置,內存不足與鎖屏解鎖,開機自啟 ,飛行模式設置,

(1)拍照啟動:Intent.ACTION_CAMERA_BUTTON

自定義廣播接收器TakePhotoReceiver:繼承BroadcastReceiver,重寫onReceive方法:

 

    //自定義拍照廣播接收器:
    class TakePhotoReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals(Intent.ACTION_CAMERA_BUTTON)){
                Toast.makeText(FourActivity.this , "檢測到拍照廣播接收器" , Toast.LENGTH_SHORT).show();
            }
        }
    }

在onCreat方法中,創建該接收器:

 

 

        TPreceiver  =   new TakePhotoReceiver();
然後在需要的監聽地方去實現:

 

 

                case R.id.startTake :
                    registerReceiver(TPreceiver , new IntentFilter(Intent.ACTION_CAMERA_BUTTON));
                    Toast.makeText(FourActivity.this , "拍照廣播已啟動" , Toast.LENGTH_SHORT).show();
                    break;
                case R.id.nostartTake :
                    if(TPreceiver != null){
                        unregisterReceiver(TPreceiver); //取消注冊
                        Toast.makeText(FourActivity.this , "拍照廣播已經取消" , Toast.LENGTH_SHORT).show();
                    }
                    break;

這裡不需要添加權限,,,

 

 

(2)耳機插入:耳機插入時需要關閉播放效果,開啟耳機模式

動作--------Intent.ACTION_HEADSET_PLUG

同理:

自定義廣播接收器:EarphoneInsertReceiver ,繼承BroadcastReceiver,重寫onReceive方法,代碼如下;

 

    //自定義拍照廣播接收器:
    class EarphoneInsertReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)){
                Toast.makeText(context, "檢測到耳機插入廣播" , Toast.LENGTH_SHORT).show();
            }
        }
    }
在onCreate方法中創建該接收器:

 

 

earphoneIR = new EarphoneInsertReceiver();
然後,在需要的地方,去實現和注冊:

 

 

registerReceiver(earphoneIR , new IntentFilter(Intent.ACTION_HEADSET_PLUG));
取消注冊:

 

 

 unregisterReceiver(earphoneIR );

取消注冊時只需要廣播接收器一個參數..

 

(3)到(11)的方法類似於上面就不粘貼代碼了:

(3)電量電池低:

Action----------Intent.ACTION_BATTERY_LOW

(4)電源斷開與接入:

斷開---------Intent.ACTION_POWER_DISCONNECTED

接入-----------Intent.ACTION_POWER_CONNECTED

(5)手機牆紙改變:

--------- Intent.ACTION_WALLPARER_CHANGED
(6)手機重啟:

-------- Intent.ACTION_REBOOT


(7)APK安裝與卸載:

安裝 ------------Intent.ACTION_PACKAGE_ADDED

卸載 ------------Intent.ACTION_PACKAGE_REMOVED
 

(8)SD開插入與拔出

插入------------Intent.ACTION_MEDIA_MOUNTED

拔出------------Intent.ACTION_MEDIA_EJECT

 

(9)系統設置與區域設置的改變

系統設置---------Intent.ACTION_CONFIGURATION_CHANGED

區域設置---------Intent.ACTION_LOCALE_CHANGED

(10)內存不足與鎖屏,解鎖

內存不足---------Intent.ACTION_DEVICE_STORAGE_LOW

鎖屏 --------------Intent.ACTION_SCREEN_OFF

解鎖-------------- Intent.ACTION_SCREEN_ON

(11)開機自啟:

-----------Intent.ACTION_BOOT_COMPLETED

這裡需要權限:

 

12)飛行模式設置:這裡有點不同,詳見代碼:

 

布局,兩個按鈕:分別是開啟飛行模式和關閉飛行模式:

 



主類中:用sendBroadcast來發送廣播,代碼如下:

 

 

public class MainActivity extends Activity {
	private Button btnStartFly , btnStopFly;//定義開啟與關閉飛行模式按鈕
	private ContentResolver cr;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		cr = getContentResolver();	//獲取
		findView();		//為控件綁定ID
		setListener();	//設置監聽
	}

	//為控件綁定ID
	private void findView() {
		btnStartFly = (Button) findViewById(R.id.btn_startflying);
		btnStopFly = (Button) findViewById(R.id.btn_stopflying);
	}

	// 設置監聽
	private void setListener() {
		btnStartFly.setOnClickListener(listener);
		btnStopFly.setOnClickListener(listener);
	}

	OnClickListener listener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btn_startflying:
				if (Settings.System.getString(cr,
						Settings.System.AIRPLANE_MODE_ON).equals("0")) {
					Log.e("AIRPLANE_MODE_ON", "0");
					// 獲取當前飛行模式狀態,返回的是String值0,或1.0為關閉飛行,1為開啟飛行
					// 如果關閉飛行,則打開飛行
					Settings.System.putString(cr,
							Settings.System.AIRPLANE_MODE_ON, "1");
					// 設置需要啟動的ACTION
					Intent intent = new Intent(
							Intent.ACTION_AIRPLANE_MODE_CHANGED).
							putExtra("state", true);;
					// 發送飛行廣播
					sendBroadcast(intent);
					Toast.makeText(MainActivity.this,
							"已開啟飛行模式",
							Toast.LENGTH_SHORT).show();
				}

				break;
			case R.id.btn_stopflying:
				if (Settings.System.getString(cr,
						Settings.System.AIRPLANE_MODE_ON).equals("1")) {
					Log.e("AIRPLANE_MODE_ON", "1");
					// 獲取當前飛行模式狀態,返回的是String值0,或1.0為關閉飛行,1為開啟飛行
					// 如果打開飛行,則關閉飛行
					Settings.System.putString(cr,
							Settings.System.AIRPLANE_MODE_ON, "0");
					// 設置需要啟動的ACTION
					Intent intent = new Intent(
							Intent.ACTION_AIRPLANE_MODE_CHANGED).
							putExtra("state", false);;
					// 發送飛行廣播
					sendBroadcast(intent);
					Toast.makeText(MainActivity.this, "已關閉飛行模式",
							Toast.LENGTH_SHORT).show();
				}
				break;
			}
		}
	};
}
然後添加權限:

 

 

  
就可以了

 

 

TWO --------- 服務:

一,基本知識:

(1)名字:Service

(2)理解:類似於Activity,有自己的生命周期,在後台運行
(3)用法:兩個步驟,創建子類,然後去AndroidManifest中配置

---------(配置該Service時:可通過來指定哪些Intent被啟動)

二,基本方法:

第一種:調用startService()時:

onCreate():第一次創建時調用

onStartCommand():每次用戶調用startService()時會調用

onDestroy():關閉服務前調用

第二種:調用bindService()時:

onCreate():第一次創建服務時調用

onBind():是Service子類必須實現的方法,返回一個IBinder對象

onUnbind():當服務上的所有客戶端斷開時調用
 

三,3個例子:定時任務,開車模式與夜間模式,音量控制

(1)定時任務:

布局:定義四個按鈕,定時發送 / 關閉 :廣播,服務

 




    

 

 

字符串:

 

    定時發送廣播
    定時啟動服務
    停止定時廣播
    停止定時服務

 

主類代碼:如下:

 

package testsdcard.com.maiyu.s07_01.activity;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import testsdcard.com.maiyu.s07_01.R;
import testsdcard.com.maiyu.s07_01.broadcast.ActionBroadCast;
import testsdcard.com.maiyu.s07_01.service.ActionService;

/**
 * Created by maiyu on 2016/7/23.
 */
public class SecondActivity extends Activity {
    private Button  BtnStartBC , BtnStartSR , BtnStopBC , BtnStopSR;  //定義啟動和停止:服務和廣播
    private Notification  baseNF ;      //定義通知對象
    private NotificationManager nm ;    //定義通知管理對象
    private AlarmManager am ;           //鬧鐘管理
    private PendingIntent   pi1 , pi2 ;  //定義延遲發送的請求

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        am  =   (AlarmManager)getSystemService(ALARM_SERVICE);      //獲取AlermManager服務
        nm  =   (NotificationManager)getSystemService(NOTIFICATION_SERVICE);    //獲取通知服務
        findView();     //為控件綁定id
        setListener();  //為控件設置監聽
    }

    //為各個控件設置監聽
    private void setListener() {
        BtnStartBC.setOnClickListener(mylistener);
        BtnStartSR.setOnClickListener(mylistener);
        BtnStopSR.setOnClickListener(mylistener);
        BtnStopBC.setOnClickListener(mylistener);
    }

    //自定義監聽器
    View.OnClickListener    mylistener  =   new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.StartBroadcast:   //開啟鬧鐘廣播
                    /**4個參數:
                     Context context, int requestCode, Intent intent, int flags
                     */
                    pi1 = PendingIntent.getBroadcast(SecondActivity.this, 0,
                            new Intent(SecondActivity.this, ActionBroadCast.class),
                            Intent.FILL_IN_ACTION); //得到延遲的PendingIntent
                    long  now = System.currentTimeMillis();
                    /**
                     * 4個參數:
                     * int type, long triggerAtMillis, long intervalMillis, PendingIntent operation
                     */
                    //設置重復鬧鐘
                    am.setInexactRepeating(AlarmManager.RTC_WAKEUP , now , 3000, pi1);

                    break;
                case R.id.StartService:
                    //獲取延遲PendingIntent
                    pi2     =   PendingIntent.getService(SecondActivity.this , 0 ,
                            new Intent(SecondActivity.this , ActionService.class) , Intent.FILL_IN_ACTION);
                    long    now1 = System.currentTimeMillis();
                    //設置重復鬧鐘
                    am.setInexactRepeating(AlarmManager.RTC_WAKEUP , now1 , 3000 , pi2);
                    break;
                case R.id.StopBroadcast:
                    am.cancel(pi1);     //取消延遲的PendingIntent
                    break;
                case R.id.StopService:
                    am.cancel(pi2);
                    break;
                default:
                    break;
            }
        }
    };

    //為控件綁定Id
    private void findView() {
        BtnStartBC      =   (Button)findViewById(R.id.StartBroadcast);
        BtnStartSR      =   (Button)findViewById(R.id.StartService);
        BtnStopBC       =   (Button)findViewById(R.id.StopBroadcast);
        BtnStopSR       =   (Button)findViewById(R.id.StopService);
    }
}

字符串:

 

 

    開啟行車模式
    關閉行車模式
    開啟夜間模式
    關閉夜間模式

 

自定義服務類:

 

package testsdcard.com.maiyu.s07_01.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * Created by maiyu on 2016/7/23.
 */
public class ActionService extends Service {
    private static int num = 0;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("ActionService" , "New Message ! " + num++);
    }
}

自定義廣播接收器:

 

 

package testsdcard.com.maiyu.s07_01.broadcast;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ActionBroadCast extends BroadcastReceiver{
    private static int  num = 0 ;
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("AciontBroadCast" ,"new message : " + num++ );
    }
}
這樣就行了,,,

 

(2)開啟行車模式和夜間模式:當開車時,需要開啟行車模式(電話會自動接入)

布局:同樣定義4個按鈕:開啟和關閉行車模式,開啟和關閉夜間模式

 




    

主類中去,實現:

 

----先調用服務:UiModeManager

 

uiModeManager   =   (UiModeManager)getSystemService(Context.UI_MODE_SERVICE);   //獲取系統UiModeManager服務
再去實現相關方法,

 

 

package testsdcard.com.maiyu.s07_01.activity;

import android.app.Activity;
import android.app.UiModeManager;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import testsdcard.com.maiyu.s07_01.R;

/**
 * Created by maiyu on 2016/7/23.
 */
public class SecondActivity extends Activity {
    private UiModeManager uiModeManager ;       //UiModeManager對象
    private Button BtnOpenDC , BtnCloseDC , BtnOpenN , BtnCloseN;       //開車模式和夜間模式

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        uiModeManager   =   (UiModeManager)getSystemService(Context.UI_MODE_SERVICE);   //獲取系統UiModeManager服務
        findView();     //為控件綁定id
        setListener();  //為控件設置監聽
    }

    //為各個控件設置監聽
    private void setListener() {
        //行車模式和夜間模式
        BtnOpenDC.setOnClickListener(mylistener);
        BtnCloseDC.setOnClickListener(mylistener);
        BtnOpenN.setOnClickListener(mylistener);
        BtnCloseN.setOnClickListener(mylistener);
    }

    //自定義監聽器
    View.OnClickListener    mylistener  =   new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.OpenDC:       //開車模式
                    uiModeManager.enableCarMode(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME);
                    Toast.makeText(SecondActivity.this , "已經開啟行車模式",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.CloseDC:      //關閉開車模式
                    uiModeManager.disableCarMode(UiModeManager.DISABLE_CAR_MODE_GO_HOME);
                    Toast.makeText(SecondActivity.this , "已經關閉行車模式",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.OpenN:        //開啟夜間模式,
                    uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_YES);
                    Toast.makeText(SecondActivity.this , "已經開啟夜間模式",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.CloseN:       //關閉夜間模式
                    uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
                    Toast.makeText(SecondActivity.this , "已經關閉夜間模式",Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };
    
    //為控件綁定Id
    private void findView() {
        //行車與夜間模式
        BtnOpenDC       =   (Button)findViewById(R.id.OpenDC);
        BtnCloseDC      =   (Button)findViewById(R.id.CloseDC);
        BtnOpenN        =   (Button)findViewById(R.id.OpenN);
        BtnCloseN       =   (Button)findViewById(R.id.CloseN);
    }
}

(3)音量控制:

 

布局:三個按鈕,當前音量,增大和減少:

 




    
字符串:

 

 

    當前音量
    增大音量
    減少音量

主類中:

 

先獲取音量管理的服務:

 

audioManager    =   (AudioManager)getSystemService(Context.AUDIO_SERVICE);      //獲取聲音管理
然後再去調用相關方法,具體代碼如下:

 

 

package testsdcard.com.maiyu.s07_01.activity;

import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import testsdcard.com.maiyu.s07_01.R;

public class SecondActivity extends Activity {
    private Button BtnCurrentV , BtnIncreaseV , BtnDeclineV;
    private AudioManager audioManager;      //聲音管理對象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        audioManager    =   (AudioManager)getSystemService(Context.AUDIO_SERVICE);      //獲取聲音管理
        findView();     //為控件綁定id
        setListener();  //為控件設置監聽
    }

    //為各個控件設置監聽
    private void setListener() {
        //聲音
        BtnCurrentV.setOnClickListener(mylistener);
        BtnIncreaseV.setOnClickListener(mylistener);
        BtnDeclineV.setOnClickListener(mylistener);
    }

    //自定義監聽器
    View.OnClickListener    mylistener  =   new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.CurrentV :    //當前音量
                    //分別得到當前的:通話音量,系統音量,音樂音量,提示聲音量
                    int   currentCall       =   audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
                    int   currentSystem     =   audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
                    int   currentMusic      =   audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                    int   currentTip        =   audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
                    Toast.makeText(SecondActivity.this , "當前通話音量:" + currentCall + "\n當前系統音量" + currentSystem
                            + "\n當前音樂音量:" + currentMusic + "\n當前提示音音量:" + currentTip ,Toast.LENGTH_SHORT).show();

                    break;
                case R.id.IncreaseV :
                    audioManager.adjustStreamVolume(AudioManager.STREAM_SYSTEM , AudioManager.ADJUST_RAISE ,
                            AudioManager.FX_FOCUS_NAVIGATION_UP);
                    break;
                case R.id.DeclineV :
                    audioManager.adjustStreamVolume(AudioManager.STREAM_SYSTEM ,AudioManager.ADJUST_LOWER ,
                            AudioManager.FX_FOCUS_NAVIGATION_UP);
                    break;
                default:
                    break;
            }
        }
    };
    
    //為控件綁定Id
    private void findView() {
        //聲音管理
        BtnCurrentV     =   (Button)findViewById(R.id.CurrentV);
        BtnIncreaseV    =   (Button)findViewById(R.id.IncreaseV);
        BtnDeclineV     =   (Button)findViewById(R.id.DeclineV);
    }
}
這樣就OK了,

 

這都只是簡單的測試......

待續........

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved