1. 程式人生 > >九圖 螢幕適配 廣播 有序廣播無序廣播(2018.5.21)

九圖 螢幕適配 廣播 有序廣播無序廣播(2018.5.21)

螢幕適配:
儘量用相對佈局和線性佈局
最好不要用相對佈局
為了更好地適配我們用九圖 畫圖

列如:480x320 和 320x240


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="@dimen/x160"
android:layout_height="wrap_content"
android:text="姓名"
android:textSize="20sp"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"

        />
</LinearLayout>
<Button 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="儲存"
   android:background="@drawable/img1"
    android:layout_gravity="center_horizontal"
    />
 <ImageView 
    android:layout_width="match_parent"
    android:layout_height
="match_parent" android:background="@drawable/img2" />

</LinearLayout>

···
320x240 的程式碼
···
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >

<TextView
    android:layout_width="@dimen/x160"
    android:layout_height="wrap_content"
    android:text="姓名"
    android:textSize="20sp" 
    android:background="#00ff00"
    />

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="儲存" 
    android:background="@drawable/img1"
    />
<ImageView 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/img2"
    
    />

</LinearLayout>


————————————————————————————————————————————————————————

手機螢幕分類和畫素密度的對應關係:

點九 自動拉伸圖:



————————————————————————————————————————————————————————

總結:
1、 IP撥號器

  1. 寫一個類繼承BroadcastReceiver,重寫onReceive方法

  2. 清單檔案中註冊receiver節點,通過intent-filter指定當前廣播接收者要處理的廣播事件

2、 SD卡狀態監聽

  1. 需要監聽掛載和解除安裝的action

  2. SD卡狀態變化的廣播還需要加一個data,scheme是file,否則收不到廣播

  3. 同一個廣播接收者接收了多個廣播事件,可以通過action來區分

3、 簡訊監聽

1.需要監聽的action:

<action android:name="android.provider.Telephony.SMS_RECEIVED"/>

廣播接收者按例:
1.解除安裝安裝
2.開機啟動

***應用安裝解除安裝的廣播************
建立一個類
···
//應用安裝解除安裝的廣播接收器
public class AppInstall extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {

String action = intent.getAction();
//獲取應用的包名
Uri data=intent.getData();

if ("android.intent.action.PACKAGE_ADDED".equals(action)) {
Log.e("TAG", "install----->" +data);
} else if("android.intent.action.PACKAGE_REMOVED".equals(action)) {
Log.e("TAG", "removed---->" +data);
}
}

}

···
清單檔案註冊:
···
<receiver android:name=".AppInstall">
<intent-filter >
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
···
************開機*********

···
//開機啟動的廣播接收者
public class BootReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
         Log.e("TAG", "機器開機了")  ;   
         Intent intent2 = new Intent(context,MainActivity.class);
         //指定任務棧   現在是在廣播接收者中建立一個Activity
         //當前應用沒有任何Activity執行  所以不在一個任務棧
         //需要通過指定一個Flags 在建立Activity的同時建立任務棧
         intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         
         context.startActivity(intent2);
         
         
}

}

···
在****MainActivity**************
···
public class MainActivity extends Activity {
EditText et_code;
BroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_code=(EditText) findViewById(R.id.et_code);

     receiver=new CodeRecerive();
     
    IntentFilter filter=new IntentFilter();
    filter.addAction("com.krr.getcode");
    registerReceiver(receiver, filter);
}
//遮蔽返回鍵
@Override
public void onBackPressed() {
    
}
private class CodeRecerive extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        String code=intent.getStringExtra("code");
        et_code.setText(code);
        
    }
    
}
@Override
    protected void onDestroy() {
    unregisterReceiver(receiver);
    }

}

···

同樣在清單檔案裡註冊:
···
<receiver android:name=".BootReceiver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>

        </intent-filter>
    </receiver>

···
接收開機廣播的許可權
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

開機廣播不是點選圖示開啟Activtiy
這時不會建立任務棧 需要我們自己建立任務棧
Intent i =new Intent ();
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

遮蔽返回鍵 在Activity中
重寫onBackPressed()方法


————————————————————————————————————————————————————————

1、 傳送無序廣播:建立Intent,設定action,通過sendBroadcast(intent)就可以把廣播發出去,當前的裝置上只要有廣播接收者註冊了相同的action,就可以收到廣播,並且在發廣播的時候,可以通過Intent傳遞資料

2、接收無序廣播:註冊廣播接收者,指定對應的action,就可以收到這個廣播
接收的順序 是否可以中斷 傳送的方法
有序廣播 可以通過priority設定接收順序 abortBroadcast()可以中斷 sendOrderedBroadcast()
無序廣播 大家一起收到 不可以中斷 sendBroadcast()

3、如何區分有序廣播和無序廣播?

接收到廣播之後在onReceive方法中呼叫abortBroadcast()方法,如果沒有異常說明是有序廣播,如果報BroadcastReceiver trying to return result during a non-ordered broadcast異常說明是無序廣播

無序廣播


建立一個傳送廣播專案和接收廣播專案
在傳送廣播專案裡首先定義佈局:
佈局:
<Button

    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="傳送廣播" 
    android:onClick="send"
    />

MainActivity 
···
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
public void send(View v){
    Intent intent = new Intent();
    intent.setAction("com.krr.broadcast");
    intent.putExtra("key", "Hello");
    sendBroadcast(intent);
    
}

}
···
接收廣播
首先建立一個類
···
//接受自定義廣播
public class CustomRecevier extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
     Log.e("TAG", "接受廣播"+intent.getStringExtra("key"));     
}

}

···
廣播接收器需要在清單檔案裡註冊的

清單檔案
···
<receiver android:name=".CustomRecevier">
<intent-filter >
<action android:name="com.krr.broadcast"/>
</intent-filter>
</receiver>

···



————————————————————————————————————————————————————————

有序傳送廣播
首先建立一個傳送專案和接收專案

在佈局中
···
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發廣播"
android:onClick="send"
/>
···

MainActivity中
···
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
public void send(View v){
    Intent intent = new Intent();//通過intent攜帶資料
    intent.setAction("com.krr.sendrice");
    //收到廣播時需要的許可權
    String receiverPermission=null;
    //作為最終的廣播接收者
    BroadcastReceiver resultReceiver =null;
    //處理最終的廣播接收者用到Handler 如果傳null會在主執行緒處理
    Handler scheduler=null;
    //初始化資料
    String initialData="每人100斤";
    
    sendOrderedBroadcast(intent, receiverPermission, 
resultReceiver, scheduler, Activity.RESULT_OK, 
   initialData, null);//傳送有序廣播
    
}

}

···

有序接收者   我們需要建立多個接收者看誰先誰後
這裡我建立3個

程式碼如下:
//州
public class StateRecevice extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    String resultData=getResultData();//獲取資料
    Toast.makeText(context, resultData, Toast.LENGTH_SHORT).show();
    setResultData("現在每人60斤");
//  abortBroadcast();//終止廣播繼續傳送   只有有序廣播可以中斷
    
}

}

第2個   接收者
···
//市
public class CityRecevice extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    String resultData=getResultData();//獲取資料
    Toast.makeText(context, resultData, Toast.LENGTH_SHORT).show();
    setResultData("現在每人40斤");
    
}

}

···
第3個
···
//縣
public class TownRecevice extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    String resultData=getResultData();//獲取資料
    Toast.makeText(context, resultData, Toast.LENGTH_SHORT).show();
    setResultData("免除個人所得稅");
    
}

}

···
都在清單檔案裡註冊
···
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <receiver android:name=".StateRecevice">
        <intent-filter android:priority="1000" >
            <action android:name="com.krr.sendrice"/>
        </intent-filter>
    </receiver>
    <receiver android:name=".CityRecevice">
        <intent-filter android:priority="800" >
            <action android:name="com.krr.sendrice"/>
        </intent-filter>
    </receiver>
    <receiver android:name=".TownRecevice">
        <intent-filter android:priority="500" >
            <action android:name="com.krr.sendrice"/>
        </intent-filter>
    </receiver>
</application>


有序廣播 優先順序排列:
優先順序高的有權中斷 :
呼叫abortBroadcast();
方法
只有有序廣播可以中斷
有序廣播的resultReceiver 作為最後的廣播接收者
我們在傳送廣播中建立一個類Final 不需要清單檔案註冊 需要在MainActivity 中 new出來
···
//欽差大臣
public class Final extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
      String resultData =getResultData();
      
//  Toast.makeText(context, "final:", + resultData,Toast.LENGTH_SHORT).show();
}

}

···
final最後執行