ขอเขียนบทความสำหรับ Android Development เบาๆซักเรื่องบ้างเพื่อคลายเครียด ก็เลยขอหยิบเรื่องการเปิด Page หรือ Official Account ที่อยู่บน Facebook, Twitter, Instagram หรือ Line ผ่านแอปพลิเคชันตัวอื่นๆกัน

แอปฯส่วนใหญ่ที่ไม่ได้เกี่ยวข้องกับ Social โดยตรง อย่างเช่น แอปพลิเคชันของบริษัทแห่งหนึ่ง ก็มักจะมีการใส่ปุ่มเพื่อเปิดหน้า Page หรือ Official Account ที่ต้องการ เช่น บริษัท ABC มี Facebook Page และ Twitter Official Account ก็คงอยากจะใส่ปุ่มลงในแอปฯเพื่อให้ผู้ใช้กดแล้วเปิดเข้า Social เหล่านี้ทันที

นักพัฒนาส่วนใหญ่ก็คงใช้คำสั่งประมาณนี้

val uri = Uri.parse("https://www.facebook.com/SleepingForLess")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)

ซึ่งเป็นคำสั่งที่จะให้เปิด URL ดังกล่าว ซึ่งเป็น URL ของ Social ที่ต้องการ (ยกตัวอย่างเป็น Sleeping For Less ใน Facebook Page)

และผลลัพธ์ที่ได้ก็จะประมาณนี้

คำสั่งดังกล่าวจะเป็นการสั่งให้เปิด URL ดังกล่าวด้วย Web Browser ที่มีอยู่บนเครื่อง (หรือแอปฯอื่นๆที่สามารถรองรับกับ URL ที่กำหนดไว้)

แต่จะเกิดอะไรขึ้นถ้าเจ้าของบล็อกใช้แอปฯ Facebook อยู่ แต่ไม่ได้ล็อกอินบน Web Browser ล่ะ?

เมื่อเจ้าของบล็อกอยากจะทำอะไรบางอย่างบน Facebook Page นี้ เช่นกด Report (ล้อเล่น) ก็จะต้องล็อกอินเข้าสู่ระบบใน Web Browser เสียก่อนใช่มั้ยล่ะ

จะดีกว่ามั้ยถ้าเข้าผ่าน Facebook App ได้โดยตรงเลย

นั่นล่ะครับ จุดประสงค์ของบทความนี้ เพื่อให้การเปิดเข้ามาในหน้า Page หรือ Official Account มีประโยชน์จริงๆ สามารถทำอะไรต่อได้จริงๆ มันก็ต้องเปิดแอปฯขึ้นมาเลยสิพี่น้อง!!!

แต่การจะทำแบบนั้นได้ นักพัฒนาก็ต้องรู้ก่อนว่า Social แต่ละตัวนั้นใช้วิธีใดในการเปิดแอปฯแล้วเปิดหน้าที่ต้องการในทันที

Social App แต่ละตัวมีรูปแบบในการสั่งงานต่างกัน

จากที่เจ้าของบล็อกไปหาข้อมูลมาก็พบว่า Social App ส่วนใหญ่นั้นสามารถสั่งงานผ่าน URL Scheme ได้เลย โดยกำหนด Page หรือ Official Account ให้ถูกต้อง และจะมีบางส่วนที่ยิงผ่าน URL ปกติ

และดูเหมือนว่าจะไม่มี Social App ตัวไหนให้สั่งเปิดผ่าน Intent ได้โดยตรง (แบบเจาะจงมาที่แอปฯนั้นๆโดยตรง)

มาดูวิธีของแต่ละเจ้ากันเถอะ!!

Facebook

สำหรับ Facebook นั้นจะใช้วิธีเปิดผ่าน URL Scheme ดังนี้

fb://page/<page_id>

ให้กำหนด <page_id> ด้วยเลข ID ของ Page ที่ต้องการ

ถ้าไม่รู้ว่า Page ที่จะกำหนดนั้นมีเลข ID อะไรให้ลองเข้าไปเช็คผ่านเว็ป https://findmyfbid.com/ ได้เลย โดยตัวเว็ปจะให้ใส่ URL ของ Page หรือ Profile ของบุคคลที่ต้องการก็ให้แปะ URL ของ Page ลงไปได้เลย แล้วตัวเว็ปจะบอกเลข ID ของ Page นั้นๆมาให้

แล้วใช้ Intent สั่งเปิด URL Scheme ดังกล่าวได้เลย

val uri = Uri.parse("fb://page/577361412281379")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)

ในโค้ดตัวอย่างกำหนด ID ของ Sleeping For Less นั่นเอง

Twitter

สำหรับ Twitter นั้นจะใช้วิธีเปิดผ่าน URL Scheme เช่นกัน

twitter://user?user_id=<user_id>

ให้กำหนด <user_id> ด้วยเลข ID ของ User ที่ต้องการ

ถ้าไม่รู้ว่า User ที่จะกำหนดนั้นมีเลข ID อะไรให้ลองเข้าไปเช็คผ่านเว็ป https://gettwitterid.com/ ได้เลย โดยตัวเว็ปจะให้ใส่ชื่อของ User (ชื่อ User ที่อิงตาม URL หรือต่อท้าย @) ที่ต้องการแล้วตัวเว็ปจะบอกเลข ID ของ Page นั้นๆมาให้

แล้วใช้ Intent สั่งเปิด URL Scheme ดังกล่าวได้เลย

val uri = Uri.parse("twitter://user?user_id=3195422066")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)

ในโค้ดตัวอย่างกำหนด ID ของ Sleeping For Less เอาไว้

Instagram

สำหรับ Instagram ก็ใช้วิธีเปิดผ่าน URL Scheme เหมือนกับ Facebook และ Twitter เลย แต่สามารถกำหนดด้วยชื่อ User ได้เลย

instagram://user?username=<username>

ให้กำหนด <username> ด้วยชื่อของ User ที่ต้องการ

แล้วใช้ Intent สั่งเปิด URL Scheme ดังกล่าวได้เลย

val uri = Uri.parse("instagram://user?username=google")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)

พอดี Sleeping For Less ไม่มีบน Instagram ในโค้ดตัวอย่างก็เลยกำหนดเป็น User ของ Google แทน

LINE

สำหรับ LINE จะแตกต่างจากชาวบ้านนิดหน่อยตรงที่ไม่จำเป็นต้องใช้ URL Scheme แต่สามารถเรียกผ่าน URL ได้โดยตรงเลย

https://line.me/ti/p/<account_name>

ให้กำหนด <account_name> ด้วยชื่อของ Account ที่ต้องการ

เพราะ LINE นั้นมีการกำหนด URL Scheme เป็น https://line.me อยู่แล้ว ดังนั้นจึงสามารถเรียกใช้งานด้วยคำสั่งแบบนี้ได้เลย

val uri = Uri.parse("https://line.me/ti/p/@linedevth")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)

สำหรับชื่อ Account ของ Official Account แต่ละเจ้า บอกเลยว่าเจ้าของบล็อกไม่รู้วิธีหาเหมือนกัน

เนื่องจากเป็น URL เข้าเว็ปธรรมดาๆ จึงสามารถเลือกได้ว่าจะเป็นบน Web Browser ที่มีอยู่ในเครื่อง หรือจะเปิดผ่าน LINE โดยตรง

ถ้าเลือก LINE ก็จะเข้าหน้า Official Account ที่กำหนดทันที แต่ถ้ากดเปิดผ่าน Web Browser ก็จะเป็นหน้าเว็ปของ LINE ที่มีปุ่มให้เลือกว่าจะดาวน์โหลดแอปฯหรือว่าเปิด URL ดังกล่าวบน LINE

จะเรียกว่าเป็นความสะดวกอย่างหนึ่งของ LINE เลยก็ว่าได้ เนื่องจาก LINE ไม่มีให้ใช้งานบนหน้าเว็ป ดังนั้นจึงสามารถกำหนด URL เพื่อให้เปิดบนแอปฯโดยตรงได้เลย

ข้อควรระวังสำหรับ Social ที่เปิดผ่าน URL Scheme

เนื่องจาก URL Scheme เป็น URL เฉพาะที่ถูกกำหนดไว้โดยมีเงื่อนไขว่าจะต้องมีแอปฯที่ติดตั้งอยู่ในเครื่องที่ดัก URL Scheme ดังกล่าวด้วย

ไม่เช่นนั้น Force Close แน่นอนจ้า

กำหนด URL Scheme อย่างถูกต้อง

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

private static final String FACEBOOK_PACAKAGE_NAME = "com.facebook.katana"; private static final String URL_SCHEME_SFL_PAGE = "fb://page/577361412281379"; private static final String URL_SFL_PAGE = "https://www.facebook.com/SleepingForLess"; ... if(isAppInstalled(context, FACEBOOK_PACAKAGE_NAME)) { openUrl(URL_SCHEME_SFL_PAGE); } else { openUrl(URL_SFL_PAGE); } ... private void openUrl(String url) { Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); } private boolean isAppInstalled(Context context, String packageName) { try { context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_ACTIVITIES); return true; } catch (PackageManager.NameNotFoundException ignored) { } return false; }

จากโค้ดตัวอย่างข้างบนนี้ก็จะทำการเช็คก่อนว่าเครื่องนั้นๆลงแอปฯ Facebook ไว้หรือไม่ (เช็คจาก Pacakage Name) ถ้ามีการติดตั้งไว้ก็จะเปิด URL Scheme แต่ถ้าไม่ได้ติดตั้งไว้ก็จะเปิด URL ธรรมดาแทน

และนอกจากวิธีการเปิด URL ธรรมดาๆแล้ว บางครั้งก็อาจจะใช้วิธีว่าถ้าไม่ได้ติดตั้งแอปฯก็ให้ไปติดตั้งแอปฯซะ

private const val FACEBOOK_PACKAGE_NAME = "com.facebook.katana"
private const val URL_SCHEME_SFL_PAGE = "fb://page/577361412281379"
...
if(isAppInstalled(context, FACEBOOK_PACAKAGE_NAME)) {
    openUrl(URL_SCHEME_SFL_PAGE);
} else {
    openAppInPlayStore(context, FACEBOOK_PACAKAGE_NAME);
}
private fun openUrl(url: String) {
    val uri: Uri = Uri.parse(url)
    val intent = Intent(Intent.ACTION_VIEW, uri)
    startActivity(intent)
}

private fun isAppInstalled(context: Context, packageName: String): Boolean {
    try {
        context.packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
        return true
    } catch (ignored: PackageManager.NameNotFoundException) {
    }
    return false
}

private fun openAppInPlayStore(context: Context, packageName: String) {
    try {
        context.startActivity(
            Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName"))
        )
    } catch (exception: ActivityNotFoundException) {
        context.startActivity(
            Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageName"))
        )
    }
}

และถ้าเครื่องนั้นดันไม่มี Google Play Store อีก ก็จะใช้วิธีเปิดหน้าผ่าน Web Browser แทน

จะใช้วิธีแบบไหนก็แล้วแต่ผู้ที่หลงเข้ามาอ่านจะเลือกใช้หรือตามที่ Requirement กำหนดไว้ ส่วนวิธีนอกเหนือจากสองวิธีนี้ก็เขียนเอาเองจ้า ไม่ยากหรอกเนอะ

สรุป

การเปิดหน้า Social App เพื่อให้แสดงหน้า Page หรือ Official Account ของ Social แต่ละตัวนั้นเป็นเรื่องที่นักพัฒนาบางคนก็มองข้ามไปเนื่องจากมองว่าเป็นเรื่องที่ไม่จำเป็นมากนัก แต่ก็ต้องใส่ไว้ ดังนั้นจึงนิยมแปะ URL จากเว็ปกันตรงๆ

ซึ่งในความเป็นจริงแล้วการเปิดหน้าเว็ปตรงๆอาจจะทำให้เกิดปัญหาผู้ใช้ไม่สามารถทำอะไรต่อได้เนื่องจากอาจจะไม่ได้ล็อกอินใช้งานบน Web Browser ดังนั้นทางที่ดีนักพัฒนาควรทำให้สามารถเปิดจากแอปฯได้ทันที ถ้ามีการติดตั้งแอปฯไว้ในเครื่องอยู่แล้ว เพื่อให้ผู้ใช้สามารถใช้งานได้ต่อทันที

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