09 กุมภาพันธ์ 2557

[Android Code] มาลองเล่นกับ Assist บนแอนดรอยด์กันบ้าง


        วันนี้เจ้าของบล็อกจะมาแนะนำความรู้ใหม่ๆสำหรับผู้ที่หลงเข้ามาอ่านหลายๆคนกันเสียหน่อย เมื่อมาเห็นชื่อบทความนี้อาจจะเข้าใจว่าเป็นระบบช่วยเหลืออะไรหรือป่าว? แต่จริงๆแล้วก็ไม่ใช่ซักเท่าไร เป็นฟีเจอร์ที่ผู้ที่หลงเข้ามาอ่านบางคนใช้อยู่บ่อยๆด้วยซ้ำ


        อาจจะเห็นวีดีโอข้างบนนี้แล้วร้องอ๋อทันที หรืออาจจะไม่รู้ว่ามีทำแบบนี้ได้ด้วย (ฮา) อันนี้เป็นกรณีที่เครื่องเป็นแบบ Software Button เท่านั้น แต่ถ้าเรื่องที่เป็นปุ่มกดล่ะ?  ขอเรียกว่า Hardware Button ละกันนะ

        เช่น Nexus S ที่มีปุ่มอยู่ 4 ปุ่ม จะมีปุ่มที่เป็นเครื่องหมายแว่นขยาย นั่นล่ะเป็นปุ่มเรียก Assist ขึ้นมา


        แต่ถ้าเป็นปุ่มแบบ Back, Home และ Recent App อย่างเช่น Acer ก็ให้กด Home ค้าง



        สำหรับปุ่มแบบ Back, Home และ Menu อย่างเช่น Sony หรือ Samsung นั้นขึ้นอยู่กับว่าเค้าใส่มาให้หรือป่าว เพราะจากที่เจ้าของบล็อกไปลองของ Sony ที่เป็นปุ่มแบบนี้ ก็หาวิธีเรียกขึ้นมาไม่ได้ ส่วนของ Samsung เรียกได้โดยกดที่ Menu ค้างเพื่อเรียก Recent App แล้วจะมีไอคอนปุ่มให้กดอยู่ตรงกลางล่าง



        หมายเหตุ - ความสามารถนี้ถูกเพิ่มเข้ามาในแอนดรอยด์เวอร์ชัน 4.1 ขึ้นไปเท่านั้น

        อันนี้แหละที่เจ้าของบล็อกเรียกว่า Assist ผู้ที่หลงเข้ามาอ่านหลายๆคนอาจจะเข้าใจว่ามันคือการเรียก Google Now แต่ว่าจริงๆแล้วไม่ถูกต้องซักเท่าไรนัก เพราะมันคือการเรียก Assist แล้วเจ้า Assist เนี่ยถูกตั้งเป็น Default ไว้ให้เรียกไปที่ Google Now ทันทีนั่นเอง

        ดังนั้นหมายความว่ายังไงล่ะ?

        หมายความว่า....

        เวลาเรียก Assist แล้วสามารถกำหนดให้เปิดแอปพลิเคชันที่ผู้ที่หลงเข้ามาอ่านเป็นคนสร้างขึ้นมาได้หรือไม่?

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


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

<action android:name="android.intent.action.ASSIST" />
<category android:name="android.intent.category.DEFAULT" />


        อยากจะให้ Assist เปิดมาที่ Activity แรกสุดที่กำหนดไว้ในแอปพลิเคชันก็กำหนดดังนี้

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.assist"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.assist.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.ASSIST" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


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

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.assist"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.assist.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="app.akexorcist.assist.Activity1" >
            <intent-filter>
                <action android:name="android.intent.action.ASSIST" />

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

        </activity>
        <activity android:name="app.akexorcist.assist.Activity2" />
        <activity android:name="app.akexorcist.assist.Activity3" />
    </application>

</manifest>

        จะเห็นว่าเจ้าของบล็อกไม่ได้ให้ Assist ไปเรียก Activity หลักที่ชื่อว่า Main แต่อย่างใด แต่ให้เรียกไปที่ Activity1 แทน โดยหน้า Activity เจ้าของบล็อกก็ค่อยเขียนคำสั่งสำหรับเวลาที่ผู้ใช้เรียกผ่าน Assist นั่นเอง


        หยุดเรื่องโปรแกรมก่อน กลับมาดูวิธีการเรียก Assist อีกครั้งนึง เวลาเรียก Assist จะเห็นว่าปุ่มเป็นรูปวงกลมที่มีคำว่า Google อยู่ตรงกลาง



        แต่จากที่เจ้าของบล็อกให้ใส่คำสั่งใน Android Manifest ให้ผู้ที่หลงเข้ามาอ่านแล้วลองติดตั้งลงเครื่องดู จากนั้นเรียก Assist อีกครั้ง ทีนี้จะเห็นว่าจากเดิมที่เป็นคำว่า Google ได้เปลี่ยนเป็นรูปแว่นขยายแล้ว



        จากนั้นจะมี Dialog แสดงขึ้นมาให้เลือกว่าจะเปิดแอปพลิเคชันไหน


        ทั้งนี้ก็เพราะว่าเดิมทีนั้นแอปพลิเคชันที่รองรับ Assist นั้นมีแต่ Google เท่านั้น (แล้ว Google ก็จะไปเรียก Google Now อีกทอดนึง) แต่ทีนี้มีมากกว่าหนึ่งแอปพลิเคชันที่รองรับการ Assist ดังนั้นระบบจึงถามผู้ใช้ว่าจะให้เปิดอันไหน ในกรณีที่อยากให้เปิดอันใดอันหนึ่งตลอดโดยไม่ต้องถาม ก็ให้เลือกแอปพลิเคชันที่ต้องการแล้วกด Always ได้เลย

        เมื่อกำหนด Always แล้ว เท่านี้ก็สามารถเรียก Assist แล้วเปิดแอปพลิเคชันที่ได้สร้างไว้ได้แล้ว~


        ถ้าอยากยกเลิก Always แล้วให้ระบบถามใหม่อีกครั้งว่าจะให้เปิดแอปพลิเคชันไหน ให้ไปเคลียร์ Default ที่แอปพลิเคชันนั้นๆทิ้งก่อน ก็คือกำหนดแอปพลิเคชันไหนเป็น Default (Always) ไว้ ก็ให้ไปกดเคลียร์ได้ที่ App Info ของแอปพลิเคชันนั้นๆ



        แต่เดี๋ยวก่อน....

        ไอคอนตอนเรียก Assist มันยังเป็นรูปแว่นขยายอยู่เลย ทำไมตอนกำหนดเป็น Google แล้วเป็นรูปวงกลมมีคำว่า Google ตรงกลางล่ะ? กำหนดภาพได้ด้วยหรอ?

        ถูกต้องครับ สามารถกำหนดภาพตอนเรียก Assist ได้ด้วย โดยกำหนดใน Android Manifest (อีกแล้ว) เพิ่มลงไปดังนี้

<meta-data 
    android:name="com.android.systemui.action_assist_icon"
    android:resource="@drawable/image" />


        โดยที่ image ก็คือภาพที่เก็บไว้ใน drawable นั้นเอง ผู้ที่หลงเข้ามาอ่านสามารถกำหนดได้ว่าจะให้ภาพไหนแสดง ซึ่งจะต้องประกาศคำสั่งนี้ไว้ต่อท้าย intent-filter ที่กำหนดเป็น Assist

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.assist"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.assist.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>            
        </activity>        
        <activity
            android:name="app.akexorcist.assist.AssistActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.ASSIST" />
                
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            
            <meta-data 
                android:name="com.android.systemui.action_assist_icon"
                android:resource="@drawable/image" />
            
        </activity>
    </application>

</manifest>

        เท่านี้ก็จะเห็นว่าเวลาเรียก Assist ขึ้นมา ถ้ากำหนดแอปพลิเคชันตัวนี้ไว้เป็น Default ก็จะเห็นไอคอนเป็นรูปที่กำหนดไว้แล้ว



        หมายเหตุ - ไม่สามารถกำหนดไอคอนแล้วไปใช้งานบนเครื่องของ Samsung ที่เป็นเวอร์ชันต่ำกว่า 4.4 ได้ เพราะ TouchWiz UI จะปิดตัวลง เป็นเพราะ TouchWiz UI ไม่ได้รองรับนั่นเอง แต่ถ้าไม่กำหนดไอคอนก็ยังคงสามารถใช้งานได้ปกติ

        และนอกจากนี้ยังสามารถกำหนดเป็น Selector ได้อีกด้วย ก็คือตอนยังไม่เลือกเป็นอีกภาพนึง เมื่อเลื่อนไปอยู่บนปุ่มดังกล่าวก็เป็นอีกภาพนึง และเมื่อเลือกปุ่มก็จะเป็นอีกภาพนึง

        อ๊ะๆ! ถ้ายังไม่รู้จัก Selector ให้ไปอ่านบทความนี้ก่อน [Android Design] เปลี่ยนภาพ Button ได้ดั่งใจด้วย Selector [Custom Button]

        สำหรับภาพที่ใช้ใน Assist จะมีสถานะอยู่ด้วยกันทั้งหมด 3 สถานะ คือ

                • Normal : ภาพในสถานะปกติ

                • Focused : เมื่อเลื่อนนิ้วไปอยู่บนภาพเดิมที่เป็น Normal

                • Active : เมื่อยกนิ้วขึ้น หลังจากที่กำลัง Focused อยู่ (เลือกน่ะแหละ)

        ทั้งนี้ทั้งนั้นบนเครื่องที่เป็นปุ่มกดที่ต้องกด Menu ค้างอาจจะเห็นแค่สถานะ Normal กับ Active มั้ง (ไม่แน่ใจ เพราะไม่มีเครื่องทดสอบ)

        โดยเจ้าของบล็อกกำหนดภาพในสถานะต่างๆเรียงลำดับกันเลยดังนี้


        วงกลมสีเหลือง กำหนดให้เป็นภาพสำหรับ Normal โดยชื่อภาพเป็น ic_assist_normal

        วงกลมสีฟ้า กำหนดให้เป็นภาพสำหรับ Focused โดยชื่อภาพเป็น ic_assist_pressed

        วงกลมสีแดง กำหนดให้เป็นภาพสำหรับ Active โดยชื่อภาพเป็น ic_assist_active


        แล้วเจ้าของบล็อกก็สร้างไฟล์ XML สำหรับทำเป็น Selector ดังนี้


assist_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    
    <item 
        android:state_active="false"
        android:state_focused="false"
        android:drawable="@drawable/ic_assist_normal" />
    
    <item 
        android:state_active="true"
        android:state_focused="false"
        android:drawable="@drawable/ic_assist_active" />

    <item
        android:state_active="false"
        android:state_focused="true"
        android:drawable="@drawable/ic_assist_pressed" />
    
</selector>


        ดังนั้นใน Android Manifest เจ้าของบล็อกก็จะต้องกำหนดเป็นดังนี้

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.assist"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.assist.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity
            android:name="app.akexorcist.assist.AssistActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.ASSIST" />
                
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            
            <meta-data 
                android:name="com.android.systemui.action_assist_icon"
                android:resource="@drawable/assist_selector" />
        </activity>
    </application>

</manifest>

        สำหรับ Java กับ Layout คงไม่ต้องแปะให้ดูหรอกมั้ง เพราะมันไม่มีอะไรเลย... แค่ Activity สองไฟล์ กับ Layout สองไฟล์ อันนึงสำหรับหน้าหลัก และอีกอันสำหรับหน้า Assist ซึ่งผู้ที่หลงเข้ามาอ่านคงจะพอเดากันได้เนอะ

        ตอนทดสอบก็ลองดูการเปลี่ยนแปลงของสีปุ่มใน Assist ดู

        เมื่อกดปุ่ม Home ค้างไว้จน Asist โผล่ขึ้นมาจะเห็นว่าเป็นปุ่มสีเหลือง (Normal)



        เมื่อเลื่อนนิ้วไปวางบนปุ่มสีเหลืองก็จะกลายเป็นสีฟ้า (Focused)



        เมื่อปล่อยนิ้วเพื่อเลือก ก็จะกลายเป็นสีแดง (Active) แล้วแอปพลิเคชันที่ตั้งไว้ก็จะโผล่ขึ้นมา



        เจ้า Assist สามารถทำประโยชน์อะไรได้บ้าง?

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


        ซึ่งเจ้าของบล็อกได้ลองเขียนเล่นๆขึ้นมาในระหว่างที่ทดลองเรื่อง Assist เพื่อมาเขียนบทความนี้น่ะแหละ ถ้าผู้ที่หลงเข้ามาอ่านคนใดสนใจอยากลองใช้ สามารถดาวน์โหลดได้ที่

Get it on Google Play


        ส่วนผู้ที่หลงเข้ามาอ่านคนใดอยากได้ไฟล์ตัวอย่างบทความนี้ก็สามารถดาวน์โหลดได้จาก

                Assist [Google Drive]

                Assist [GitHub]

                Assist [Sleeping For Less]




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

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