編輯:關於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(); } }
三,廣播的分類:
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(); } } }
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時:可通過
二,基本方法:
第一種:調用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); } }
布局:三個按鈕,當前音量,增大和減少:
字符串:
當前音量 增大音量 減少音量
先獲取音量管理的服務:
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了,
這都只是簡單的測試......
待續........
閒來無事,做了一個簡單的抽獎轉盤的ui實現,供大家參考package com.microchange.lucky; import android.content.Con
DrawLayout這個自定義的空間很常見,qq,網易新聞,知乎等等,都有這種效果,那這種效果是怎樣實現的呢?本篇博客將帶你來怎樣實現它。廢話不多說,先來看一下 效果首先
Android系統 小米,三星,索尼手機發送桌面快鍵提醒數字圖標,在Android系統中,眾所周知不支持BadgeNumber,雖然第三方控件BadgeView可以實現應
最近比較閒,公司項目更換後台,於是自己來研究微信支付和支付寶支付,把自己學習的過程寫下來,以備以後查看。注:要集成微信支付和支付寶功能,必須要有以下幾個配置信息,而這寫信