Computer >> คอมพิวเตอร์ >  >> ระบบ >> Android

เครื่องรับสัญญาณออกอากาศสำหรับผู้เริ่มต้น

สมมติว่าคุณมีแอปพลิเคชันที่ขึ้นอยู่กับการเชื่อมต่ออินเทอร์เน็ตที่เสถียร คุณต้องการให้แอปพลิเคชันของคุณได้รับการแจ้งเตือนเมื่อการเชื่อมต่ออินเทอร์เน็ตมีการเปลี่ยนแปลง คุณทำอย่างนั้นได้อย่างไร? วิธีแก้ปัญหาที่เป็นไปได้คือบริการที่ตรวจสอบการเชื่อมต่ออินเทอร์เน็ตเสมอ การใช้งานนี้ไม่ดีด้วยเหตุผลหลายประการ ดังนั้นเราจะไม่พิจารณาถึงเรื่องนี้ วิธีแก้ปัญหานี้คือ Broadcast Receiver และมันจะรับฟังการเปลี่ยนแปลงที่คุณบอกให้ทำ ผู้รับการออกอากาศจะได้รับแจ้งการออกอากาศเสมอ โดยไม่คำนึงถึงสถานะของแอปพลิเคชันของคุณ ไม่สำคัญว่าแอปพลิเคชันของคุณกำลังทำงานอยู่ในพื้นหลังหรือไม่ทำงานเลย

พื้นหลัง

เครื่องรับสัญญาณออกอากาศเป็นส่วนประกอบในแอปพลิเคชัน Android ของคุณที่รับฟังข้อความออกอากาศ (หรือเหตุการณ์) จากช่องทางต่างๆ:

  • จากแอปพลิเคชันอื่น
  • จากระบบเอง
  • จากใบสมัครของคุณ

หมายความว่าพวกเขาถูกเรียกใช้เมื่อมีการกระทำบางอย่างเกิดขึ้นที่พวกเขาได้รับการตั้งโปรแกรมให้ฟัง (IE, การออกอากาศ)

การออกอากาศเป็นเพียงข้อความที่อยู่ภายในวัตถุเจตนา การออกอากาศอาจเป็นได้ทั้งโดยปริยายหรือโจ่งแจ้ง

  • การออกอากาศโดยนัย เป็นโปรแกรมที่ไม่ได้กำหนดเป้าหมายแอปพลิเคชันของคุณโดยเฉพาะ ดังนั้นจึงไม่ใช่เฉพาะแอปพลิเคชันของคุณ ในการลงทะเบียน คุณต้องใช้ IntentFilter และประกาศในรายการของคุณ คุณต้องทำทั้งหมดนี้เนื่องจากระบบปฏิบัติการ Android จะตรวจสอบตัวกรองความตั้งใจที่ประกาศไว้ทั้งหมดในรายการของคุณและดูว่ามีรายการที่ตรงกันหรือไม่ เนื่องจากลักษณะการทำงานนี้ การออกอากาศโดยนัยจึงไม่มีแอตทริบิวต์เป้าหมาย ตัวอย่างสำหรับการออกอากาศโดยนัยคือการกระทำของข้อความ SMS ที่เข้ามา
  • ออกอากาศอย่างโจ่งแจ้ง เป็นเป้าหมายเฉพาะสำหรับแอปพลิเคชันของคุณบนส่วนประกอบที่ทราบล่วงหน้า สิ่งนี้เกิดขึ้นเนื่องจากแอตทริบิวต์เป้าหมายที่มีชื่อแพ็คเกจของแอปพลิเคชันหรือชื่อคลาสส่วนประกอบ

มีสองวิธีในการประกาศผู้รับ:

  1. โดยการประกาศในไฟล์ AndroidManifest.xml ของคุณด้วยแท็ก (เรียกอีกอย่างว่าสแตติก)
<receiver android:name=".YourBrodcastReceiverClass"  android:exported="true">
    <intent-filter>
        <!-- The actions you wish to listen to, below is an example -->
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>
AndroidManifest.xml

คุณจะสังเกตเห็นว่าเครื่องรับสัญญาณออกอากาศที่ประกาศข้างต้นมีคุณสมบัติ exported=”true” . คุณลักษณะนี้บอกผู้รับว่าสามารถรับการออกอากาศจากนอกขอบเขตของแอปพลิเคชันได้

2. หรือแบบไดนามิกโดยการลงทะเบียนอินสแตนซ์กับ registerReceiver (เรียกว่า Context Register)

public abstract Intent registerReceiver (BroadcastReceiver receiver, 
                IntentFilter filter);

การนำไปใช้

ในการสร้างเครื่องรับการออกอากาศของคุณเอง ก่อนอื่นคุณต้องขยายคลาสหลักของ BroadcastReceiver และแทนที่วิธีการบังคับ onReceive:

public void onReceive(Context context, Intent intent) {
    //Implement your logic here
 }

นำทั้งหมดมารวมกันให้ผลตอบแทน:

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        StringBuilder sb = new StringBuilder();
        sb.append("Action: " + intent.getAction() + "\n");
        sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
        String log = sb.toString();
        Toast.makeText(context, log, Toast.LENGTH_LONG).show();

    }
}
MyBroadcastReceiver.java
⚠️เมธอด onReceive ทำงานบนเธรดหลัก และด้วยเหตุนี้ การดำเนินการจึงควรสั้น

หากดำเนินการกระบวนการที่ยาวนาน ระบบอาจฆ่ากระบวนการหลังจากที่เมธอดกลับมา เพื่อหลีกเลี่ยงปัญหานี้ ให้ลองใช้ goAsync หรือกำหนดเวลางาน คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการกำหนดเวลางานได้ที่ด้านล่างของบทความนี้

ตัวอย่างการลงทะเบียนแบบไดนามิก

ในการลงทะเบียนผู้รับด้วยบริบท ก่อนอื่นคุณต้องสร้างอินสแตนซ์ของผู้รับการออกอากาศของคุณ:

BroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();

จากนั้น คุณสามารถลงทะเบียนได้ขึ้นอยู่กับบริบทเฉพาะที่คุณต้องการ:

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
this.registerReceiver(myBroadcastReceiver, filter);
พารามิเตอร์แรกสำหรับ IntentFilter คือสตริงที่แสดงถึงการกระทำ

อย่าลืมยกเลิกการลงทะเบียนเครื่องรับสัญญาณออกอากาศเมื่อไม่ต้องการใช้อีกต่อไป

@Override
protected void onStop() {
  super.onStop();
  unregisterReceiver(myBroadcastReceiver);
}

การแพร่ภาพเหตุการณ์

เบื้องหลังการออกอากาศข้อความจากแอปพลิเคชันของคุณคือการอนุญาตให้แอปพลิเคชันของคุณตอบสนองต่อเหตุการณ์ที่เกิดขึ้นภายในแอปพลิเคชัน ลองนึกถึงสถานการณ์ที่ผู้ใช้ดำเนินการบางอย่างในส่วนหนึ่งของโค้ด และด้วยเหตุนี้ คุณจึงต้องการดำเนินการตรรกะอื่นๆ ที่คุณมีในที่อื่น

มีสามวิธีในการส่งการออกอากาศ:

  1. sendOrderedBroadcast วิธีตรวจสอบให้แน่ใจว่าได้ส่งการออกอากาศไปยังเครื่องรับเพียงเครื่องเดียวในแต่ละครั้ง ในทางกลับกัน การออกอากาศแต่ละครั้งสามารถส่งผ่านข้อมูลไปยังผู้ที่ตามมา หรือเพื่อหยุดการเผยแพร่การออกอากาศไปยังผู้รับที่ตามมา
  2. ส่งออกอากาศ คล้ายกับวิธีการที่กล่าวมาข้างต้น โดยมีข้อแตกต่างประการหนึ่ง ผู้รับการออกอากาศทั้งหมดได้รับข้อความและไม่พึ่งพาซึ่งกันและกัน
  3. LocalBroadcastManager.sendBroadcast วิธีส่งเฉพาะการออกอากาศไปยังผู้รับที่กำหนดไว้ภายในแอปพลิเคชันของคุณและไม่เกินขอบเขตของแอปพลิเคชันของคุณ ตัวอย่างของการส่งการออกอากาศที่กำหนดเอง

https://giphy.com/gifs/23gUJhHyWkXEwl7UYV/html5

เครื่องรับสัญญาณออกอากาศสำหรับผู้เริ่มต้น
รูปภาพโดย John Gibbons บน Unsplash

สิ่งที่ควรให้ความสนใจ

  • อย่าส่งข้อมูลที่ละเอียดอ่อนผ่านการแพร่ภาพโดยนัย เนื่องจากแอปพลิเคชันใดๆ ที่รับฟังข้อมูลนั้น จะได้รับข้อมูลดังกล่าว คุณสามารถป้องกันได้โดยระบุแพ็คเกจหรือแนบสิทธิ์ในการออกอากาศ
  • อย่าเริ่มกิจกรรมจากการออกอากาศที่ได้รับเนื่องจากขาดประสบการณ์ของผู้ใช้ เลือกให้แสดงการแจ้งเตือนแทน

หัวข้อย่อยต่อไปนี้อ้างถึงการเปลี่ยนแปลงในตัวรับการออกอากาศที่เกี่ยวข้องกับระบบปฏิบัติการ Android แต่ละเวอร์ชัน (เริ่มจาก 7.0) สำหรับแต่ละเวอร์ชันมีข้อ จำกัด บางประการและพฤติกรรมก็เปลี่ยนไปเช่นกัน โปรดคำนึงถึงข้อจำกัดเหล่านี้เมื่อนึกถึงการใช้เครื่องรับส่งสัญญาณ

  • 7.0 ขึ้นไป (API ระดับ 24) - การออกอากาศสองระบบถูกปิดใช้งาน Action_New_Picture และ Action_New_Video (แต่ถูกนำกลับมาใน Android O สำหรับเครื่องรับที่ลงทะเบียน)
  • 8.0 ขึ้นไป (API ระดับ 26) - การออกอากาศโดยนัยส่วนใหญ่จำเป็นต้องลงทะเบียนเป็นแบบไดนามิกและไม่ใช่แบบสแตติก (ในรายการของคุณ) คุณสามารถค้นหาการออกอากาศที่ได้รับอนุญาตพิเศษในลิงก์นี้
  • 9.0 ขึ้นไป (API ระดับ 28) - ข้อมูลที่ได้รับน้อยลงในการออกอากาศระบบ Wi-Fi และ Network_State_Changed_Action

การเปลี่ยนแปลงใน Android O คือสิ่งที่คุณต้องระวังมากที่สุด สาเหตุที่ทำการเปลี่ยนแปลงเหล่านี้เนื่องจากนำไปสู่ปัญหาด้านประสิทธิภาพ การใช้งานแบตเตอรี่หมด และส่งผลกระทบต่อประสบการณ์การใช้งานของผู้ใช้ สิ่งนี้เกิดขึ้นเนื่องจากแอปพลิเคชั่นจำนวนมาก (แม้แต่ที่ไม่ได้ทำงานอยู่) กำลังรับฟังการเปลี่ยนแปลงทั้งระบบ และเมื่อการเปลี่ยนแปลงนั้นเกิดขึ้น ความโกลาหลก็บังเกิด ลองนึกภาพว่าทุกแอปพลิเคชันที่ลงทะเบียนในการดำเนินการนั้นมีชีวิตขึ้นมาเพื่อตรวจสอบว่าจำเป็นต้องทำอะไรเนื่องจากการออกอากาศหรือไม่ พิจารณาบางอย่าง เช่น สถานะ Wi-Fi ซึ่งเปลี่ยนแปลงบ่อย แล้วคุณจะเริ่มเข้าใจว่าทำไมการเปลี่ยนแปลงเหล่านี้จึงเกิดขึ้น

ทางเลือกอื่นสำหรับเครื่องรับส่งสัญญาณ

เพื่อให้ง่ายต่อการสำรวจข้อจำกัดเหล่านี้ ด้านล่างนี้คือรายละเอียดของส่วนประกอบอื่นๆ ที่คุณสามารถใช้ได้ในกรณีที่ไม่มีเครื่องรับการออกอากาศ แต่ละคนมีความรับผิดชอบและกรณีการใช้งานที่แตกต่างกัน ดังนั้นลองจับคู่ว่าอันไหนที่เหมาะกับความต้องการของคุณ

  • LocalBroadcastManager - ตามที่กล่าวไว้ข้างต้น ใช้ได้เฉพาะการออกอากาศภายในแอปพลิเคชันของคุณเท่านั้น
  • การจัดตารางงาน - งานสามารถเรียกใช้ได้ขึ้นอยู่กับสัญญาณหรือทริกเกอร์ที่ได้รับ ดังนั้นคุณอาจพบว่าการออกอากาศที่คุณกำลังฟังอยู่สามารถแทนที่ด้วยงานได้ นอกจากนี้ JobScheduler จะรับประกันว่างานของคุณจะเสร็จสิ้น แต่จะคำนึงถึงปัจจัยต่างๆ ของระบบ (เวลาและเงื่อนไข) เพื่อกำหนดว่าเมื่อใดควรทำงาน เมื่อสร้างงาน คุณจะแทนที่วิธีการที่เรียกว่า onStartJob . วิธีนี้ทำงานบนเธรดหลัก ดังนั้นตรวจสอบให้แน่ใจว่าวิธีนี้ทำงานเสร็จภายในระยะเวลาที่จำกัด หากคุณต้องการใช้ตรรกะที่ซับซ้อน ให้ลองเริ่มงานเบื้องหลัง นอกจากนี้ ค่าส่งคืนสำหรับเมธอดนี้เป็นบูลีน โดยที่ true แสดงว่ายังมีการดำเนินการบางอย่างอยู่ และค่า false หมายความว่างานเสร็จสิ้นแล้ว

หากคุณต้องการสัมผัสกับความสุขและความประหลาดใจที่เป็นเครื่องรับส่งสัญญาณโดยตรง คุณสามารถทำตามลิงก์เหล่านี้ไปยังที่เก็บที่ฉันตั้งไว้:

  1. การออกอากาศแบบกำหนดเอง (พร้อมการประกาศรายการ)
  2. การลงทะเบียนการออกอากาศ (โดยไม่ประกาศในรายการ)
  3. LocalBroadcastManager

ออกอากาศจบแล้ว