FMUSER Wirless ส่งวิดีโอและเสียงได้ง่ายขึ้น!
es.fmuser.org
it.fmuser.org
fr.fmuser.org
de.fmuser.org
af.fmuser.org -> แอฟริคานส์
sq.fmuser.org -> แอลเบเนีย
ar.fmuser.org -> ภาษาอาหรับ
hy.fmuser.org -> อาร์เมเนีย
az.fmuser.org -> อาเซอร์ไบจัน
eu.fmuser.org -> บาสก์
be.fmuser.org -> เบลารุส
bg.fmuser.org -> บัลแกเรีย
ca.fmuser.org -> คาตาลัน
zh-CN.fmuser.org -> ภาษาจีน (ประยุกต์)
zh-TW.fmuser.org -> ภาษาจีน (ดั้งเดิม)
hr.fmuser.org -> โครเอเชีย
cs.fmuser.org -> เช็ก
da.fmuser.org -> เดนมาร์ก
nl.fmuser.org -> ดัตช์
et.fmuser.org -> เอสโตเนีย
tl.fmuser.org -> ฟิลิปปินส์
fi.fmuser.org -> ฟินแลนด์
fr.fmuser.org -> ฝรั่งเศส
gl.fmuser.org -> กาลิเซีย
ka.fmuser.org -> จอร์เจีย
de.fmuser.org -> เยอรมัน
el.fmuser.org -> กรีก
ht.fmuser.org -> ชาวเฮติครีโอล
iw.fmuser.org -> ภาษาฮิบรู
hi.fmuser.org -> ภาษาฮินดี
hu.fmuser.org -> ฮังการี
is.fmuser.org -> ไอซ์แลนด์
id.fmuser.org -> ชาวอินโดนีเซีย
ga.fmuser.org -> ไอริช
it.fmuser.org -> อิตาเลี่ยน
ja.fmuser.org -> ภาษาญี่ปุ่น
ko.fmuser.org -> ภาษาเกาหลี
lv.fmuser.org -> ลัตเวีย
lt.fmuser.org -> ลิทัวเนีย
mk.fmuser.org -> มาซิโดเนีย
ms.fmuser.org -> มาเลย์
mt.fmuser.org -> มอลตา
no.fmuser.org -> นอร์เวย์
fa.fmuser.org -> เปอร์เซีย
pl.fmuser.org -> โปแลนด์
pt.fmuser.org -> โปรตุเกส
ro.fmuser.org -> โรมาเนีย
ru.fmuser.org -> รัสเซีย
sr.fmuser.org -> เซอร์เบีย
sk.fmuser.org -> สโลวัก
sl.fmuser.org -> สโลวีเนีย
es.fmuser.org -> สเปน
sw.fmuser.org -> ภาษาสวาฮิลี
sv.fmuser.org -> สวีเดน
th.fmuser.org -> ไทย
tr.fmuser.org -> ตุรกี
uk.fmuser.org -> ยูเครน
ur.fmuser.org -> ภาษาอูรดู
vi.fmuser.org -> เวียดนาม
cy.fmuser.org -> เวลส์
yi.fmuser.org -> ยิดดิช
การแพร่ภาพแบ่งออกเป็น 1000 ประเภท ได้แก่ "การออกอากาศปกติ" และ "การออกอากาศตามลำดับ" การออกอากาศธรรมดาเป็นแบบอะซิงโครนัสอย่างสมบูรณ์และเครื่องรับการออกอากาศทั้งหมดสามารถรับได้ในเวลาเดียวกัน (ตามเหตุผล) ประสิทธิภาพในการส่งข้อความค่อนข้างสูง แต่ข้อเสียคือผู้รับไม่สามารถส่งผ่านผลลัพธ์การประมวลผลไปยังผู้รับถัดไปและไม่สามารถยุติได้ การเผยแพร่เจตนาออกอากาศ; อย่างไรก็ตามการออกอากาศตามลำดับจะขึ้นอยู่กับลำดับความสำคัญที่ประกาศโดยผู้รับ (ประกาศใน android: แอตทริบิวต์ลำดับความสำคัญขององค์ประกอบตัวกรองความตั้งใจยิ่งจำนวนมากขึ้นลำดับความสำคัญสูงขึ้นช่วงค่า: -1000 ถึง XNUMX นอกจากนี้ยังเป็น เป็นไปได้เรียกใช้ setPriority () ของวัตถุ IntentFilter เพื่อตั้งค่า) และผู้รับจะได้รับการถ่ายทอดในทางกลับกัน ตัวอย่างเช่นถ้าระดับ A สูงกว่าระดับ B และระดับ B สูงกว่า C การออกอากาศจะถูกส่งไปยัง A ก่อนจากนั้นไปที่ B และสุดท้ายไปที่ C หลังจากที่ A ได้รับการออกอากาศแล้ว สามารถจัดเก็บข้อมูลในการออกอากาศ เมื่อการออกอากาศถูกส่งไปยัง B B จะได้รับข้อมูลที่เก็บไว้โดย A จากการออกอากาศ
Context.sendBroadcast ()
สิ่งที่ส่งไปคือการออกอากาศธรรมดาและสมาชิกทุกคนมีโอกาสได้รับและดำเนินการ
Context.sendOrperedBroadcast ()
การส่งเป็นการออกอากาศอย่างมีระเบียบ ระบบจะดำเนินการเครื่องรับทีละเครื่องตามลำดับความสำคัญที่ประกาศโดยเครื่องรับ ผู้รับก่อนหน้านี้มีสิทธิ์ยุติการออกอากาศ (BroadcastReceiver.abortBroadcast ()) หากการออกอากาศถูกยุติโดยเครื่องรับก่อนหน้าเครื่องรับรุ่นหลังจะไม่สามารถรับการออกอากาศได้อีกต่อไป สำหรับการออกอากาศตามสั่งเครื่องรับก่อนหน้านี้สามารถเก็บผลการประมวลผลไว้ในเจตนาการออกอากาศแล้วส่งต่อไปยังเครื่องรับถัดไป
เครื่องรับสัญญาณออกอากาศ (BroadcastReceiver) ใช้เพื่อรับ Intent ในการออกอากาศและการส่งข้อมูล Intent จะรับรู้ได้โดยการเรียก Context.sendBroadcast () และ Context.sendOrperedBroadcast () โดยปกติแล้ว Intent การออกอากาศสามารถรับได้จากเครื่องรับสัญญาณหลายเครื่องที่สมัครเป็นสมาชิก Intent นี้ คุณลักษณะนี้คล้ายกับตัวรับข้อความหัวข้อใน JMS ในการใช้วิธีการรับสัญญาณออกอากาศมีดังนี้:
ขั้นตอนแรก: กำหนดตัวรับสัญญาณออกอากาศสืบทอด BroadcastReceiver และเขียนเมธอด onReceive () ใหม่
คลาสสาธารณะ IncomingSMSReceiver expandsBroadcastReceiver {
@Override โมฆะสาธารณะ onReceive (Contextcontext, Intentintent) {
}
}
ขั้นตอนที่ 2: สมัครรับข้อมูลเจตนาที่สนใจในการออกอากาศมีสองวิธีการสมัครสมาชิก:
ประเภทแรก: ใช้รหัสเพื่อสมัครสมาชิก (การสมัครสมาชิกแบบไดนามิก)
ตัวกรอง IntentFilter = newIntentFilter ("android.provider.Telephony.SMS_RECEIVED");
ผู้รับ IncomingSMSReceiver = newIncomingSMSReceiver ();
registerReceiver (ตัวรับ, ตัวกรอง);
ประเภทที่สอง: สมัครสมาชิกในไฟล์ โหนดในไฟล์ AndroidManifest.xml (การสมัครสมาชิกแบบคงที่)
มาดูความแตกต่างระหว่างการสมัครสมาชิกการออกอากาศแบบไดนามิกและการสมัครสมาชิกการออกอากาศแบบคงที่:
การสมัครสมาชิกแบบคงที่เรียกอีกอย่างว่า: การออกอากาศประจำ เมื่อแอปพลิเคชันของคุณถูกปิดหากมีข้อความออกอากาศเครื่องรับสัญญาณออกอากาศที่คุณเขียนก็สามารถรับได้เช่นกัน วิธีการลงทะเบียนคือ AndroidManifast ในแอปพลิเคชันของคุณ .xml สำหรับการสมัครสมาชิก
การออกอากาศการสมัครสมาชิกแบบไดนามิกเรียกอีกอย่างว่า: การออกอากาศแบบไม่มีถิ่นที่อยู่ เมื่อแอปพลิเคชันสิ้นสุดลงการออกอากาศจะหายไปตามธรรมชาติ ตัวอย่างเช่นคุณสมัครรับข้อมูลการออกอากาศใน onCreate หรือ onResume ในกิจกรรมและคุณต้องยกเลิกการสมัครสมาชิกการออกอากาศใน onDestory หรือ onPause มิฉะนั้นจะมีการรายงานข้อยกเว้นดังนั้นเครื่องรับสัญญาณออกอากาศของคุณจะเป็นบุคคลที่ไม่มีถิ่นที่อยู่
มีรายละเอียดอีกอย่างหนึ่งที่นี่คือสองวิธีการสมัครสมาชิก เมื่อส่งการออกอากาศคุณต้องใส่ใจกับ: วิธีการแสดงเจตนาโดยนัยใช้สำหรับการลงทะเบียนแบบไดนามิกดังนั้นคุณต้องใช้เจตนาโดยปริยายในการส่งเมื่อส่งการออกอากาศ มิฉะนั้นเครื่องรับสัญญาณจะไม่สามารถรับการออกอากาศได้ ให้ความสนใจกับประเด็นนี้ แต่เมื่อสมัครสมาชิกแบบคงที่เนื่องจากสมัครใน AndroidMainfest.xml จึงเป็นไปได้ที่จะใช้แสดงเจตนาและเจตนาโดยปริยายเมื่อส่งการออกอากาศ (แน่นอนว่านี่เป็นเพียงเครื่องรับการออกอากาศที่กำหนดโดยตัวเราเอง) ดังนั้นในกรณีนี้โดยทั่วไปเราจะใช้นัย แสดงเจตจำนงในการส่งออกอากาศ.
ลองดูตัวอย่าง:
ดูโครงสร้างโครงการ:
ดูการถ่ายทอดการสมัครสมาชิกแบบคงที่:
แพ็คเกจ com.broadcast.demo;
นำเข้า android.app.Activity;
นำเข้า android.content.Intent;
นำเข้า android.os.Bundle;
นำเข้า android.view.View;
นำเข้า android.view.View.OClickListener;
นำเข้า android.widgetbutton;
นำเข้า com.example.androidbroadcastdemo.R;
/ **
* การออกอากาศการสมัครสมาชิกแบบคงที่
* @ผู้เขียน weijiang204321
*
*/
คลาสสาธารณะ StaticRegisterBroadcastActivity ขยายกิจกรรม {
@แทนที่
โมฆะที่ได้รับการป้องกัน onCreate (Bundle savedInstanceState) {
super.onCreate (saveInstanceState);
setContentView (R.layout.activity_main);
ปุ่ม btn = (ปุ่ม) findViewById (R.id.btn);
ไปยัง
btn.setOnClickListener (ใหม่ OnClickListener () {
@แทนที่
โมฆะสาธารณะ onClick (View v) {
// ใช้วิธีที่คงที่ในการลงทะเบียนการออกอากาศคุณสามารถใช้การแสดงเจตนาเพื่อส่งการออกอากาศ
เจตนาออกอากาศ = เจตนาใหม่ ("com.broadcast.set.broadcast");
sendBroadcast (ออกอากาศ null);
}
ไปยัง
});
}
ไปยัง
}
สมัครสมาชิกใน AndroidMainfest.xml:
<? รุ่น Xml = เข้ารหัส "1.0" = "UTF-8"?>
<รายการ xmlns:android="http://schemas.android.com/apk/res/android"
package = "com.example.androidbroadcastdemo"
android: versionCode = "1"
android: versionName = "1.0">
<ใช้-sdk
Android: minSdkVersion = "8"
android: targetSdkVersion = "18" />
<ใบสมัคร
android: allowBackup = "จริง"
android: icon = "@ drawable / ic_launcher"
android: label = "@ string / app_name"
android: theme = "@ style / AppTheme">
<กิจกรรม
android: name = "com.broadcast.demo.StaticRegisterBroadcastActivity"
android: label = "@ string / app_name">
อย่ากังวลกับเนื้อหาอื่น ๆ ในตอนนี้เนื่องจากเราจะพูดถึงในภายหลังที่นี่เราเน้นเฉพาะการลงทะเบียนการออกอากาศแบบคงที่
มาดูที่ตัวรับสัญญาณของการออกอากาศ:
แพ็คเกจ com.broadcast.receiver;
นำเข้า android.content.BroadcastReceiver;
นำเข้า android.content.Context;
นำเข้า android.content.Intent;
นำเข้า android.util.Log;
/ **
* เครื่องรับสัญญาณออกอากาศ
* @ผู้เขียน weijiang204321
*
*/
UnSortBroadcastReceiver คลาสสาธารณะขยาย BroadcastReceiver {
@แทนที่
โมฆะสาธารณะ onReceive (บริบทบริบทเจตนาเจตนา) {
Log.e ("Intent_Action:", Intent.getAction () + "");
}
}
ตรรกะในเมธอด onReceive ในเครื่องรับสัญญาณออกอากาศนั้นง่ายมากซึ่งก็คือการพิมพ์เนื้อหาของการดำเนินการ
เรียกใช้โปรแกรมผลลัพธ์นั้นง่ายมากนี่ไม่ใช่ภาพ
มาดูการสมัครสมาชิกแบบไดนามิก:
แพ็คเกจ com.broadcast.demo;
นำเข้า android.app.Activity;
นำเข้า android.content.Intent;
นำเข้า android.content.IntentFilter;
นำเข้า android.os.Bundle;
นำเข้า android.view.View;
นำเข้า android.view.View.OClickListener;
นำเข้า android.widgetbutton;
นำเข้า com.broadcast.receiver.UnSortBroadcastReceiver;
นำเข้า com.example.androidbroadcastdemo.R;
/ **
* ใช้วิธีแบบไดนามิกในการลงทะเบียนการออกอากาศ
* @ผู้เขียน weijiang204321
*
*/
คลาสสาธารณะ DynamicRegisterBroadcastActivity ขยายกิจกรรม {
ไปยัง
สตริงสุดท้ายคงที่สาธารณะ NEW_LIFEFORM_DETECTED = "com.dxz.broadcasttest.NEW_LIFEFORM";
เครื่องรับ UnSortBroadcastReceiver ที่ได้รับการป้องกัน
ไปยัง
@แทนที่
โมฆะที่ได้รับการป้องกัน onCreate (Bundle savedInstanceState) {
super.onCreate (saveInstanceState);
setContentView (R.layout.activity_main);
ปุ่ม btn0 = (ปุ่ม) findViewById (R.id.btn);
btn0.setOnClickListener (ใหม่ OnClickListener () {
โมฆะสาธารณะ onClick (View v) {
// ส่งออกอากาศ
เจตนา = เจตนาใหม่ (NEW_LIFEFORM_DETECTED);
sendBroadcast (มัน);
}
});
}
@แทนที่
โมฆะป้องกัน onResume () {
super.onResume ();
// ลงทะเบียนออกอากาศ
IntentFilter counterActionFilter = IntentFilter ใหม่ (NEW_LIFEFORM_DETECTED);
ผู้รับ = UnSortBroadcastReceiver ใหม่ ();
registerReceiver (ผู้รับ, counterActionFilter);
}
@แทนที่
โมฆะป้องกัน onPause () {
super.onPause ();
// ยกเลิกการออกอากาศ
unregisterReceiver (ตัวรับ);
}
}
ที่นี่เราสมัครรับข้อมูลการออกอากาศใน onResume และยกเลิกการสมัครรับข้อมูลการออกอากาศใน onPause
เปลี่ยนกิจกรรมที่เรียกใช้เป็น DynamicRegisterBroadcastActivity ใน AndroidMainfest.xml เนื้อหาอื่น ๆ ไม่จำเป็นต้องแก้ไข เรียกใช้โปรแกรมและพิมพ์ผลลัพธ์นั้นง่ายมากดังนั้นฉันจะไม่เห็นภาพที่นี่
มาดูการกระจายเสียงตามลำดับและการกระจายเสียงแบบไม่เรียงลำดับ
เราได้กล่าวไปแล้วในตอนต้นลองมาดูการกระจายเสียงที่ไม่เป็นระเบียบ:
อันดับแรกเรากำหนดตัวรับการออกอากาศสองเครื่อง:
เครื่องรับสัญญาณออกอากาศเครื่องแรก:
แพ็คเกจ com.broadcast.receiver;
นำเข้า android.content.BroadcastReceiver;
นำเข้า android.content.Context;
นำเข้า android.content.Intent;
นำเข้า android.util.Log;
/ **
* เครื่องรับสัญญาณ
* @ผู้เขียน weijiang204321
*
*/
คลาสสาธารณะ SortBroadcastReceiverA ขยาย BroadcastReceiver {
@แทนที่
โมฆะสาธารณะ onReceive (บริบทบริบทเจตนาเจตนา) {
Log.e ("สาธิต:", "เครื่องรับสัญญาณ A");
}
}
เครื่องรับสัญญาณที่สอง:
แพ็คเกจ com.broadcast.receiver;
นำเข้า android.content.BroadcastReceiver;
นำเข้า android.content.Context;
นำเข้า android.content.Intent;
นำเข้า android.util.Log;
/ **
* เครื่องรับสัญญาณข
* @ผู้เขียน weijiang204321
*
*/
คลาสสาธารณะ SortBroadcastReceiverB ขยาย BroadcastReceiver {
@แทนที่
โมฆะสาธารณะ onReceive (บริบทบริบทเจตนาเจตนา) {
Log.e ("สาธิต:", "ออกอากาศ B");
}
ไปยัง
ไปยัง
}
สมัครสมาชิกเพื่อออกอากาศใน AndroidMainfest.xml
ผลการดำเนินการ:
ผลการวิ่งแปลกไปหน่อย ทำไมตัวรับ B อยู่ด้านหน้าและตัวรับ A อยู่ด้านหลัง? เหตุผลก็คือเมื่อเราสมัครรับข้อมูลการแพร่ภาพใน AndroidMainfest.xml เราตั้งค่าแอตทริบิวต์ android: priority ในตัวกรองความตั้งใจ ยิ่งค่ามีขนาดใหญ่ลำดับความสำคัญก็จะยิ่งสูงขึ้น ลำดับความสำคัญของเครื่องรับ B คือ 1000 ลำดับความสำคัญของเครื่องรับ A คือ 999 ดังนั้น B จึงได้รับการถ่ายทอดก่อนจากนั้น A จะได้รับ แต่ไม่มีการเชื่อมต่อระหว่างเครื่องรับ B และเครื่องรับ A และไม่สามารถโต้ตอบได้ใช่ เนื่องจากนี่เป็นการออกอากาศนอกลำดับและอะซิงโครนัสเราสามารถทำการทดลองได้โดยการเพิ่มโค้ดลงในเมธอด onReceiver ใน B:
abortBroadcast (); // ยุติการส่งการออกอากาศนี้
ผลการดำเนินการ:
เราสามารถเห็นข้อผิดพลาดพร้อมท์นั่นคือการออกอากาศที่ไม่ได้รับคำสั่งไม่ได้รับอนุญาตให้ยุติการออกอากาศ ในความเป็นจริงการยกเลิกไม่มีประโยชน์เพราะเครื่องรับ A ยังคงรับการถ่ายทอดอยู่
มาดูการออกอากาศอย่างเป็นระเบียบรหัสต้องได้รับการแก้ไข:
ประการแรกคือเมื่อส่งการออกอากาศ:
เจตนาออกอากาศ = เจตนาใหม่ ("com.broadcast.set.broadcast");
sendOrderBroadcast (ออกอากาศ null);
จากนั้นเพิ่มวิธีการยุติการออกอากาศในเครื่องรับ B:
abortBroadcast ();
ไม่จำเป็นต้องแก้ไขรหัสอื่นผลการดำเนินการ:
มีเพียงเครื่องรับ B เครื่องรับ A ไม่ได้รับการออกอากาศเนื่องจากการออกอากาศถูกยกเลิกในเครื่องรับ B และเครื่องรับที่ตามมาไม่สามารถรับได้
แก้ไขโค้ดด้านล่าง:
ผู้รับ B:
แพ็คเกจ com.broadcast.receiver;
นำเข้า android.content.BroadcastReceiver;
นำเข้า android.content.Context;
นำเข้า android.content.Intent;
นำเข้า android.os.Bundle;
นำเข้า android.util.Log;
/ **
* เครื่องรับสัญญาณข
* @ผู้เขียน weijiang204321
*
*/
คลาสสาธารณะ SortBroadcastReceiverB ขยาย BroadcastReceiver {
@แทนที่
โมฆะสาธารณะ onReceive (บริบทบริบทเจตนาเจตนา) {
Log.e ("สาธิต:", "เครื่องรับสัญญาณ B");
บันเดิลบันเดิล = Bundle ใหม่ ();
bundle.putString ("next_receiver", "เครื่องรับสัญญาณออกอากาศต่อไป");
setResultExtras (มัด);
}
ไปยัง
}
หลังจากที่ B ได้รับการถ่ายทอดมันจะเก็บค่าบางอย่างและส่งต่อไปยังเครื่องรับถัดไป
รหัสของผู้รับ A:
แพ็คเกจ com.broadcast.receive
สินค้าอื่น ๆ ของเรา:
แพ็คเกจอุปกรณ์สถานีวิทยุ FM แบบมืออาชีพ
|
||
|
ป้อนอีเมลเพื่อรับเซอร์ไพรส์
es.fmuser.org
it.fmuser.org
fr.fmuser.org
de.fmuser.org
af.fmuser.org -> แอฟริคานส์
sq.fmuser.org -> แอลเบเนีย
ar.fmuser.org -> ภาษาอาหรับ
hy.fmuser.org -> อาร์เมเนีย
az.fmuser.org -> อาเซอร์ไบจัน
eu.fmuser.org -> บาสก์
be.fmuser.org -> เบลารุส
bg.fmuser.org -> บัลแกเรีย
ca.fmuser.org -> คาตาลัน
zh-CN.fmuser.org -> ภาษาจีน (ประยุกต์)
zh-TW.fmuser.org -> ภาษาจีน (ดั้งเดิม)
hr.fmuser.org -> โครเอเชีย
cs.fmuser.org -> เช็ก
da.fmuser.org -> เดนมาร์ก
nl.fmuser.org -> ดัตช์
et.fmuser.org -> เอสโตเนีย
tl.fmuser.org -> ฟิลิปปินส์
fi.fmuser.org -> ฟินแลนด์
fr.fmuser.org -> ฝรั่งเศส
gl.fmuser.org -> กาลิเซีย
ka.fmuser.org -> จอร์เจีย
de.fmuser.org -> เยอรมัน
el.fmuser.org -> กรีก
ht.fmuser.org -> ชาวเฮติครีโอล
iw.fmuser.org -> ภาษาฮิบรู
hi.fmuser.org -> ภาษาฮินดี
hu.fmuser.org -> ฮังการี
is.fmuser.org -> ไอซ์แลนด์
id.fmuser.org -> ชาวอินโดนีเซีย
ga.fmuser.org -> ไอริช
it.fmuser.org -> อิตาเลี่ยน
ja.fmuser.org -> ภาษาญี่ปุ่น
ko.fmuser.org -> ภาษาเกาหลี
lv.fmuser.org -> ลัตเวีย
lt.fmuser.org -> ลิทัวเนีย
mk.fmuser.org -> มาซิโดเนีย
ms.fmuser.org -> มาเลย์
mt.fmuser.org -> มอลตา
no.fmuser.org -> นอร์เวย์
fa.fmuser.org -> เปอร์เซีย
pl.fmuser.org -> โปแลนด์
pt.fmuser.org -> โปรตุเกส
ro.fmuser.org -> โรมาเนีย
ru.fmuser.org -> รัสเซีย
sr.fmuser.org -> เซอร์เบีย
sk.fmuser.org -> สโลวัก
sl.fmuser.org -> สโลวีเนีย
es.fmuser.org -> สเปน
sw.fmuser.org -> ภาษาสวาฮิลี
sv.fmuser.org -> สวีเดน
th.fmuser.org -> ไทย
tr.fmuser.org -> ตุรกี
uk.fmuser.org -> ยูเครน
ur.fmuser.org -> ภาษาอูรดู
vi.fmuser.org -> เวียดนาม
cy.fmuser.org -> เวลส์
yi.fmuser.org -> ยิดดิช
FMUSER Wirless ส่งวิดีโอและเสียงได้ง่ายขึ้น!
ติดต่อ
ที่ตั้ง:
เลขที่ 305 อาคาร HuiLan เลขที่ 273 Huanpu Road Guangzhou China 510620
หมวดหมู่
จดหมายข่าว