22 ตุลาคม 2559

[Android Code] วันนี้แอปพลิเคชันของคุณรองรับ Multi Window ของ Samsung แล้วหรือยัง?



        ในทุกวันนี้ต้องบอกเลยว่าหนึ่งในฟีเจอร์หลักของอุปกรณ์แอนดรอยด์ประจำค่าย Samsung ก็คงหนีไม่พ้น Multi Window ที่เป็นฟีเจอร์ประจำตระกูล Samsung มานานหลายปีมากกับไอเดียที่ว่าผู้ใช้สามารถใช้งานแอปฯสองตัว (หรือหลายตัว) ได้พร้อมๆกันบนหน้าจอเดียวกัน


รู้จักกับ Multi Window จาก Samsung กันหรือยัง?

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


        สำหรับ Multi Window ของ Samsung นั้นมี 2 รูปแบบด้วยกันคือ

        • Split Screen การแบ่งหน้าจอเป็นสองส่วนเพื่อเปิดแอปฯแยกกัน สามารถปรับได้ว่าจะให้หน้าจอฝั่งไหนมีพื้นที่เยอะหรือน้อยกว่าอีกฝั่ง

        • Pop-up การแสดงหน้าต่างแอปฯแบบ Floating Window สามารถเปิดได้หลายๆแอปฯพร้อมๆกัน และสามารถย่อ/ขยายและย้ายตำแหน่งหน้าต่างได้ตามต้องการ

นี่มันเหมือนกับ Multi Window ของ Android 7.0 Nougat เลยนี่นา!

        อย่าเรียกว่าเหมือนเลยครับ.. เรียกว่า Android เอาฟีเจอร์นี้ของ Samsung ไปใส่เป็น Multi Window ใน Android 7.0 Nougat ดีกว่านะ...

        ซึ่งการทำงานของ Multi Window บน Samsung กับบน Android 7.0 นั้นถึงแม้จะมีผลลัพธ์ออกมาเหมือนกัน แต่กลับมีเบื้องหลังที่นักพัฒนาจะต้องจัดการที่แตกต่างกันอยู่นะ ซึ่งกรณีของ Multi Window ใน Android 7.0 สามารถไปอ่านเบื้องหลังกันได้จาก [Android Code] รู้จัก Multi Window บน Android N และวิธีการรับมือ


        ส่วนความแตกต่างระหว่างทั้งสองนั้น เดี๋ยวขอเล่าให้ฟังทีหลังนะ

เตรียมตัวให้พร้อม!! สู่ขั้นตอนที่ยุ่งยากมากๆ!!

ประกาศว่าแอปฯนี้รองรับ Multi Window นะจ๊ะ!

        เพิ่ม <meta-data> เข้าไปใน Android Manifest ดังนี้

<meta-data
    android:name="com.samsung.android.sdk.multiwindow.enable"
    android:value="true" />

        โดยประกาศไว้ใน <application> แต่ว่าอยู่ข้างนอก <activity> นะ เพราะถ้าประกาศผิดที่มันจะไม่มีผลใดๆ


        โดยคำสั่งดังกล่าวจะทำให้แอปฯของผู้ที่หลงเข้ามาอ่านรองรับกับ Multi Window โดยสังเกตได้จากเครื่องหมาย Multi Window เมื่ออยู่บนอุปกรณ์แอนดรอยด์ของ Samsung ที่รองรับ Multi Window เวลาเข้า Recent App


        เพิ่มเติม - อย่าแปลกใจถ้า Code Completion ของ Android Studio ไม่แสดงคำสั่งนี้ เพราะว่านี่คือคำสั่ง XML เฉพาะของ Samsung ซึ่ง Code Completion ไม่รู้อยู่แล้วว่ามีคำสั่งนี้ โดย <meta-data> เหล่านี้จะถูกอ่านเมื่อทำงานบนเครื่อง Samsung เท่านั้น

เพิ่ม App Icon ลงใน App Drawer ของ Multi Window

          ถ้าอยากให้แอปฯของผู้ที่หลงเข้ามาอ่านแสดงใน App Drawer ของ Multi Window ก็จะต้องเพิ่มโค้ดเข้าไปใน Android Manifest


        โดยกำหนดลงใน Activity ที่ต้องการได้เลยว่า

<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />

         ซึ่งแนะนำว่าเป็น Activity ตัวเดียวกับที่กำหนด Category เป็น Launcher ดีกว่านะ


อยากให้แอปฯเปิดได้แค่ตัวเดียวเท่านั้นหรือป่าว?

        เนื่องจาก Multi Window ทำให้เปิดแอปฯได้มากกว่าหนึ่งตัวพร้อมๆกัน ดังนั้นจึงเกิดคำถามต่อมาว่า "แล้วมันเปิดแอปฯตัวเดิมซ้ำๆได้มั้ย?" ซึ่ง Multi Window ของ Samsung ก็มีคำสั่งให้กำหนดได้ว่าอยากได้แบบไหน ผ่าน <meta-data> เหมือนเดิมนั่นเอง

<meta-data
    android:name="com.samsung.android.sdk.multiwindow.multiinstance.enable"
    android:value="true" />

        ถ้ากำหนดเป็น True หมายความว่าสามารถเปิดซ้ำหลายๆตัวได้ แต่ถ้าเป็น False จะทำให้เปิดได้แค่ตัวเดียวเท่านั้น



        สรุปโค้ดที่ใช้กำหนดการทำงานของ Multi Window ก็จะมีประมาณนี้

<?xml version="1.0" encoding="utf-8"?>
<manifest 
    ...>

    <application
        ...>

        <activity 
            ...>
            <intent-filter>
                ...

                <category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="com.samsung.android.sdk.multiwindow.enable"
            android:value="true" />

        <meta-data
            android:name="com.samsung.android.sdk.multiwindow.multiinstance.enable"
            android:value="true" />

        ...

    </application>

</manifest>

        สามารถปรับแต่งค่าได้ตามที่ต้องการ โดยอิงจากที่เจ้าของบล็อกอธิบายไว้ในแต่ละส่วนได้เลย

หมดแล้วจ้า ขั้นตอนยุ่งย๊าก ยุ่งยากจังเลยเนอะ

        นั่นล่ะฮะ ขั้นตอนทั้งหมดในการกำหนดให้แอปฯของผู้ที่หลงเข้ามาอ่านรองรับกับ Multi Window ซึ่งมีคำสั่งเยอะมากจนแทบจะจำไม่หมด (ประชด)

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

        เมื่อแอปฯถูกติดตั้งลงบนเครื่องของ Samsung ก็จะมีการอ่านค่าใน Android Manifest เหมือนแอนดรอยด์ทั่วๆไปน่ะแหละ แต่จะมีการอ่านค่าของ Multi Window เพิ่มเติมด้วย ซึ่งในกรณีที่เป็นเครื่องยี่ห้ออื่นก็จะไม่สนใจค่าดังกล่าว จึงเป็นที่มาว่าทำไมจึงไม่ส่งผลกระทบกับเครื่องยี่ห้ออื่นๆเลย

ความแตกต่างกันระหว่าง Multi Window ของ Samsung และ Android 7.0+ 

        อย่างที่บอกในตอนแรกว่าถึงแม้ทั้งคู่จะดูเหมือนกัน แต่ก็มีเบื้องหลังที่แตกต่างกันอยู่ ซึ่งส่งผลต่อนักพัฒนาสมควร แต่ว่าส่งผลอย่างไรให้ดูภาพตัวอย่างข้างล่างนี้ก่อน


        ในภาพนี้คือแอปฯของเจ้าของบล็อกที่เขียนขึ้นมาเอง โดยกำหนดว่าถ้าเปิดบนหน้าจอที่มีความกว้างมากกว่าที่กำหนด จะให้แสดงข้อมูลเป็น 2 คอลัมน์ แต่ถ้าหน้าจอแคบกว่านั้นก็จะแสดงเป็น 1 คอลัมน์เพื่อความเหมาะสม

Multi Window ของ Android 7.0+

        แต่สิ่งที่เกิดขึ้นคือบน Android 7.0+ นั้นแสดงผลปกติ ถ้าปรับให้พื้นที่ของแอปฯกว้างขึ้นก็จะแสดงเป็น 2 คอลัมน์ และถ้าพื้นที่ของแอปฯลดลงจนถึงขนาดที่กำหนดก็จะเหลือ 1 คอลัมน์ ซึ่งสิ่งที่เกิดขึ้นตอนปรับขนาดของหน้าต่างนี้เรียกว่า Configuration Change นั่นเอง (ถ้ายังไม่รู้จัก ให้ไปอ่านเพิ่มเติมได้ที่ [Android Code] Configuration Changes อีกหนึ่งอย่างที่นักพัฒนาแอนดรอยด์ควรรู้จัก)

        Android 7.0 ได้ออกแบบมาว่า Multi Window นั้นเมื่อมีการเปลี่ยนขนาดหน้าจอจะถือว่าเป็น Configuration Change ทั้งหมด ดังนั้นแอปฯจะต้องรองรับกับเงื่อนไขดังกล่าว ถึงจะทำงานได้สมบูรณ์แบบ

Multi Window ของ Samsung

        แต่สำหรับ Samsung ที่มีฟีเจอร์แบบนี้ตั้งแต่สมัยพระเจ้าเหา การจะไปกำหนดรูปแบบ Configuration Change แบบนี้ก็คงจะเป็นไปไม่ได้ (ทาง Samsung ก็ต้องคำนึงว่าจะทำยังไงให้นักพัฒนาใช้งานฟีเจอร์นี้ได้โดยส่งผลกระทบกับแอปฯเดิมที่มีอยู่ให้น้อยที่สุด) ดังนั้น Multi Window ของ Samsung เมื่อมีการปรับขนาดหน้าต่างจะไม่เกิด Configuration Change ใดๆเลย

        ดังนั้นเมื่อดูภาพตัวอย่างข้างบนจะเห็นว่า เมื่อแสดงเป็น Split Screen ที่มีขนาดหน้าจอแคบลง จำนวนคอลัมน์ก็จะยังเป็น 2 คอลัมน์เหมือนเดิม ทั้งนี้เพราะตัวแอปฯไม่ได้รับรู้ว่าขนาดหน้าจอเปลี่ยนแปลง (แต่เจ้าของบล็อกจัด Layout ให้ Responsive) ดังนั้นเมื่อ Configuration Change ไม่เกิดขึ้น ก็ทำให้ตัวแอปฯก็แค่บีบหน้าจอ Layout ให้แคปลงกว่าเดิมเท่านั้นเอง

ความแตกต่างอย่างที่ 2 คือ Orientation!!

        Multi Window บน Android 7.0+ นั้นไม่ได้อ้างอิง Orientation จากตัวเครื่อง แต่จะขึ้นอยู่กับขนาดหน้าต่างของแอปฯตัวนั้นๆ ถ้าหน้าต่างมีความกว้างมากกว่าความสูงก็จะเป็นแนวนอน (Landscape) และถ้าความสูงมากกว่าความกว้างก็จะเป็นแนวตั้ง (Portrait) ไปโดยปริยาย (จึงเป็นที่มาว่าควรทำแอปฯให้รองรับทั้งแนวตั้งและแนวนอน)


        แต่ Multi Window ของ Samsung นั้นจะขึ้นอยู่กับว่าผู้ใช้ถือเครื่องแนวตั้งหรือแนวนอนเท่านั้น โดยไม่สนใจว่าหน้าต่าง ณ ตอนนั้นจะกว้างหรือสูงเท่าไรก็ตาม

ความแตกต่างอย่างที่ 3 Pop-up View กับ Freeform Mode

        ของ Samsung จะเรียกว่า Pop-up View ในขณะที่ของ Android 7.0+ จะเรียกว่า Freeform Mode แต่มันก็คือรูปแบบการทำงานที่เหมือนกันนะ แต่ถึงแม้ว่าจะเป็นหน้าต่างเล็กๆที่ย้ายตำแหน่งไปมาได้ก็ตาม


        Multi Window ของ Samsung จะทำได้แค่ย่อ/ขยายขนาดหน้าต่างโดยที่สัดส่วนหน้าจอยังเท่าเดิม (เท่ากับหน้าจอ) ไม่สามารถปรับเฉพาะความกว้างหรือเฉพาะความสูงได้ เพราะว่า Samsung ใช้วิธี Scale ขนาดหน้าจอโดยที่ไม่ส่งผลกับค่า DP ดังนั้นจึงทำให้ Layout ภายในแอปฯยังคงแสดงผลได้เหมือนเดิม

        แต่สำหรับของ Android 7.0+ นั้นจะปรับได้อิสระมาก ดังนั้นขนาดหน้าต่างจึงไม่ตายตัว และมีผลต่อค่า DP ด้วย ทำให้ Layout มีการเปลี่ยนแปลงไปตามขนาดหน้าจอ และที่สำคัญคือการปรับขนาดหน้าจอนั้นถือว่าเป็น Configuration Change นะ

        ดังนั้นในกรณี Pop-up View ของ Samsung บอกเลยว่า ไม่ต้องทำอะไร เพราะตัวเครื่องจัดการให้เองทุกอย่างโดยไม่ส่งผลกระทบกับตัวแอปฯแต่อย่างใด

ถ้าอยากทำบางอย่างเกี่ยวกับ Multi Window ผ่าน Java Code มี SDK ให้ด้วยนะ!

        ถึงแม้ว่า Multi Window ของ Samsung จะรองรับได้ทันทีเพียงแค่ใส่ XML ให้ถูกต้อง แต่ก็อาจจะมีนักพัฒนาบางคนต้องการเรียกใช้คำสั่งบางอย่างของ Multi Window ภายในโค้ด ซึ่งทาง Samsung ก็ได้ทำเป็น SDK ให้ดาวน์โหลดไปใช้งานกันได้ฟรีๆเลย สามารถไปดาวน์โหลดได้ที่ MultiWindow SDK [Samsung Developer]

        ดูเหมือนว่าตัวหน้าเว็ปพึ่งจะอัปเดตใหม่ หน้าตาเปลี่ยนไปเล็กน้อย แอบตกใจพอสมควร เพราะหาปุ่มดาวน์โหลดไม่เจอ ฮาๆ


        ตามด้วย License Agreement เล็กน้อยที่อ่านหน่อยก็ดีนะ จากนั้นยอมรับเงื่อนไขแล้วกดปุ่ม Download ซะ



        เมื่อดาวน์โหลดเสร็จแล้วให้เปิดเข้าไปดูข้างในก็จะเห็นไฟล์ .jar อยู่ 2 ไฟล์


        ให้เอาไฟล์ทั้ง 2 ไปไว้ในโปรเจคของผู้ที่หลงเข้ามาอ่านซะ ใส่ไว้ใน libs แล้ว Build Gradle ใหม่หนึ่งคร้ัง เป็นอันพร้อมใช้งาน


        เพิ่มเติม - ไลบรารีจำพวกไฟล์ .jar จะทำงานได้ทันทีเมื่อเอาไปใส่ใน libs ทั้งนี้เพราะใน build.gradle จะกำหนดไว้ให้เรียบร้อยแล้ว

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    ...
}

        ดังนั้นถ้าโปรเจคของผู้ที่หลงเข้ามาอ่านคนใดมีปัญหา ไลบรารีไม่สามารถใช้งานได้ ก็ให้ลองเข้าไปดูใน  build.gradle ของโปรเจคดูก่อนว่ามีโค้ดแบบตัวอย่างข้างบนอยู่หรือไม่ ถ้าไม่มีก็ใส่เพิ่มเข้าไปซะแล้ว Build Gradle ใหม่หนึ่งครั้ง

        ส่วนคำสั่งมีอะไรให้ใช้งานบ้าง ก็ลองเข้าไปดูใน API Reference ของ MultiWindow SDK กันแทนละกันเนอะ ขี้เกียจอธิบาย

ต้นทุนในการทำแอปฯให้รองรับ Multi Window ของ Samsung

        • เพิ่มโค้ด XML แค่ 3 ชุดใน Android Manifest
        • แอปฯควรจะรองรับทั้งหน้าจอแนวตั้งและแนวนอน รวมไปถึง Responsive ด้วย (จริงๆก็เป็นเรื่องพื้นฐานที่ควรทำอยู่แล้วนะ)

         เอาเข้าจริง เป็นต้นทุนที่น้อยมากๆเลยนะเนี่ย... ลูกค้าเปลี่ยน Requirement ยังมีต้นทุนเยอะกว่าอีก

เหตุผลดีๆที่ว่าทำไมควรทำแอปฯให้รองรับ Multi Window ของ Samsung

        • เพราะผู้ใช้แอปฯของนักพัฒนาส่วนใหญ่ล้วนเป็นเครื่อง Samsung เพราะงั้นก็การใส่ฟีเจอร์ที่ Exclusive สำหรับผู้ใช้เหล่านี้จึงไม่สูญเปล่าแน่นอน
        • ต้นทุนในการพัฒนาแค่นิดเดียว
        • Multi Window SDK ใช้งานฟรี (เพราะทาง Samsung ต้องการให้นักพัฒนานำไปใช้งาน)
        • สร้างเอกลักษณ์ที่แตกต่างจากแอปฯอื่นๆ

สรุป 

        สำหรับ Multi Window ก็มีมานมนานมาก (ราวๆ 4 ปี) ซึ่งเป็นฟีเจอร์ที่มีอยู๋ในเครื่อง Samsung แทบทุกเครื่องแล้วในทุกวันนี้ ซึ่งเจ้าของบล็อกชอบก็ตรงที่ Samsung ได้ทำเป็น SDK มาให้นักพัฒนาได้ใช้งานกัน (รวมไปถึงฟีเจอร์อื่นๆด้วย) ในขณะที่ยี่ห้ออื่นๆที่ทำฟีเจอร์เหล่านี้แต่กลับทำขึ้นมาเพื่อใช้งานกับแอปฯของตัวเองเท่านั้น ไม่ได้มี SDK ให้ใช้งาน ไม่ได้คำนึงนักพัฒนาที่อยากทำแอปฯให้รองรับกับฟีเจอร์เหล่านั้น

        แต่ถ้าเครื่อง Samsung ได้อัปเกรดเป็น Android 7.0 กันแล้ว ก็ไม่รู้เหมือนกันนะว่าเค้าจะใช้ Multi Window ของ Samsung เหมือนเดิม หรือว่าเปลี่ยนไปใช้ของ Android 7.0 กันแน่ ก็ต้องรอติดตามดูกันต่อไป (ถ้าสรุปได้ยังไงก็จะมาเพิ่มข้อมูลในบทความนี้ให้)

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

        แล้วจะรอช้าอยู่ใยล่ะครับ?




เหล่าพันธมิตรแอนดรอยด์

Devahoy Layer Net NuuNeoI The Cheese Factory Somkiat CC Mart Routine Artit-K Arnondora Kamonway Try to be android developer Oatrice Benz Nest Studios Kotchaphan@Medium Jirawatee@Medium Travispea@Medium