IV.Mốc ranh giới(Landmark)

Landmark là một vị trí vật lý với tên đại diện cho vị trí tới người dùng cuối. Location API cho phép người dùng tạo ra, thêm, lưu trữ, lấy ra hay xóa các Landmark. Hai lớp Landmark và LandmarkStore cung cấp các chức năng kể trên. Lớp Landmark đại diện cho thông tin của mốc ranh giới, các thông tin đó bao gồm: tên, mô tả, các thông tin địa chỉ và các tọa độ. Thông tin địa chỉ chính là lớp AddressInfo.

Landmark(String name, String description,
              QualifiedCoordinates coordinates, AddressInfo addressInfo)

Ví dụ: cách tạo ra một Landmark

...
AddressInfo textAddress = new AddressInfo();
textAddress.setField(AddressInfo.COUNTRY , "UK");
textAddress.setField(AddressInfo.CITY , "London");
 Landmark landmark =
  new Landmark("My Restaurant”,” My Restaurant best in  the world",
                       new QualifiedCoordinates(11.289496608768690, 34.59678880927362,460, 31.32, 45.000)
                       , textAddress);
...

LandmarkStore là một vùng được chia sẽ để lưu trữ, chỉnh sữa và xóa Landmark. Thông tin Landmark có thể được lưu trữ trong data store và có thể được sử dụng sau này khi ứng dụng cần nó.

Landmark cũng có thể được phân loại trong LandmarkStore. Các Landmark có tên và có thể được đặt trong một hay nhiều chuyên mục(category). Mỗi chuyên mục được thiết kế để nhóm các Landmark có cùng kiểu đến người dùng cuối. Tất cả cơ sở dữ liệu của LandmarkStore phải được chia sẽ bởi tất cả các ứng dụng J2ME và có thể được chia sẽ bởi các ứng dụng native.

Ví dụ sau đây mô tả cách tạo ra LandmarkStore và LandmarkStore Category

...
/*Check if the Landmark Store already exists*/
String allLandmarkStores[] = LandmarkStore.listLandmarkStores();
boolean isStoreExist=false;
for(int i=0; i< allLandmarkStores.length; i++) {
    if(allLandmarkStores [i].equals("MyLandmarks")) {
        isStoreExist = true;
    }
}

/*Create a new Lanmark Store if the store does not exist*/
if(!isStoreExist){                
   LandmarkStore.createLandmarkStore("MyLandmarkStore");
}
myLmStore = LandmarkStore.getInstance("MyLandmarkStore");
/*Add category*/
myLmStore.addCategory("Restaurant");
...

1.Thêm một Landmark vào LandmarkStore

Lớp LandmarkStore cung cấp phương thức addLandmark(Landmark landmark, String category) để thêm một đối tượng Landmark vào LandmarkStore. Đối số Category có thể là: Home, Restaurants…

Đoạn code sau mô tả cách thêm một đối tượng Landmark vào LandmarkStore:

...
Criteria cr = new Criteria();
/*Accuracy set to 100 Meters*/
cr.setHorizontalAccuracy(100);
/*Get LocationProvider*/
LocationProvider provider = LocationProvider.getInstance(cr);

/*180 secs time out*/
Location location = provider.getLocation(180);
QualifiedCoordinates c = location.getQualifiedCoordinates();
double latitude = c.getLatitude();
double longitude = c.getLongitude();
float altitude = c.getAltitude();
float hAccuracy = c.getHorizontalAccuracy();
float vAccuracy = c.getVerticalAccuracy();

/*Same Address Info for all landmarks.*/
AddressInfo textAddress = new AddressInfo();
textAddress.setField(AddressInfo.COUNTRY , "MyCountry");
textAddress.setField(AddressInfo.STATE , "MyState");
textAddress.setField(AddressInfo.CITY , "MyCity");
textAddress.setField(AddressInfo.STREET , "MyStreet");

Landmark landmark =
   new Landmark(name, description,
          new QualifiedCoordinates(latitude, longitude, altitude, hAccuracy, vAccuracy),
          textAddress);
...

2.Nhận đối tượng Landmark từ LandmarkStore

Để nhận đối tượng Landmark từ LandmarkStore, chỉ cần gọi phương thức getLandmarks() từ LandmarkStore.

Đoạn code sau mô tả cách lấy các đối tượng Landmark từ LandmarkStore

...
try {                   
  Enumeration landmarkEnum = MyLandmarkStore.getLandmarks();
  while (landmarkEnum.hasMoreElements()) {
    Landmark myLandmark = (Landmark)landmarkEnum.nextElement();
    double lmLatitude = myLandmark.getQualifiedCoordinates().getLatitude();
    double lmLongitude =        
          myLandmark.getQualifiedCoordinates().getLatitude();
    String landmarkName = myLandmark.getName();
    String lmCountry=    
          landmark.getAddressInfo().getField(AddressInfo.COUNTRY);

    form.append(“landmarkName  “+landmarkName + " Latitude: " +lmLatitude +
                      " Longitude: " + lmLongitude +" Country: " +lmCountry);
  }
}catch(Exception e){
  form.append(“No Landmarks in MyLandmarkStore”);
}
...

3.Xóa đối tượng Landmark từ LandmarkStore:

Để xóa đối tượng Landmark từ LandmarkStore, chỉ cần gọi phương thức deleteLandmark(Landmark landmark). Ngoài ra, để xóa LandmarkStore, ta gọi phương thức deleteLandmarkStore(String storeName).

Đoạn code dưới đây mô tả cách xóa Landmark từ tất cả các chuyên mục và xóa cả thông tin từ LandmarkStore.

...
try{
/*Check if the Landmark Store already exists*/
String allLandmarkStores[] = LandmarkStore.listLandmarkStores();
boolean isStoreExist=false;
for(int i=0; i< allLandmarkStores.length; i++) {
  if(allLandmarkStores [i].equals("MyLandmarks")) {
    isStoreExist = true;
  }
}
if(isStoreExist)
  LandmarkStore .deleteLandmarkStore(“MyLandmarks”);
}catch(Exception e)
{
  form.append(“Exception at deleting Landmark”+e);
}
...

V.Định hướng(Orientation)

Lớp Orientation đại diện cho hướng vật lý của thiết bị(la bàn định hướng). Ứng dụng không chỉ xác định vị trí của thiết bị mà còn cả hướng của nó nếu thiết bị có một compass.

Sử dụng phương thức getOrientation() để lấy về đối tượng Orientation, cụ thể như sau:

...
Orientation orientation = Orientation.getOrientation();
float azimuth = orientation.getCompassAzimuth();
float pitch = orientation.getPitch();
float roll = orientation.getRoll();
boolean isOrientationMagnetic = orientation.isOrientationMagnetic();
form.append(“azimuth ”+azimuth+” pitch ”+pitch+
                 ” roll ”+roll+” isOrientationMagnetic ”+ isOrientationMagnetic);
...

Trong ví dụ trên, phương thức isOrientationMagnetic() cho biết hướng  này có liên quan đến từ trường của trái đất hay liên quan đến hướng bắc và trọng lực.

VI.Bảo mật và cấp phép

Các phương thức được kiệt kê dưới đây sẽ ném một SecurityException nếu người dùng không cấp phép truy cập vào các hoạt động về lấy vị trí.

Tên cấp phép Các phương thức được cấp phép
javax.microedition.location.Location LocationProvider.getLocation(), LocationProvider.setLocationListener()
javax.microedition.location.Orientation Orientation.getOrientation()
javax.microedition.location.ProximityListener LocationProvider.addProximityListener()
javax.microedition.location.LandmarkStore.read LandmarkStore.getInstance(), LandmarkStore.listLandmarkStores()
javax.microedition.location.LandmarkStore.write LandmarkStore.addLandmark(), LandmarkStore.deleteLandmark(), LandmarkStore.removeLandmarkFromCategory(), LandmarkStore.updateLandmark()
javax.microedition.location.LandmarkStore.category LandmarkStore.addCategory(), LandmarkStore.deleteCategory()
javax.microedition.location.LandmarkStore.management LandmarkStore.createLandmarkStore(), LandmarkStore.deleteLandmarkStore()

VII.Ví dụ

Ví dụ 1: mô tả cách sử dụng Location API để nhận thông tin Location.

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;

import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationProvider;

import javax.microedition.location.QualifiedCoordinates;
import javax.microedition.midlet.MIDlet;

public class LocationMidlet extends MIDlet implements CommandListener,
                                                                                  Runnable{

    /* Define String Constants */
    private final String locate_String = "Locate";
    private final String exit_String = "Exit";
    private final String done_String = "Done";
    private final String locationForm_Title_String = "Location Demo";
    private final String locationInfo_String =
             "Press Locate Command to start Application Demo\n";
    private final String exitInfo_String = "Press Exit Command to exit Application \n";
    /*LocationMidlet Display */
    private Display display;

    /*LocationMidlet Commands*/
    private Command cmd_Locate, cmd_Exit, cmd_Done;

    /*LocationMidlet Form*/
    private Form locationForm;

    /** location provider */
    private LocationProvider locationProvider = null;
    private Location location;
    private QualifiedCoordinates coordinates;

    private Thread locationThread;

    /*LocationMidlet Constructor*/
    public LocationMidlet()
    {
        /*Intialize Commands*/
        cmd_Locate = new Command(locate_String, Command.OK,1);
        cmd_Done   = new Command(done_String, Command.OK,1);
        cmd_Exit   = new Command(exit_String, Command.EXIT,2);

        /*Create Form*/
        locationForm = new Form(locationForm_Title_String);

        /*Appending location and Exit Information*/
        locationForm.append(locationInfo_String);
        locationForm.append(exitInfo_String);

        /*Adding commands to Location Form*/
        locationForm.addCommand(cmd_Exit);
        locationForm.addCommand(cmd_Locate);
        locationForm.setCommandListener(this);
        /*Intialize display*/
        display = Display.getDisplay(this);

        /*Create LocationProvider Instance*/
        locationProvider = null;
        createLocationProvider();
        if(locationProvider == null)
        {
            displayError();           
        }
    }

    public void startApp() {
        /*display Form*/
        display.setCurrent(locationForm);
    }

    public void pauseApp() {

        /*your code to handle interrupt*/
    }

    public void destroyApp(boolean unconditional) {
        /*your code before notifyDestroyed method*/
        notifyDestroyed();
    }

    private void exitMidlet()
    {
        destroyApp(true);
    }

    private void displayError()
    {
        locationForm.deleteAll();
        locationForm.append("Unable to create LocationProvider");
        locationForm.addCommand(cmd_Exit);
    }

    /*Initialize LocationProvider using Default Criteria*/
    private void createLocationProvider() {
        if (locationProvider == null) {
            /*Constructs a Criteria object. All the fields are set to the default values*/
            Criteria criteria = new Criteria();
            /* criteria Fields which you can set
            criteria.setCostAllowed(true); //default value
            criteria.setSpeedAndCourseRequired(true);
            criteria.setHorizontalAccuracy(500);
            criteria.setAltitudeRequired(true);
            criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_LOW);
            */

            try {
                locationProvider = LocationProvider.getInstance(criteria);
            } catch (LocationException le) {  
                /*Unable to create Location Provider using this criteria*/
                le.printStackTrace();
            }
        }
    }

    private void createLocation()
    {       
        try {
            // Get a location fix for 30 seconds timeout
            location = locationProvider.getLocation(30);
        } catch (LocationException ex) {
            ex.printStackTrace();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }    
    }

    private void getLocationResults()
    {
        coordinates = location.getQualifiedCoordinates();
    }

    private void displayLocationResults()
    {
        /*
         locationForm.append("Course"+loc.getCourse());
         locationForm.append("Speed"+loc.getSpeed());
         */
        locationForm.append("Altitude:"+coordinates.getAltitude() +"\n");
        locationForm.append("Latitude:"+coordinates.getLatitude() +"\n");
        locationForm.append("Longitude:"+coordinates.getLongitude() +"\n");
    }

    public void commandAction(Command cmd, Displayable disp) {
        if(cmd == cmd_Locate)
        {
            /*Deleting previous data displayed*/
            locationForm.deleteAll();
            /*Removing exit and locate command*/
            locationForm.removeCommand(cmd_Exit);
            locationForm.removeCommand(cmd_Locate);
            /*Adding done command*/
            locationForm.addCommand(cmd_Done);
            /*Create Thread to avoid deadlock*/
            locationThread = new Thread(this);
            locationThread.start();           
        }else
        if(cmd == cmd_Exit)
        {
            exitMidlet();
        }else
        if(cmd == cmd_Done)
        {
            locationForm.deleteAll();

            /*Remove done command*/
            locationForm.removeCommand(cmd_Done);

            /*Adding commands to Location Form*/
            locationForm.addCommand(cmd_Exit);
            locationForm.addCommand(cmd_Locate);

            /*Appending location and Exit Information*/
            locationForm.append(locationInfo_String);
            locationForm.append(exitInfo_String);

        }
    }

    public void run() {
        /*Get Location*/
        createLocation();
        /*Get Location Results*/
        getLocationResults();
        /*Display Results*/
        displayLocationResults();
    }
}

Ví dụ 2: Mô tả cách thêm, lưu, nhận và xóa Landmark

import java.io.IOException;

import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;

import javax.microedition.location.AddressInfo;
import javax.microedition.location.Coordinates;
import javax.microedition.location.Landmark;
import javax.microedition.location.LandmarkException;
import javax.microedition.location.LandmarkStore;
import javax.microedition.location.QualifiedCoordinates;

import javax.microedition.midlet.MIDlet;

public class LandmarkMidlet extends MIDlet implements CommandListener,
                                                                                    Runnable{
    private final String OFFICE_CATEGORY = "OFFICE";
    private LandmarkStore landmarkStore = null;

    private final int ADD_LANDMARK = 1;
    private final int SHOW_LANDMARK = ADD_LANDMARK + 1;
    private final int DELETE_LANDMARK = SHOW_LANDMARK + 1;

    private int landmarkState;

    private List landmarkList;
    private Command cmd_Exit;
    private Command cmd_showLandmark, cmd_deleteLandmark;
    private Command cmd_addLandmark;
    private Display display;

    private Thread landmarkThread;
    private Vector landmarkVector;

    public LandmarkMidlet()
    {
        landmarkList = new List("Landmark Demo", List.IMPLICIT);

        cmd_Exit = new Command("Exit", Command.EXIT, 1);
        /* cmd_addCategory = new Command("Add Category", Command.SCREEN, 1); */
        cmd_addLandmark = new Command("Add Landmark", Command.SCREEN, 1);
        /* cmd_showCategory = new Command("show Category", Command.SCREEN, 1); */
        cmd_showLandmark = new Command("show Landmark", Command.SCREEN, 1);
        cmd_deleteLandmark = new Command("delete Landmark", Command.SCREEN, 1);
        /* cmd_deleteCategory = new Command("delete Category", Command.SCREEN, 1);*/

        landmarkList.addCommand(cmd_Exit);
        landmarkList.addCommand(cmd_addLandmark);
        landmarkList.addCommand(cmd_showLandmark);
        landmarkList.addCommand(cmd_deleteLandmark);

        landmarkList.setCommandListener(this);

        landmarkVector = new Vector();

        display = Display.getDisplay(this);

        display.setCurrent(landmarkList);
    }

    public void startApp() {
        loadLandmarks();
    }

    public void pauseApp() {
        /*your code to handle interrupts*/
    }

    public void destroyApp(boolean unconditional) {
        /*your code before notifyDestroyed*/
        notifyDestroyed();
    }

    private void exitMidlet()
    {
        destroyApp(true);
    }

    private void loadLandmarks() {
        landmarkStore = LandmarkStore.getInstance(null);
        /*Added Office Category in LandmarkStore*/
        addLandmarkCategory();
    }

    /*
    private void getLandmarkCategory() {
        Enumeration c = landmarkStore.getCategories();
        boolean exists;
        for (exists = false; c.hasMoreElements() ;)
        {
            String abc = (String)c.nextElement();           
        }       
    }
     */

    private void addLandmarkCategory()
    {
        try {
            Enumeration c = landmarkStore.getCategories();
            boolean exists;
            for (exists = false; c.hasMoreElements() ;)
            {
                String category = (String)c.nextElement();
                if (category.equals(OFFICE_CATEGORY)) {
                    exists = true;
                    break;
                }
            }
            /*If Office Category doesn’t exists then add Office Category
             in LandmarkStore*/
            if(!exists)           
                landmarkStore.addCategory(OFFICE_CATEGORY);
        } catch (IOException ex) {           
            ex.printStackTrace();
        } catch (LandmarkException ex) {           
            ex.printStackTrace();
        }
    }

    private void addLandmark()
    {      
        /*Latitude range -90 to 90 degrees*/
        /*Longitude range -180 to 180 degrees*/
        QualifiedCoordinates officeCoordinates =
                    new QualifiedCoordinates(85.0, 85.0, 100, 500, 500);

        AddressInfo officeAddressInfo = new AddressInfo();
        officeAddressInfo.setField(AddressInfo.STREET, "OfficeStreet");
        officeAddressInfo.setField(AddressInfo.CITY, "OfficeCity");
        officeAddressInfo.setField(AddressInfo.POSTAL_CODE, "123456");
        officeAddressInfo.setField(AddressInfo.PHONE_NUMBER, "1234567890");

        Landmark landmark1 =
             new Landmark("My Office", "Office Description",
                    (QualifiedCoordinates) officeCoordinates, officeAddressInfo);

        try {
            /*Category needs to be present before adding Landmark
             * addLandmarkCategory() adds category
             */
            landmarkStore.addLandmark(landmark1, OFFICE_CATEGORY);
            /*Refresh List with newly added Landmark*/
            showLandmark();
        } catch (IOException ex) {
            /*Landmark could not be added to Office category*/
            ex.printStackTrace();
        }
    }

    /*
    private void showCategory()
    {
        //delete data in form
        Enumeration c = landmarkStore.getCategories();
        boolean exists;
        for (exists = false; c.hasMoreElements() ;) {
            String category = (String)c.nextElement();
            //append in Form
        }
    }
     */

    private void showLandmark()
    {
        try {
            //delete landmarks in list and vector
            landmarkVector.removeAllElements();
            landmarkList.deleteAll();
            Enumeration c = landmarkStore.getLandmarks();           
            boolean exists;
            /*returns null if no landmark is present in landmarkStore Category*/
            for (exists = false; c!=null && c.hasMoreElements();) {
                Landmark landmark = (Landmark) c.nextElement ();
                landmarkVector.addElement(landmark);
                landmarkList.append(landmark.getName(), null);               
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void deleteLandmark()
    {
        int landmarkIndex = landmarkList.getSelectedIndex();
        /*Check to avoid OutofBoundsException*/
        if(landmarkIndex>-1)
        {           
            Landmark landmark =
                 (Landmark)landmarkVector.elementAt(landmarkIndex);
            try {
                landmarkStore.deleteLandmark(landmark);
            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (LandmarkException ex) {
                ex.printStackTrace();
            }
            /*Refresh List*/
            showLandmark();
        }
    }

    public void commandAction(Command cmd, Displayable disp) {
        if(cmd_Exit == cmd)
        {
            exitMidlet();
        }else
        if(cmd_addLandmark == cmd)
        {
            landmarkState  = ADD_LANDMARK;
            landmarkThread = new Thread(this);
            landmarkThread.start();
        }else
        if(cmd_showLandmark == cmd)
        {
            showLandmark();
        }else
        if(cmd_deleteLandmark == cmd)
        {
            landmarkState  = DELETE_LANDMARK;
            landmarkThread = new Thread(this);
            landmarkThread.start();           
        }
    }

    public void run() {
        if(ADD_LANDMARK == landmarkState)       
            addLandmark();
        else
        if(DELETE_LANDMARK == landmarkState)                   
            deleteLandmark();

        landmarkState = -1;
    }
}

Ví dụ 3: mô tả cách lấy Orientation

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.location.Orientation

public class OrientationMidlet extends MIDlet implements CommandListener {

    private Command exitCmd  = new Command("Exit", Command.EXIT, 1);
    private Display display;
    private Form mainForm;

    public OrientationMidlet(){
    }

    protected void destroyApp(boolean unconditional){

    }

    protected void pauseApp(){
    }

    protected void startApp()throws MIDletStateChangeException{
        display = Display.getDisplay(this);
        mainForm = new Form("OrientationMidlet");
        mainForm.addCommand(exitCmd);
        mainForm.setCommandListener(this);
        getOrientation();
        display.setCurrent(mainForm);
    }

    private void getOrientation()
    {
            Orientation orientation = Orientation.getOrientation();
            float azimuth = orientation.getCompassAzimuth();
            float pitch = orientation.getPitch();
            float roll = orientation.getRoll();
            boolean isOrientationMagnetic = orientation.isOrientationMagnetic();                    

            mainForm.append("“azimuth "+“azimuth);
            mainForm.append("pitch "+pitch);
            mainForm.append("roll "+roll);
            mainForm.append("isOrientationMagnetic "+isOrientationMagnetic);
    }

    public void commandAction(Command c, Displayable d) {
        if (c == exitCmd) {
            destroyApp(false);
            notifyDestroyed();       
        }   
    }
 }
Các bài liên quan:
Location API(JSR 79) trên J2ME - Phần 1