16 มกราคม 2556

[Android Code] การใช้ Listener กับ Camera ใน Google Maps Android API v2


* Google Maps Android API v2 ไม่สามารถรันทดสอบบน AVD ได้ *

คราวนี้ก็มาต่อกันด้วย Event Listener ของ Camera กันต่อเลย
ซึ่ง Listener สำหรับมุมกล้องของแผนที่ก็จะมีอยู่แบบเดียว
คือ OnCameraChangeListener ที่ทำงานเมื่อเลื่อนมุมกล้อง
ดังนั้นบทความนี้ก็จะไม่ค่อยมีอะไรมากมายนัก มีแค่นี้แหละ


โดยที่ Listener นี้จะทำงานเมื่อมุมกล้องอยู่เลื่อนตำแหน่งเท่านั้น
ดังนั้นระหว่างที่มุมกล้องกำลังเลื่อนตำแหน่งอยู่ก็จะไม่ทำงาน
ซึ่งน่าเสียดายเล็กน้อยเหมือนกันนะ ที่ไม่มีฟังก์ชันตอนกำลังเลื่อน

สำหรับ OnCameraChangeListener ก็จะเรียกใช้งานดังนี้
GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager() .findFragmentById(R.id.map)).getMap(); mMap.setOnCameraChangeListener(new OnCameraChangeListener() { public void onCameraChange(CameraPosition arg0) { ... } });
หัวใจสำคัญของ OnCameraChangeListener ก็คือ arg0
(ในกรณีที่กำหนดเป็นชื่อตัวแปรอื่น ก็ตามที่กำหนดไว้) 
ซึ่ง arg0 นั้นจะเป็น Object ของคลาส CameraPosition 
ที่จะมีค่าต่างๆของ Camera ที่ส่งมาให้ในฟังก์ชัน ดังนี้

arg0.bearing : มุมที่หมุนไป (ทิศเหนือชี้บนเป็น 0 องศา)

arg0.target.latitude : ละติจูดของแผนที่เมื่อเลื่อนตำแหน่งเสร็จ

arg0.target.longitude : ลองจิจูดของแผนที่เมื่อเลื่อนตำแหน่งเสร็จ

arg0.tilt : มุมเอียงของแผนที่ (มองจากด้านบนของแผนที่เป็น 0)

arg0.zoom : ระดับการซูมมุมกล้องของแผนที่ ณ ตอนนั้นๆ 


ทีนี้ก็มาดูตัวอย่างกันเลยดีกว่า เพราะไม่มีอะไรแล้ว

Main.java



1. ประกาศ textView1 คราวนี้เปลี่ยนตัวอย่างมาใช้เป็น final บ้าง
ปกติเจ้าของบล็อกประกาศไว้ข้างนอกฟังก์ชัน onCreate ตลอด

2. ประกาศ mMap และกำหนดเป็น R.id.map ที่ได้สร้างไว้ใน Layout

3. กำหนด Listener เป็น onCameraChangeListener ให้กับ mMap

4. เมื่อมุมกล้องมีการเลื่อนตำแหน่งจะมีการแสดงค่าใน textView1
โดยจะแบ่งออกเป็น 5 บรรทัดด้วยกัน โดยจะมี Rotate (มุมที่หมุน),
Latitude (ละติจูด), Longitude (ลองจิจูด), Tilt (มุมเอียง) และ Zoom (ระดับซูม) 
แต่ละบรรทัดจะมีการแสดงค่าที่ได้จาก arg0 เพื่อให้รู้ค่า ณ ตอนนั้นๆ



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



Main.java
package app.akexorcist.googlemapsv2cameralistener;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.model.CameraPosition;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.TextView;

public class Main extends FragmentActivity {    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        final TextView textView1 = (TextView)findViewById(R.id.textView1);
        
        GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
            public void onCameraChange(CameraPosition arg0) {                
                textView1.setText("Rotate : " 
                        + String.valueOf(arg0.bearing) 
                        + "\nLatitude : " 
                        + String.valueOf(arg0.target.latitude)
                        + "\nLongitude : " 
                        + String.valueOf(arg0.target.longitude)
                        + "\nTilt : " + String.valueOf(arg0.tilt)
                        + "\nZoom : " + String.valueOf(arg0.zoom));
            }
        });
    }
}

main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Main" >

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="60dp"
        android:shadowColor="#000000"
        android:shadowRadius="5"
        android:text="TextView"
        android:textColor="#FFFFFF" />

</RelativeLayout>

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />
    
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name=
            "com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name=
            "app.akexorcist.googlemapsv2cameralistener.permission.MAPS_RECEIVE"/>
      
    <permission 
        android:name=
            "app.akexorcist.googlemapsv2cameralistener.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>
    
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.googlemapsv2cameralistener.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>
        <meta-data
           android:name="com.google.android.maps.v2.API_KEY"
           android:value="your_api_key"/>
    </application>
</manifest>


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

เมื่อดาวน์โหลดตัวอย่างไป Import แล้วให้ตรวจสอบตามนี้
• ใส่ API Key ที่ไปขอจาก Google API ลงใน AndroidManifest.xml
• เลือก Library ของ google-play-services_lib ให้ตรงกับเครื่อง

อาจจะมีปัญหาพอสมควรสำหรับผู้ที่ดาวน์โหลดไปทดสอบ
เพราะว่าการใช้ Google Maps นี้มีการขอ API Key และ Library
ดังนั้นจึงควรตรวจสอบให้แน่ใจว่าได้กำหนดไว้ถูกต้องแล้ว 
และก็อย่าลืมว่าทดสอบบน AVD หรือ Emulator ไม่ได้นะ
เพราะต้องมี Play Store ซึ่ง AVD ไม่มี ทำให้แอป Force Close




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

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