ฟีเจอร์ที่สำคัญที่สุดอย่างหนึ่งของ Android คือความสามารถของแอปในการส่งผู้ใช้ไปยังแอปอื่น
อิงตาม "การกระทำ" ที่อยากจะทำ ตัวอย่างเช่น หาก
แอปของคุณมีที่อยู่ของธุรกิจที่คุณต้องการให้แสดงบนแผนที่ คุณไม่จำเป็นต้องสร้าง
กิจกรรมที่แสดงแผนที่ในแอป แต่คุณสามารถสร้างคำขอเพื่อดูที่อยู่แทนได้
โดยใช้ Intent
จากนั้น ระบบ Android จะเริ่มต้นแอปที่สามารถแสดง
ที่อยู่บนแผนที่
ตามที่ได้อธิบายไว้ในชั้นเรียนแรก อาคาร แอปแรกของคุณ คุณต้องใช้ Intent เพื่อสลับไปมาระหว่างกิจกรรมต่างๆ ในแอปของคุณเอง คุณ มักจะทำเช่นนั้นด้วยIntent แบบเจาะจงปลายทาง ซึ่งจะระบุชื่อคลาสที่แน่นอนของ คอมโพเนนต์ที่คุณจะเริ่มต้น แต่เมื่อคุณต้องการมีแอปอีกแอปหนึ่ง ให้ดำเนินการบางอย่าง เช่น เช่น "ดูแผนที่" คุณต้องใช้Intent แบบไม่เจาะจงปลายทาง
บทเรียนนี้แสดงวิธีการสร้างความตั้งใจโดยปริยายสำหรับการกระทำบางอย่างและวิธีใช้งาน เพื่อเริ่มกิจกรรมที่เป็นการดำเนินการในแอปอื่น ดูวิดีโอที่ฝังที่นี่ด้วย เพื่อให้เข้าใจเหตุผลที่คุณต้องรวมการตรวจสอบรันไทม์สำหรับ Intent แบบไม่เจาะจงปลายทางด้วย
สร้าง Intent แบบไม่เจาะจงปลายทาง
Intent แบบไม่เจาะจงปลายทางจะไม่ประกาศชื่อคลาสของคอมโพเนนต์เพื่อเริ่มต้น แต่จะประกาศแทน ในการทำงาน การดำเนินการจะระบุสิ่งที่คุณต้องการทำ เช่น view แก้ไข ส่ง หรือรับเนื้อหา
เชื่อมโยงการดำเนินการผ่าน Intent กับข้อมูล
Intent มักมีข้อมูลที่เกี่ยวข้องด้วย
เช่น ที่อยู่ที่ต้องการดู หรือข้อความอีเมลที่ต้องการส่ง
ข้อมูลอาจเป็น Uri
ทั้งนี้ขึ้นอยู่กับ Intent ที่คุณต้องการสร้าง
ประเภทข้อมูลอีกประเภทหนึ่ง หรือเจตนาอาจไม่จำเป็นต้องใช้ข้อมูลเลย
ถ้าข้อมูลของคุณเป็น Uri
คุณสามารถใช้ตัวสร้าง Intent()
ง่ายๆ เพื่อตั้งการทำงานและ
ตัวอย่างเช่น วิธีสร้างความตั้งใจเพื่อเริ่มต้นการโทรโดยใช้ข้อมูล Uri
เพื่อระบุหมายเลขโทรศัพท์มีดังนี้
Kotlin
val callIntent: Intent = Uri.parse("tel:5551234").let { number -> Intent(Intent.ACTION_DIAL, number) }
Java
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
เมื่อแอปเรียกใช้ Intent นี้ด้วยการโทร startActivity()
แอป "โทรศัพท์" จะเริ่มโทรหาหมายเลขโทรศัพท์ที่ระบุไว้
นี่คือ Intent อีก 2 รายการ รวมถึงการดำเนินการและข้อมูล Uri
คู่:
ดูแผนที่
Kotlin
// Map point based on address val mapIntent: Intent = Uri.parse( "geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California" ).let { location -> // Or map point based on latitude/longitude // val location: Uri = Uri.parse("geo:37.422219,-122.08364?z=14") // z param is zoom level Intent(Intent.ACTION_VIEW, location) }
Java
// Map point based on address Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); // Or map point based on latitude/longitude // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
ดูหน้าเว็บ
Kotlin
val webIntent: Intent = Uri.parse("https://www.android.com").let { webpage -> Intent(Intent.ACTION_VIEW, webpage) }
Java
Uri webpage = Uri.parse("https://www.android.com"); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
เพิ่มส่วนเสริมไปยัง Intent
Intent แบบไม่เจาะจงปลายทางประเภทอื่นๆ ต้องใช้ "เพิ่มเติม" ที่ให้ข้อมูลประเภทต่างๆ
เช่น สตริง คุณเพิ่มข้อมูลเพิ่มเติมอย่างน้อย 1 รายการได้โดยใช้เมธอด putExtra()
ต่างๆ
โดยค่าเริ่มต้น ระบบจะระบุประเภท MIME ที่เหมาะสมที่ Intent ต้องการโดยอิงจาก
ข้อมูล Uri
ที่รวมอยู่ หากคุณไม่ใส่ Uri
ในช่อง
โดยทั่วไป คุณควรใช้ setType()
เพื่อระบุประเภท
ที่เกี่ยวข้องกับ Intent การตั้งค่าประเภท MIME จะระบุเพิ่มเติมถึงประเภทของ
กิจกรรมควรได้รับความตั้งใจ
ต่อไปนี้เป็น Intent บางส่วนที่เพิ่มข้อมูลเพิ่มเติมเพื่อระบุการดำเนินการที่ต้องการ
ส่งอีเมลพร้อมไฟล์แนบ
Kotlin
Intent(Intent.ACTION_SEND).apply { // The intent does not have a URI, so declare the "text/plain" MIME type type = "text/plain" putExtra(Intent.EXTRA_EMAIL, arrayOf("jan@example.com")) // recipients putExtra(Intent.EXTRA_SUBJECT, "Email subject") putExtra(Intent.EXTRA_TEXT, "Email message text") putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")) // You can also attach multiple items by passing an ArrayList of Uris }
Java
Intent emailIntent = new Intent(Intent.ACTION_SEND); // The intent does not have a URI, so declare the "text/plain" MIME type emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jan@example.com"}); // recipients emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text"); emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")); // You can also attach multiple items by passing an ArrayList of Uris
สร้างกิจกรรมในปฏิทิน
หมายเหตุ: Intent นี้สำหรับกิจกรรมในปฏิทินรองรับเฉพาะ API ระดับ 14 ขึ้นไป
Kotlin
// Event is on January 23, 2021 -- from 7:30 AM to 10:30 AM. Intent(Intent.ACTION_INSERT, Events.CONTENT_URI).apply { val beginTime: Calendar = Calendar.getInstance().apply { set(2021, 0, 23, 7, 30) } val endTime = Calendar.getInstance().apply { set(2021, 0, 23, 10, 30) } putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.timeInMillis) putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.timeInMillis) putExtra(Events.TITLE, "Ninja class") putExtra(Events.EVENT_LOCATION, "Secret dojo") }
Java
// Event is on January 23, 2021 -- from 7:30 AM to 10:30 AM. Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI); Calendar beginTime = Calendar.getInstance(); beginTime.set(2021, 0, 23, 7, 30); Calendar endTime = Calendar.getInstance(); endTime.set(2021, 0, 23, 10, 30); calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis()); calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis()); calendarIntent.putExtra(Events.TITLE, "Ninja class"); calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
หมายเหตุ: คุณต้องกำหนด Intent
ให้เฉพาะเจาะจงมากที่สุด เช่น ถ้าต้องการแสดงรูปภาพ
เมื่อใช้ Intent ACTION_VIEW
คุณควรระบุประเภท MIME เป็น
image/*
วิธีนี้จะช่วยป้องกันไม่ให้แอปที่ "ดู" ได้ ข้อมูลประเภทอื่นๆ (เช่น แอปแผนที่)
ที่เกิดจากความตั้งใจ
เริ่มกิจกรรมด้วยความตั้งใจ
เมื่อคุณสร้าง Intent
และตั้งค่าข้อมูลเพิ่มเติมแล้ว โปรดโทรหา startActivity()
เพื่อส่งไปยังระบบ
Kotlin
startActivity(intent)
Java
startActivity(intent);
รับมือกับสถานการณ์ที่ไม่มีแอปใดได้รับ Intent
แม้ว่าอีกแอปหนึ่งที่ติดตั้งไว้จะจัดการ Intent หลายรายการได้สำเร็จ
บนอุปกรณ์ เช่น แอปโทรศัพท์ อีเมล หรือปฏิทิน แอปของคุณควรเตรียมการ
สำหรับสถานการณ์ที่ไม่มีกิจกรรมใดที่จะจัดการกับความตั้งใจของแอปของคุณได้ เมื่อใดก็ตามที่คุณ
สร้างความตั้งใจ เตรียมพร้อมที่จะจับ
ActivityNotFoundException
ซึ่งเกิดขึ้นหากไม่มีกิจกรรมอื่นๆ ที่จัดการกับความตั้งใจของแอปได้
Kotlin
try { startActivity(intent) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
try { startActivity(intent); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
หลังจากตรวจพบข้อยกเว้นนี้แล้ว ให้ตัดสินใจว่าแอปควรทำอย่างไรต่อไป รายการถัดไป จะขึ้นอยู่กับลักษณะเฉพาะของเจตนาที่คุณพยายามจะ เรียกใช้ ตัวอย่างเช่น หากคุณรู้จักแอปที่เจาะจงซึ่งจัดการความตั้งใจได้ ระบุลิงก์ให้ผู้ใช้ดาวน์โหลดแอป ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธี ที่ลิงก์ไปยังผลิตภัณฑ์ของคุณใน Google Play
กล่องโต้ตอบที่มีคำอธิบาย
หากระบบระบุกิจกรรมได้มากกว่า 1 รายการที่สามารถจัดการความตั้งใจ จะแสดงกล่องโต้ตอบ (บางครั้งเรียกว่า "กล่องโต้ตอบที่มีคำอธิบาย") สำหรับ ผู้ใช้จะเลือกแอปที่จะใช้ ดังที่แสดงในรูปที่ 1 หากมีเพียงรายการเดียว ที่จัดการความตั้งใจแล้ว ระบบจะเริ่มการทำงานของสิ่งนั้นทันที
![แผงจะปรากฏขึ้น
บริเวณด้านล่างของหน้าจอ แผงนี้แสดงแอปต่างๆ ที่อาจ
จัดการความตั้งใจ](https://developer.android.com/static/images/training/basics/intents-choice.png?authuser=19&hl=th)
รูปที่ 1 ตัวอย่างการเลือก ที่ปรากฏขึ้นเมื่อมีแอปมากกว่า 1 แอปสามารถจัดการ Intent ได้
ตัวอย่างที่สมบูรณ์
ต่อไปนี้เป็นตัวอย่างที่สมบูรณ์ที่แสดงวิธีสร้างความตั้งใจที่จะดูแผนที่ ยืนยันว่า มีไว้เพื่อจัดการ Intent แล้วเริ่มแอป:
Kotlin
// Build the intent. val location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California") val mapIntent = Intent(Intent.ACTION_VIEW, location) // Try to invoke the intent. try { startActivity(mapIntent) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
// Build the intent. Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); // Try to invoke the intent. try { startActivity(mapIntent); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
แสดงตัวเลือกแอป
![](https://developer.android.com/static/images/training/basics/intent-chooser.png?authuser=19&hl=th)
รูปที่ 2 กล่องโต้ตอบตัวเลือก
โปรดสังเกตว่าเมื่อคุณเริ่มกิจกรรมโดยการส่ง Intent
ไปยัง startActivity()
และมีแอปมากกว่า 1 แอปที่ตอบสนองต่อ
ผู้ใช้เลือกได้ว่าจะใช้แอปใดโดยค่าเริ่มต้น (โดยเลือกช่องทำเครื่องหมายด้านล่าง
ของกล่องโต้ตอบ ดูรูปที่ 1) ซึ่งมีประโยชน์มากเมื่อดำเนินการที่ผู้ใช้
โดยทั่วไปต้องการใช้แอปเดิมทุกครั้ง เช่น เมื่อเปิดหน้าเว็บ (ผู้ใช้
ใช้เว็บเบราว์เซอร์เพียงตัวเดียว) หรือถ่ายรูป (ผู้ใช้มักชอบกล้อง 1 ตัว)
แต่หากการทำงานที่ต้องทำนั้นหลายแอปสามารถจัดการได้จากหลายแอปและผู้ใช้อาจ เลือกใช้แอปที่แตกต่างกันในแต่ละครั้ง เช่น "แชร์" ซึ่งผู้ใช้อาจมี แอปที่ผู้ใช้อาจแชร์รายการ คุณควรแสดงกล่องโต้ตอบตัวเลือกอย่างชัดเจน ดังที่แสดงในรูปที่ 2 กล่องโต้ตอบตัวเลือก บังคับให้ผู้ใช้เลือกแอปที่จะใช้สำหรับการทำงานทุกครั้ง (ผู้ใช้ไม่สามารถเลือก แอปเริ่มต้นสำหรับการดำเนินการ)
หากต้องการแสดงตัวเลือก ให้สร้าง Intent
โดยใช้ createChooser()
แล้วส่งไปยัง startActivity()
เช่น
Kotlin
val intent = Intent(Intent.ACTION_SEND) // Create intent to show chooser val chooser = Intent.createChooser(intent, /* title */ null) // Try to invoke the intent. try { startActivity(chooser) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
Intent intent = new Intent(Intent.ACTION_SEND); // Create intent to show chooser Intent chooser = Intent.createChooser(intent, /* title */ null); // Try to invoke the intent. try { startActivity(chooser); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
การดำเนินการนี้จะแสดงกล่องโต้ตอบที่มีรายการแอปที่ตอบสนองต่อ Intent ที่ส่งผ่าน
ไปยังเมธอด
createChooser()
พารามิเตอร์ title
อาจเป็น
ระบุหากการดำเนินการไม่ใช่
ACTION_SEND
หรือ
ACTION_SEND_MULTIPLE