1. 程式人生 > >[安卓基礎]學習第七天

[安卓基礎]學習第七天

一、為什麼需要廣播接收者(broadcastReceiver)

1.有什麼樣的人員聽廣播 老人,計程車司機
2.聽廣播必須:電臺,收音機,調頻道
3.Android內部已經定義好了電臺,已經定義好了一些廣播事件,如外撥電話,簡訊到來等等
4.使用broadcastReceiver去接收系統定義好的這些事件
5.javame javase javaee
6.定義廣播接收者目的是為了方便安卓開發者開發

二、案例

2-1.案例——ip撥號器

360永久免費 瑞星 卡巴斯基

1.在清單檔案中配置receiver,並新增使用者許可權

<uses-permission
android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<application //...... <!-- 配置廣播接收者 --> <receiver android:name="com.elnui.day07_caseip.OutGoingCallReceiver"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL"
/>
</intent-filter> </receiver> </application>

2.新建一個類繼承BroadcastReceiver

public class OutGoingCallReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        // 獲取使用者輸入的ip號碼在config.xml檔案中
SharedPreferences sp = context.getSharedPreferences("config", 0); String number = sp.getString("ipnumber", ""); // 獲取當前撥打的電話 String num = getResultData(); // 在當前號碼前假17951 // 判斷當前號碼是不是長途號碼 if(num.startsWith("0")){ // 修改撥打的號碼 setResultData(number + num); } } }

3.getResultData()

Retrieve the current result data, as set by the previous receiver. Often this is null.

4.setResultData()

Change the current result data of this broadcast; 
only works with broadcasts sent through Context.sendOrderedBroadcast. 
This is an arbitrary string whose interpretation is up to the broadcaster. 

5.總結

  • BroadcastReceiver是一個抽象類,沒有上下文
public abstract class BroadcastReceiver{}
  • public void onReceive(Context context, Intent intent) {},該方法中的context就是上下文

2-2.案例——sd卡監聽器

1.onReceive()方法

- intent.getAction();    //獲取當前廣播的事件型別 
    Retrieve the general action to be performed, such as ACTION_VIEW. 
    The action describes the general way the rest of the information in the intent should be interpreted
        -- most importantly, what to do with the data returned by getData.

2.清單檔案配置

<receiver android:name="com.elnui.day07_casesd.SdcardStateReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_MOUNTED"/>
        <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
        <!-- 小細節,這裡必須配置data,約束型別叫file,因為sd裡面的資料型別是file -->
        <data android:scheme="file"/>
    </intent-filter>
</receiver>
說明:<intent-filter>下必須新增<data android:scheme="file"/>

3.程式碼

public class SdcardStateReceiver extends BroadcastReceiver{

    // 當SD卡狀態發生改變時呼叫
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String action = intent.getAction();
        if("android.intent.action.MEDIA_MOUNTED".equals(action)){
            System.out.println("SD卡掛載了。");
        }else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){
            System.out.println("SD卡掛載了。");
        }
    }
}

2-3.案例——簡訊監聽器

1.程式碼

public class SmsListerReceiver extends BroadcastReceiver {

    // 當簡訊到來的時候執行
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        System.out.println("Receive sms.............success!!!");

        // 獲取傳送者的號碼和內容
        Object []objects = (Object[]) intent.getExtras().get("pdus");
        for (Object obj : objects) {
            // 獲取SmsMessage的例項
            SmsMessage smg = SmsMessage.createFromPdu((byte[])obj);

            String messageBody = smg.getMessageBody();
            String messageAddr = smg.getOriginatingAddress();
            System.out.println("___Address:" + messageAddr + ":" + messageBody);
        }
    }
}

2.清單檔案配置

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

<receiver android:name="com.elnui.day07_casesms.SmsListerReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

3.類SmsManager

  • pdu也是封裝簡訊的一種格式

4.類SmsMessage (android.telephony包下)

通過這個API拿到簡訊的資訊
通過靜態的createFromPdu()即可獲得例項

- getOriginatingAddress(); // 獲取號碼
- getMessageBody(); // 獲取內容

2-4.解除安裝安裝

1.程式碼

public class StatusReceiver extends BroadcastReceiver {

    // 當有新的應用被安裝或者解除安裝時呼叫
    @Override
    public void onReceive(Context context, Intent intent) {
        // 獲取當前廣播的型別
        String action = intent.getAction();
        if("android.intent.action.PACKAGE_INSTALL".equals(action)){
            System.out.println("___PACKAGE_INSTALL");
        }else if("android.intent.action.PACKAGE_REMOVED".equals(action)){
            System.out.println("___PACKAGE_REMOVED");
        }else if("android.intent.action.PACKAGE_ADDED".equals(action)){
            System.out.println("___PACKAGE_ADDED" + intent.getData());
        }
    }
}

2.清單檔案配置(此處得配置data)

<receiver android:name="com.elnui.day07_caseinstall.StatusReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_INSTALL"/>
        <action android:name="android.intent.action.PACKAGE_REMOVED"/>
        <action android:name="android.intent.action.PACKAGE_ADDED"/>

        <!-- 小細節:還需配置一個data -->
        <data android:scheme="package"/>
    </intent-filter>
</receiver>
android.intent.action.PACKAGE_INSTALL是谷歌工程師預留的字元段

3.getData()

intent.getData()可以拿到包名

2-5.開機啟動

1.程式碼

public class BootReceiver extends BroadcastReceiver {

    // 當手機重啟時呼叫
    @Override
    public void onReceive(Context context, Intent intent) {

        // 開啟Activity
        Intent x  = new Intent(context,MainActivity.class);

        // 新增標記
        x.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        context.startActivity(x);
    }
}

2.清單檔案配置

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application>
    <receiver android:name="com.elnui.day07_reboot.BootReceiver">
        <intent-filter >
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>
</application>

3.注意

不能在廣播接收者裡面開啟Activity,需要新增一個任務棧的標記
開機啟動一定要加RECEIVE_BOOT_COMPLETED許可權
// 新增標記
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

4.補充

在頁面按返回鍵會呼叫onBackPressed()
    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub
        super.onBackPressed();
    }

三、不同版本廣播的特點

四、有序廣播和無序廣播

4-1.無序廣播

比如新聞聯播,到7點就播

1.廣播發送者

程式碼

    public void click1(View v){
        Intent intent = new Intent();
        intent.setAction("com.elnui.custom");
        intent.putExtra("name", "準時開播");
        sendBroadcast(intent);
    }

2.廣播接收者

程式碼

public class wuxuRecelver extends BroadcastReceiver {

    // 當接收到自定義的廣播時執行
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String str = intent.getStringExtra("name");

        Toast.makeText(context, str, 1).show();
    }
}

清單檔案

        <receiver android:name="com.elnui.day07_recelve.wuxuRecelver">
            <intent-filter >
                <action android:name="com.elnui.custom"/>
            </intent-filter>
        </receiver>

4-2.有序廣播

類似中央傳送紅標頭檔案,按照優先順序進行接收

1.傳送者

程式碼

    // 點擊發送有序廣播
    public void click1(View v){
        Intent intent = new Intent();
        intent.setAction("com.elnui.sendOrderBroadcast");

        /**
         * intent 意圖
         * receiverPermission 接收的許可權
         * resultReceiver 最終的recriver
         * scheduler handler
         * initialCode 初始碼
         * initialData 初始化資料
         * initialExtras 額外資料
         * 
         * */
        sendOrderedBroadcast(intent, null, new FinalReceiver(), null, 1, "有序廣播-1000", null);
    }

2.接收者(以其中一個為例)

程式碼

public class CountryReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String str = getResultData();

        Toast.makeText(context, "鄉_>>"+str, 1).show();

        setResultData("有序廣播-100");

        // 終止廣播
        //abortBroadcast();
    }
}

清單檔案

<!-- 省長優先順序 最高優先順序-->
        <receiver android:name="com.elnui.day07_receiver.ProvienceReceiver">
            <intent-filter android:priority="1000">
                <action android:name="com.elnui.sendOrderBroadcast"/>
            </intent-filter>
        </receiver>

        <!-- 市長優先順序 -->
        <receiver android:name="com.elnui.day07_receiver.CityReceiver">
            <intent-filter android:priority="100">
                <action android:name="com.elnui.sendOrderBroadcast"/>
            </intent-filter>
        </receiver>

        <!-- 鄉長優先順序 -->
        <receiver android:name="com.elnui.day07_receiver.CountryReceiver">
            <intent-filter android:priority="10">
                <action android:name="com.elnui.sendOrderBroadcast"/>
            </intent-filter>
        </receiver>

        <!-- 村民優先順序 -->
        <receiver android:name="com.elnui.day07_receiver.PeopleReceiver">
            <intent-filter android:priority="1">
                <action android:name="com.elnui.sendOrderBroadcast"/>
            </intent-filter>
        </receiver>

3.最終接收者

public class FinalReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String str = getResultData();

        Toast.makeText(context, "報告_>>"+str, 1).show();
    }
}
說明:最終接收者無需再清單檔案中配置

4.abortBroadcast()

終止廣播

5.有序和無序廣播的區別

  1. 無序廣播不可以被終止,呼叫abortBroadcast()會在日誌檔案中列印警告
  2. 無序廣播資料不可以修改

五、特殊廣播接收者

操作特別頻繁的廣播事件,比如螢幕的鎖屏和解鎖,電池電量的變化。這種事件的廣播在清單檔案註冊無效

5-1.註冊廣播接收者的兩種方式

1. 使用程式碼動態註冊 Context.registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

public class MainActivity extends Activity {

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

        // 動態去註冊廣播接收者
        ScreenReceiver sc = new ScreenReceiver();
        /*
         *      <action android:name="android.intent.action.SCREEN_OFF"/>
                <action android:name="android.intent.action.SCREEN_ON"/>
         * */
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.intent.action.SCREEN_OFF");
        intentFilter.addAction("android.intent.action.SCREEN_ON");
        registerReceiver(sc, intentFilter);
    }
}

04-16 10:24:40.719: E/ActivityThread(2270): android.app.IntentReceiverLeaked:
Activity com.elnui.day07_broadcast.MainActivity has leaked IntentReceiver [email protected]
that was originally registered here. Are you missing a call to unregisterReceiver()?

注意,當Activity銷燬的時候,要取消註冊廣播接收者unregisterReceiver()

2. 在清單檔案通過receiver節點靜態註冊

六、樣式和主題

6-1.樣式

樣式的作用一般在控制元件上,樣式的作用範圍比較窄

6-2.主題

主題一般作用在Activity或者Application節點下,作用範圍相抵較大

6-3.二者定義的方式一樣

七、國際化

i18n
在res目錄下建立不同國家語言環境的目錄即可,如values-ch,values-en..

八、常見對話方塊

8-1.Toast

8-2.普通對話方塊

public void click1(View v){
        // 通過Builder構建器來構造
        AlertDialog.Builder builder = new Builder(this);

        builder.setTitle("警告"); // 標題
        builder.setMessage("世界上最遙遠的距離是沒有網路");   //內容
        builder.setPositiveButton("確定", new OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                System.out.println("___點選了確定按鈕");
            }
        }); //
        builder.setNegativeButton("取消", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                System.out.println("___點選了取消按鈕");
            }
        }); //
        builder.show();
    }

8-3.單選對話方塊

    // 點選,彈出一個單選對話方塊
    public void click2(View v){
        // 通過Builder構建器來構造
        AlertDialog.Builder builder = new Builder(this);

        builder.setTitle("請選擇課程");
        items = new String[] {"安卓","IOS","C","C++","C#"};
        builder.setSingleChoiceItems(items, 0, new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                System.out.println("___點選了單選按鈕");

                // 取出選擇的內容
                String str = items[which];
                Toast.makeText(getApplicationContext(), str, 1).show();
                // 關閉單選框
                dialog.dismiss();
            }
        });
        builder.show();
    }

8-4.多選對話方塊

    // 點選,彈出一個多選對話方塊
    public void click3(View v){
        // 通過Builder構建器來構造
        AlertDialog.Builder builder = new Builder(this);
        builder.setTitle("請選擇水果");
        final String frults[] = new String[] {"蘋果","西瓜","桔子","榴蓮","哈密瓜"};
        checkedItems = new boolean[] {true,false,false,false,false};
        builder.setMultiChoiceItems(frults, checkedItems, new OnMultiChoiceClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                // TODO Auto-generated method stub

            }
        });
        builder.setPositiveButton("確定", new OnClickListener() {
            StringBuffer sb = new StringBuffer();
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                // 把選中的條目資料取出來
                for (int i = 0; i < checkedItems.length; i++) {
                    if(checkedItems[i]){
                        String frult = frults[i];
                        sb.append(frult + "-");
                    }
                }
                Toast.makeText(getApplicationContext(), sb.toString(), 1).show();

                // 關閉單選框
                dialog.dismiss();
            }
        });
        builder.show();
    }

8-5.進度條對話方塊

PrograssBar

與進度相關的控制元件,都可以在子執行緒更新UI

    // 點選,彈出進度條對話方塊
    public void click4(View v){
        final ProgressDialog dialog = new ProgressDialog(this);
        dialog.setTitle("正在玩命載入。。。。");  

        // 設定進度條樣式
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

        // 執行緒
        new Thread(){
            @Override
            public void run() {
                // TODO Auto-generated method stub

                // 設定最大進度
                dialog.setMax(100);
                for (int i = 0; i < 100; i++) {
                    // 設定進度
                    dialog.setProgress(i);

                    // 延時
                    SystemClock.sleep(50);
                    if(dialog.getProgress() == 99){
                        dialog.dismiss();
                    }
                }
                super.run();
            }
        }.start();;

        // 最後show()
        dialog.show();
    }

九、兩種上下文的區別

9-1.getApplicationContext()

返回的物件是Context物件【父類】

9-2.this

最終繼承Context物件【子類】
注意: 對話方塊只能用this

十、安卓中的動畫

10-1.幀動畫

  • 載入一系列的圖片資源
  • The AnimationDrawable class is the basis for Drawable animations.
    res/drawable/my_animation.xml
  • 在android2.3之前的手機上需要用相容性寫法,使用執行緒
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/girl_1" android:duration="200" />
    <item android:drawable="@drawable/girl_2" android:duration="200" />
    <item android:drawable="@drawable/girl_3" android:duration="200" />
    <item android:drawable="@drawable/girl_4" android:duration="200" />
    <item android:drawable="@drawable/girl_5" android:duration="200" />
    <item android:drawable="@drawable/girl_6" android:duration="200" />
    <item android:drawable="@drawable/girl_7" android:duration="200" />
    <item android:drawable="@drawable/girl_8" android:duration="200" />
    <item android:drawable="@drawable/girl_9" android:duration="200" />
    <item android:drawable="@drawable/girl_10" android:duration="200" />
    <item android:drawable="@drawable/girl_11" android:duration="200" />
</animation-list>

onCreat()

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView rocketImage  = (ImageView)findViewById(R.id.iv);

        // 設定背景資源
        rocketImage.setBackgroundResource(R.drawable.my_animation);

        // 獲取AnimationDraw型別
        AnimationDrawable rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

        // 開啟動畫
        rocketAnimation.start();
    }

10-2.View動畫(補間動畫)

10-3.屬性動畫

筆記:

筆記一:Android TextView 文字居中

兩種方法

  • 在xml檔案設定:Android:gravity=”center”
  • 在程式中設定:m_TxtTitle.setGravity(Gravity.CENTER);
android:gravity和android:layout_gravity的區別在於前者對控制元件內部操作,後者是對整個控制元件操作

相關推薦

[基礎]學習

一、為什麼需要廣播接收者(broadcastReceiver) 1.有什麼樣的人員聽廣播 老人,計程車司機 2.聽廣播必須:電臺,收音機,調頻道 3.Android內部已經定義好了電臺,已經定義好了一些廣播事件,如外撥電話,簡訊到來等等 4.使用broadca

[基礎]學習九天

一、為什麼需要內容提供者 1-1.回憶定義資料庫 新建一個類繼承SQLiteOpenHelper public class MyOpenHelper extends SQLiteOpenHelper { public MyOpenHe

python學習 基礎數據類型補充 深淺copy 集合 關鍵字後面加可叠代對象

div ext split() 不可變 append 鍵值對 port [] 賦值 在基礎數據類型中可能遇到的坑:   元組:     tuple1=(1) 的數據類型是int , tuple2=(‘alex‘)的數據類型是str 等     tuple1=(1,) 和 t

逆向學習筆記 -- 少月團隊:35的收穫

七月六號到今天八月十九號,我跟七少月團隊學習35天了(大部分時間都是研究自己渴望有的東西),今晚就抽出玩遊戲的時間,寫一篇文章分享一下加入七少月團隊35天的經歷以及收穫。 在我沒有加入七少月團隊

實訓--基於HttpClient來完畢數據在server和設備間的交互。

-i post aries 補充 addition odi tracking -m 回調 上午:老師首先回想了昨天作業。 首先在安卓project中的TOOLS文件裏,解析字節流那裏,不用改變。而是把server端的編碼方式變為UTF-8,然後將在安卓project

python基礎學習

py 學習 6.1內置函數 6.1.1 filter函數 6.1.2 map函數 6.1.3 reduce函數 6.1.1:filter (函數名字, 序列) 過濾器對象 filter()函數是 Python 內置的另一個有用的高階函數,filter()函數接收一個函數 f

百度前端學院-基礎學院-

相同 自己的 http 視口 you css align 其他 知識點 第五天到第六天的內容沒有記筆記,不好不好。 第七天到第八天的學習目標是:學習布局的各種方式。主要包含position相關和Flexbox相關。 知識點: 1、默認情況下,塊級元素的內容寬度是其父元素的寬

liunxC學習

今天是一天的程式編寫練習(大部分是抄寫,練習格式,熟悉之前學到的一些指令和函式) 一、用“*”列印一個半徑為10 的圓 第一種畫圓的方法 #include <stdio.h> #include <math.h> int main() { doub

2018-11-22 python學習

#列表型別 ======================================基本使用====================================== 1、用途:記錄多個值(同種屬性) 2、定義方式:在[]內用逗號分隔開多個任意型別的值 l=['a','b','c'] #l=li

linux學習 (Linux就該這麽學)

屬性 com hat sat acl權限 img 相關信息 http lin 今天講了chmod (權限 設置)和 chown(屬性 設置),特殊權限:SUID u+s 數字法是4 x=s - = S,SGID g+s 數字法是2 x=s -=S,SBIT o+t x

linux學習 (Linux就該這麼學)

今天講了chmod (許可權 設定)和 chown(屬性 設定),特殊許可權:SUID u+s 數字法是4  x=s  - = S,SGID g+s 數字法是2 x=s -=S,SBIT o+t  x=t -=T數字法是1 是保護位,  還有檔案的隱藏屬性 chatt

Linux學習

今天學習主要內容:             1、檔案的特殊許可權(SUID:讓程式執行者,臨時獲取程式所有者的身份                   &n

Java基礎複習——面向物件思想、類、物件、封裝、構造方法、JavaBean

目錄 一 面向物件思想 1.概述 2.面向物件的三大特徵          3.類和物件 4.類和物件的關係 5.類的定義 6.成員變數和區域性變數 7.物件的使用格式 8.物件記憶體圖 二.封裝

python自動化運維學習--函式的變數和返回值

函式的變數 區域性變數和全域性變數 python中的任何變數都有特定的作用域 在函式中定義的變數一般只能在該函式內部使用,這些只能在程式特定部分使用的變數就叫做區域性變數 在一個檔案頂部定義的變數可以供檔案中的任何函式呼叫,這些可以為整個程式所使用的變數稱為全域性變數

自測試題——

第六期試題答案:1.B 2.B 3.AB 4.D 5.C 6.C 7.AB 8.D 9.D 10.答:IPC是內部程序通訊的簡稱, 是共享"命名管道"的資源。Android中的IPC機制是為了讓Activity和Service之間可以隨時的進行互動,故在Android中該

swift學習 ?和!

Swift語言使用var定義變數,但和別的語言不同,Swift裡不會自動給變數賦初始值,也就是說變數不會有預設值,所以要求使用變數之前必須要對其初始化。如果在使用變數之前不進行初始化就會報錯: var stringValue : String  //error: variable 'stringValue'

STM32學習--串列埠除錯助手沒弄懂

啊啊 啊..今天真的好沮喪。調程式碼足足調了一晚上,不知道什麼原因工程就是錯,最後好不容易啊,在主函式加了個#include "stm32f10x_lib.h"就好使了,真不知道為什麼。然後隨即而來的又是一通打擊,什麼破串列埠除錯助手啊,就是不給我出字啊,simulator

Oracle學習

高階查詢1.分組查詢①概念分組函式作用於一組資料,並對一組資料返回一個值。②分組函式的使用分組函式avg()、sum()、min()、max()、count()、wm_concat():行轉列select avg(sal),sum(sal)from emp;select ma

Java學習

類成員(static成員): 當使用例項來訪問類成員時,系統底層依然是委託該類來訪問類成員。因此,即便該類例項為null,她依然可以訪問所屬類的類成員。 例如: package lesson5; class L5 { public static void main(S

python基礎自學

變數進階 0.1變數的引用 變數和資料都是儲存在記憶體中的 在python中函式的引數傳遞以及返回值都是靠引用傳遞的 1.1引用的概念 變數和資料是分開儲存的 資料儲存在記憶體中的一個位置 變數中儲存著資料在記憶體中的地址 變數中記錄資料