บทแนะนำนี้จะแนะนำคุณเกี่ยวกับวิธีสร้าง "สวัสดีโลก" สหพันธ์การค้า (Tradefed หรือ TF) การกำหนดค่าการทดสอบ และให้ข้อมูลเบื้องต้นเกี่ยวกับ TF เริ่มต้นจากสภาพแวดล้อมในการพัฒนา คุณจะสร้าง การกำหนดค่า และเพิ่มคุณลักษณะ
บทแนะนำนี้จะนำเสนอกระบวนการพัฒนาการทดสอบเป็นชุดแบบฝึกหัด แต่ละขั้นประกอบด้วยขั้นตอนต่างๆ หลายขั้นตอน ซึ่งจะแสดงวิธีสร้างและ ปรับแต่งการกำหนดค่าของคุณ โค้ดตัวอย่างทั้งหมดที่คุณต้องทำการทดสอบให้เสร็จสมบูรณ์ และชื่อของแบบฝึกหัดแต่ละชุดจะมีคำอธิบายประกอบ ซึ่งอธิบายบทบาทที่เกี่ยวข้องในขั้นตอนนั้น
- D สำหรับนักพัฒนาซอฟต์แวร์
- I สำหรับผู้ผสานรวม
- R สำหรับตัวดำเนินการทดสอบ
หลังจากดูบทแนะนำจบ คุณจะมีการกำหนดค่า TF ที่ใช้งานได้ และทำความเข้าใจแนวคิดสำคัญมากมายในกรอบการทำงาน TF
ตั้งค่าสหพันธ์การค้า
โปรดดูรายละเอียดเกี่ยวกับการตั้งค่าสภาพแวดล้อมการพัฒนา TF ที่หัวข้อ เครื่อง ตั้งค่า ส่วนที่เหลือของบทแนะนำนี้จะถือว่าคุณได้เปิด Shell ที่ เริ่มต้นมาใช้ในสภาพแวดล้อมของ TF
เพื่อความง่าย บทแนะนำนี้จะแสดงการเพิ่มการกำหนดค่าและ ในไลบรารีหลักของเฟรมเวิร์ก TF ซึ่งอาจขยายไปสู่การพัฒนา โมดูลนอกโครงสร้างต้นทางด้วยการรวบรวม JAR ที่แลกเปลี่ยนแล้ว จากนั้นจึงคอมไพล์ โมดูลของคุณเทียบกับ JAR นั้น
สร้างคลาสทดสอบ (D)
มาสร้างการทดสอบ Hello World ที่ส่งข้อความไป Stdout กัน ต โดยทั่วไปการทดสอบแบบแลกเปลี่ยนจะใช้ IRemoteTest ของ Google การใช้งาน HelloWorldTest มีดังนี้
package com.android.tradefed.example; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.invoker.TestInformation; import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.result.ITestInvocationListener; import com.android.tradefed.testtype.IRemoteTest; public class HelloWorldTest implements IRemoteTest { @Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World!"); } }
บันทึกโค้ดตัวอย่างนี้ไปยัง
<tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java
แล้วสร้างขึ้นมาใหม่โดยแลกกับ
m -jN
โปรดทราบว่า CLog.i
ในตัวอย่างด้านบนใช้เพื่อส่งต่อเอาต์พุตไปยังคอนโซล เพิ่มเติม
ข้อมูลเกี่ยวกับการเข้าสู่ระบบในสหพันธ์การค้ามีอธิบายอยู่ในการบันทึก (D, I, R)
หากสร้างไม่สำเร็จ โปรดปรึกษา เครื่อง ตั้งค่าเพื่อให้มั่นใจว่าคุณไม่ได้ข้ามขั้นตอนใดขั้นตอนหนึ่ง
สร้างการกำหนดค่า (I)
การทดสอบสหพันธ์การค้าสามารถดำเนินการได้โดยการสร้าง การกำหนดค่า ไฟล์ XML ที่จะแนะนำการแลกเปลี่ยน ทดสอบ รวมถึงโมดูลอื่นๆ ที่จะดำเนินการและมีอะไรบ้าง คำสั่งซื้อ
เรามาสร้างการกำหนดค่าใหม่สำหรับ HelloWorldTest กัน (โปรดดูข้อมูลคลาสทั้งหมด ชื่อของ HelloWorldTest )
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> </configuration>
บันทึกข้อมูลนี้ลงในไฟล์ helloworld.xml
ที่ใดก็ได้ในเครื่องของคุณ
ระบบไฟล์ (เช่น /tmp/helloworld.xml
) TF จะแยกวิเคราะห์
ไฟล์ XML การกำหนดค่า (หรือที่เรียกว่า config) ให้โหลดคลาสที่ระบุโดยใช้
เงาสะท้อน สร้างอินสแตนซ์ แคสต์ไปยัง IRemoteTest
และตั้งชื่อ
run
เรียกใช้การกำหนดค่า (R)
จาก Shell ให้เปิดคอนโซลที่แลกเปลี่ยนดังนี้
tradefed.sh
ตรวจสอบว่าอุปกรณ์เชื่อมต่อกับเครื่องที่เป็นโฮสต์และแลกเปลี่ยนข้อมูลได้ โดยทำดังนี้
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
คุณดำเนินการกำหนดค่าได้โดยใช้ run <config>
คอนโซล ลองถามคำถามเหล่านี้ดู
tf> run /tmp/helloworld.xml 05-12 13:19:36 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
คุณจะเห็นข้อความ "สวัสดี TF World!" ออกจากเทอร์มินัล
คุณสามารถยืนยันว่าคำสั่งทำงานเสร็จแล้วโดยใช้ list invocations
หรือ
l i
ในข้อความแจ้งของคอนโซล และไม่พิมพ์สิ่งใดเลย หากมีคำสั่งในขณะนี้
ทำงานอยู่ ส่วนขยายนี้จะแสดงดังนี้
tf >l i Command Id Exec Time Device State 10 0m:00 [876X00GNG] running stub on build(s) 'BuildInfo{bid=0, target=stub, serial=876X00GNG}'
เพิ่มการกำหนดค่าไปยังคลาสพาธ (D, I, R)
เพื่อความสะดวกในการทำให้ใช้งานได้ คุณยังสามารถรวมการกำหนดค่าต่างๆ ไว้ในการแลกเปลี่ยน JAR เอง Tradefed จะจดจำการกำหนดค่าทั้งหมดที่วางไว้โดยอัตโนมัติ config ของโฟลเดอร์ใน classpath
ย้ายไฟล์ helloworld.xml
ไปยังการแลกเปลี่ยน
ไลบรารีแกน
(<tree>/tools/tradefederation/core/res/config/example/helloworld.xml
)
เปลี่ยนการแลกซื้อเครื่องใหม่แล้ว รีสตาร์ทคอนโซลที่เทรด จากนั้นขอให้เทรดแสดง
รายการการกำหนดค่าจากคลาสพาธ:
tf> list configs […] example/helloworld: Runs the hello world test
ตอนนี้คุณเรียกใช้การกำหนดค่า Helloworld ได้โดยใช้สิ่งต่อไปนี้
tf> run example/helloworld 05-12 13:21:21 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
โต้ตอบกับอุปกรณ์ (D, R)
ที่ผ่านมา HelloWorldTest ของเราไม่ได้ทำอะไรที่น่าสนใจเลย Tradefed ความเชี่ยวชาญพิเศษกำลังทดสอบโดยใช้อุปกรณ์ Android ดังนั้นมาเพิ่มอุปกรณ์ Android กัน การทดสอบ
การทดสอบสามารถรับการอ้างอิงไปยังอุปกรณ์ Android โดยใช้ TestInformation
ได้ หากให้ไว้
ตามเฟรมเวิร์กเมื่อมีการเรียกเมธอด IRemoteTest#run
มาแก้ไขข้อความพิมพ์ HelloWorldTest เพื่อแสดงหมายเลขซีเรียลของ อุปกรณ์:
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); }
ตอนนี้ให้สร้างใหม่โดยแลกซื้อเครื่องใหม่และดูรายการอุปกรณ์โดยทำดังนี้
tradefed.sh
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
จดหมายเลขซีเรียลว่าพร้อมใช้งาน ที่ อุปกรณ์ที่ควรจัดสรรให้กับ HelloWorld
tf> run example/helloworld 05-12 13:26:18 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548
คุณควรเห็นข้อความพิมพ์ใหม่ที่แสดงหมายเลขซีเรียลของ อุปกรณ์
ส่งผลการทดสอบ (D)
IRemoteTest
รายงานผลลัพธ์ตามวิธีการโทรใน
ITestInvocationListener
ที่ระบุให้กับเมธอด #run
เฟรมเวิร์ก TF ก็คือ
รับผิดชอบในการรายงานการเริ่มต้น (ผ่าน
ITestInvocationListener#invocationStarted)
และสิ้นสุด (ผ่าน
ITestInvocationListener#invocationEnded)
ของคำขอแต่ละรายการ
การเรียกใช้การทดสอบคือการรวบรวมการทดสอบเชิงตรรกะ วิธีรายงานผลการทดสอบ
IRemoteTest
มีหน้าที่รายงานจุดเริ่มต้นของการทดสอบ
จุดเริ่มต้นและจุดสิ้นสุดของการทดสอบแต่ละครั้ง และจุดสิ้นสุดของการทดสอบ
ต่อไปนี้คือลักษณะหน้าตาของการติดตั้ง HelloWorldTest กับ ผลสอบไม่ผ่าน
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); TestDescription testId = new TestDescription("com.example.TestClassName", "sampleTest"); listener.testRunStarted("helloworldrun", 1); listener.testStarted(testId); listener.testFailed(testId, "oh noes, test failed"); listener.testEnded(testId, Collections.emptyMap()); listener.testRunEnded(0, Collections.emptyMap()); }
TF มีฟีเจอร์ IRemoteTest
หลายรายการที่คุณนำมาใช้ซ้ำได้
แทนที่จะเขียนเองทั้งหมด ตัวอย่างเช่น
TestationTest
สามารถเรียกใช้การทดสอบของแอปพลิเคชัน Android จากระยะไกลบนอุปกรณ์ Android แยกวิเคราะห์
แล้วส่งต่อผลลัพธ์เหล่านั้นไปที่ ITestInvocationListener
)
โปรดดูรายละเอียดที่หัวข้อ
ทดสอบ
ประเภท
ผลการทดสอบใน Store (I)
การใช้งาน Listener ทดสอบเริ่มต้นสำหรับการกำหนดค่า TF คือ TextResultReporter ซึ่งจะทิ้งผลลัพธ์ของการเรียกใช้ไปยัง stdout เพื่อให้เห็นภาพ ให้เรียกใช้ กำหนดค่า HelloWorldTest จากส่วนก่อนหน้า
./tradefed.sh
tf> run example/helloworld 04-29 18:25:55 I/TestInvocation: Invocation was started with cmd: /tmp/helloworld.xml 04-29 18:25:55 I/TestInvocation: Starting invocation for 'stub' with '[ BuildInfo{bid=0, target=stub, serial=876X00GNG} on device '876X00GNG'] 04-29 18:25:55 I/HelloWorldTest: Hello, TF World! I have device 876X00GNG 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Running helloworldrun: 1 tests 04-29 18:25:55 W/InvocationToJUnitResultForwarder: Test com.example.TestClassName#sampleTest failed with stack: oh noes, test failed 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Run ended in 0 ms
หากต้องการจัดเก็บผลลัพธ์ของการเรียกใช้ไว้ที่อื่น เช่น ในไฟล์ ให้ระบุ
การใช้งาน ITestInvocationListener
ที่กำหนดเองโดยใช้
result_reporter
ในการกำหนดค่า
นอกจากนี้ TF ยังมี
XmlResultReporter
Listener ซึ่งเขียนผลการทดสอบไปยังไฟล์ XML ในรูปแบบที่คล้ายกับ
ที่ผู้เขียน ant JUnit XML ใช้อยู่ หากต้องการระบุ results_reporter ใน
การกำหนดค่า ให้แก้ไข …/res/config/example/helloworld.xml
การกำหนดค่า:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> </configuration>
ตอนนี้ให้สร้างการแลกเปลี่ยนและเรียกใช้ตัวอย่าง Hello World อีกครั้ง ดังนี้
tf> run example/helloworld 05-16 21:07:07 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548 05-16 21:07:07 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_2991649128735283633/device_logcat_6999997036887173857.txt 05-16 21:07:07 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_2991649128735283633/host_log_6307746032218561704.txt 05-16 21:07:07 I/XmlResultReporter: XML test result file generated at /tmp/0/inv_2991649128735283633/test_result_536358148261684076.xml. Total tests 1, Failed 1, Error 0
สังเกตเห็นข้อความบันทึกที่ระบุว่ามีการสร้างไฟล์ XML แล้ว เวลา ไฟล์ที่สร้างขึ้นควรมีลักษณะดังนี้
<?xml version='1.0' encoding='UTF-8' ?> <testsuite name="stub" tests="1" failures="1" errors="0" time="9" timestamp="2011-05-17T04:07:07" hostname="localhost"> <properties /> <testcase name="sampleTest" classname="com.example.TestClassName" time="0"> <failure>oh noes, test failed </failure> </testcase> </testsuite>
นอกจากนี้คุณยังเขียน Listener การเรียกใช้ที่กำหนดเองได้ โดยเพียงแค่ เพื่อนำเมตริก ITestInvocationListener ของ Google
Tradefed รองรับ Listener การเรียกใช้ได้หลายรายการ คุณจึงส่งผลการทดสอบได้
ไปยังปลายทางอิสระหลายแห่ง หากต้องการทำเช่นนี้ เพียงระบุมากกว่าหนึ่ง
<result_reporter>
แท็กในการกำหนดค่า
สิ่งอำนวยความสะดวกในการบันทึก (D, I, R)
สถานที่ตัดไม้ของ TF มีความสามารถในการดำเนินการต่อไปนี้
- เก็บบันทึกจากอุปกรณ์ (หรือที่เรียกว่า Logcat ของอุปกรณ์)
- จัดเก็บบันทึกจากเฟรมเวิร์กของสหพันธ์การค้าที่ทำงานในเครื่องโฮสต์ (หรือที่เรียกว่าบันทึกของโฮสต์)
เฟรมเวิร์ก TF จะจับภาพ Logcat จากอุปกรณ์ที่จัดสรรโดยอัตโนมัติ
และส่งไปยัง Listener การเรียกใช้เพื่อประมวลผล
จากนั้น XmlResultReporter
จะบันทึก Logcat ของอุปกรณ์ที่บันทึกไว้เป็นไฟล์
ระบบจะรายงานบันทึกของโฮสต์ TF โดยใช้
Wrapper ของ CLog
สำหรับคลาสบันทึก ddmlib เราจะแปลง
การเรียก System.out.println
ก่อนหน้าใน HelloWorldTest ไปยัง
โทรผ่าน CLog
:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());
CLog
จัดการการประมาณค่าสตริงโดยตรง ซึ่งคล้ายกับ
String.format
เมื่อสร้างและเรียก TF ใหม่ คุณจะเห็น
ข้อความบันทึกใน stdout:
tf> run example/helloworld … 05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548 …
โดยค่าเริ่มต้น แลกเปลี่ยน
บันทึกของโฮสต์เอาต์พุต
ข้อความไปยัง Stadout TF ยังมีการใช้งานบันทึกที่เขียน
ข้อความไปยังไฟล์:
FileLogger
หากต้องการเพิ่มการบันทึกไฟล์ ให้เพิ่มแท็ก logger
ลงในการกำหนดค่าโดยระบุ
ชื่อเต็มของชั้นเรียน FileLogger
:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> <logger class="com.android.tradefed.log.FileLogger" /> </configuration>
จากนั้นสร้างและเรียกใช้ตัวอย่าง helloworld อีกครั้ง:
tf >run example/helloworld … 05-16 21:38:21 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_6390011618174565918/device_logcat_1302097394309452308.txt 05-16 21:38:21 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt …
ข้อความบันทึกจะระบุเส้นทางของบันทึกโฮสต์ ซึ่งเมื่อดูแล้ว ควรมีข้อความบันทึก HelloWorldTest ดังนี้
more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
ตัวอย่างเอาต์พุต:
… 05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
ตัวเลือกการจัดการ (D, I, R)
ออบเจ็กต์ที่โหลดจากการกำหนดค่า TF (หรือที่เรียกว่าออบเจ็กต์การกำหนดค่า)
ยังสามารถรับข้อมูลจากอาร์กิวเมนต์บรรทัดคำสั่งผ่านการใช้
คำอธิบายประกอบ @Option
รายการ
หากต้องการเข้าร่วม คลาสออบเจ็กต์การกำหนดค่าจะใช้ @Option
ไปยังฟิลด์สมาชิก และตั้งชื่อที่ไม่ซ้ำ ซึ่งช่วยให้สามารถ
ค่าในช่องสมาชิกที่จะป้อนข้อมูลผ่านตัวเลือกบรรทัดคำสั่ง (และ
เพิ่มตัวเลือกนั้นลงในระบบช่วยเหลือการกำหนดค่าโดยอัตโนมัติ)
หมายเหตุ: ไม่รองรับช่องบางประเภท สำหรับ คำอธิบายประเภทที่สนับสนุน โปรดดู OptionSetter
เพิ่ม @Option
ลงใน HelloWorldTest กันเลย
@Option(name="my_option", shortName='m', description="this is the option's help text", // always display this option in the default help text importance=Importance.ALWAYS) private String mMyOption = "thisisthedefault";
ต่อไป ให้คุณเพิ่มข้อความบันทึกเพื่อแสดงค่าของตัวเลือก HelloWorldTest เพื่อสาธิตการใช้งานที่ถูกต้อง
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { … CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);
สุดท้าย ให้สร้าง TF ใหม่และเรียกใช้ Helloworld คุณควรเห็นข้อความบันทึกที่มี
ค่าเริ่มต้น my_option
:
tf> run example/helloworld … 05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
ส่งค่าจากบรรทัดคำสั่ง
ส่งผ่านค่าสำหรับ my_option
คุณควรจะเห็น
my_option
จะเติมค่านั้นด้วยค่าต่อไปนี้
tf> run example/helloworld --my_option foo … 05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
การกำหนดค่า TF ยังมีระบบช่วยเหลือ ซึ่งแสดงโดยอัตโนมัติ
ข้อความช่วยเหลือสำหรับ @Option
ช่อง ลองเลย แล้วคุณจะเห็น
ข้อความช่วยเหลือสำหรับ my_option
:
tf> run example/helloworld --help Printing help for only the important options. To see help for all options, use the --help-all flag cmd_options options: --[no-]help display the help text for the most important/critical options. Default: false. --[no-]help-all display the full help text for all options. Default: false. --[no-]loop keep running continuously. Default: false. test options: -m, --my_option this is the option's help text Default: thisisthedefault. 'file' logger options: --log-level-display the minimum log level to display on stdout. Must be one of verbose, debug, info, warn, error, assert. Default: error.
จดบันทึกข้อความเกี่ยวกับ "การพิมพ์เฉพาะตัวเลือกที่สำคัญ" วิธีลด
เพื่อเป็นตัวเลือกให้เป็นระเบียบ โดย TF จะใช้แอตทริบิวต์ Option#importance
เพื่อ
ตัดสินใจว่าจะแสดงข้อความช่วยเหลือของช่อง @Option
ที่เฉพาะเจาะจงหรือไม่เมื่อ
ระบุ --help
แล้ว --help-all
แสดงความช่วยเหลือเสมอสำหรับ
ฟิลด์ @Option
ทั้งหมด โดยไม่คำนึงถึงความสำคัญ โปรดดูรายละเอียดที่หัวข้อ
Option.Importance
ส่งผ่านค่าจากการกำหนดค่า
คุณยังสามารถระบุค่า Option ภายในการกำหนดค่าได้โดยการเพิ่ม
องค์ประกอบ <option name="" value="">
ทดสอบโดยใช้
helloworld.xml
:
<test class="com.android.tradefed.example.HelloWorldTest" > <option name="my_option" value="fromxml" /> </test>
การสร้างใหม่และเรียกใช้ Helloworld ควรให้ผลลัพธ์ดังนี้:
05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
ความช่วยเหลือในการกำหนดค่าควรอัปเดตเพื่อระบุค่าเริ่มต้นของ
my_option
:
tf> run example/helloworld --help test options: -m, --my_option this is the option's help text Default: fromxml.
ออบเจ็กต์การกำหนดค่าอื่นๆ ที่รวมอยู่ในการกำหนดค่า Helloworld เช่น
FileLogger
ยอมรับตัวเลือกด้วย ตัวเลือก
--log-level-display
น่าสนใจเพราะเป็นการกรองบันทึกที่
ปรากฏบน Stdout ก่อนหน้านี้ในบทแนะนำ คุณอาจสังเกตการ์ด "สวัสดี TF
โลก! ฉันมีอุปกรณ์ ..." ข้อความบันทึกหยุดแสดงใน stdout หลังจากที่เรา
เปลี่ยนไปใช้ FileLogger
คุณสามารถเพิ่มการพูดรายละเอียด
เข้าสู่ระบบ stdout โดยการส่งผ่านในอาร์กิวเมนต์ --log-level-display
ลองเลย แล้วคุณจะเห็นข้อความ "ฉันมีอุปกรณ์" ข้อความบันทึกปรากฏอีกครั้งใน stdout นอกเหนือไปจากการบันทึกไว้ในไฟล์:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
เท่านี้เองนะเพื่อน
โปรดอย่าลืมว่า ถ้าคุณติดค้างอะไรบางอย่าง การค้า ซอร์สโค้ดของการรวมศูนย์มีข้อมูลที่เป็นประโยชน์มากมายซึ่งไม่มีการเปิดเผยใน เอกสารประกอบ ถ้าไม่ได้ผล ให้ลองถามใน แพลตฟอร์ม Android Google Group ที่มี "สหพันธ์การค้า" ในเรื่องของข้อความ