com.dmsl.anyplace.tasks.AnyplaceSuggestionsTask.java Source code

Java tutorial

Introduction

Here is the source code for com.dmsl.anyplace.tasks.AnyplaceSuggestionsTask.java

Source

/*
 * AnyPlace: A free and open Indoor Navigation Service with superb accuracy!
 *
 * Anyplace is a first-of-a-kind indoor information service offering GPS-less
 * localization, navigation and search inside buildings using ordinary smartphones.
 *
 * Author(s): Timotheos Constambeys, Lambros Petrou
 *
 * Supervisor: Demetrios Zeinalipour-Yazti
 *
 * URL: http://anyplace.cs.ucy.ac.cy
 * Contact: anyplace@cs.ucy.ac.cy
 *
 * Copyright (c) 2015, Data Management Systems Lab (DMSL), University of Cyprus.
 * All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in the
 * Software without restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

package com.dmsl.anyplace.tasks;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import org.apache.http.conn.ConnectTimeoutException;

import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Handler;

import com.dmsl.anyplace.cache.AnyplaceCache;
import com.dmsl.anyplace.googleapi.GooglePlaces;
import com.dmsl.anyplace.googleapi.PlacesList;
import com.dmsl.anyplace.nav.AnyPlaceSeachingHelper;
import com.dmsl.anyplace.nav.IPoisClass;
import com.dmsl.anyplace.nav.PoisModel;
import com.dmsl.anyplace.nav.AnyPlaceSeachingHelper.SearchTypes;
import com.dmsl.anyplace.utils.GeoPoint;

/**
 * The task that provides the Suggestions according to the zoom level and the position.
 */
public class AnyplaceSuggestionsTask extends AsyncTask<Void, Void, String> {

    public interface AnyplaceSuggestionsListener {
        void onSuccess(String result, List<? extends IPoisClass> pois);

        void onUpdateStatus(String string, Cursor cursor);

        void onErrorOrCancel(String result);
    }

    private AnyplaceSuggestionsListener mListener;
    private Context ctx;
    private final Object sync = new Object();
    private boolean run = false;

    private boolean exceptionOccured = false;
    private SearchTypes searchType;
    private GeoPoint position;
    private String query;
    private List<? extends IPoisClass> pois;

    private AnyplaceCache mAnyplaceCache = null;

    public AnyplaceSuggestionsTask(AnyplaceSuggestionsListener l, Context ctx, SearchTypes searchType,
            GeoPoint position, String query) {
        this.mListener = l;
        this.searchType = searchType;
        this.position = position;
        this.query = query;
        this.ctx = ctx;
        mAnyplaceCache = AnyplaceCache.getInstance(ctx);
    }

    public static boolean matchQueryPoi(String query, String poi) {
        query = query.toLowerCase(Locale.ENGLISH);
        poi = poi.toLowerCase(Locale.ENGLISH);
        String[] segs = poi.split(" ");

        for (String s : segs) {
            if (s.contains(query)) {
                return true;
            }
        }

        return false;
    }

    public List<PoisModel> queryStaticAnyPlacePOI(String query) throws IOException {
        Collection<PoisModel> pois = mAnyplaceCache.getPois();
        List<PoisModel> ianyplace = new ArrayList<PoisModel>();
        for (PoisModel pm : pois) {
            if (matchQueryPoi(query, pm.name) || matchQueryPoi(query, pm.description)) {
                ianyplace.add(pm);
            }
        }
        return ianyplace;
    }

    @Override
    protected String doInBackground(Void... params) {
        try {
            // get the search suggestions
            if (searchType == SearchTypes.INDOOR_MODE) {
                // if we are at a zoom level higher than 19 then we use the
                // AnyPlacePOI API

                // sleep for a while to avoid execution in case another task
                // started and check afterwards if you are cancelled
                Thread.sleep(150);
                if (isCancelled()) {
                    return "Cancelled!";
                }

                // use the 2-step method to get out quickly if this task is
                // cancelled
                List<PoisModel> places = queryStaticAnyPlacePOI(query);
                if (isCancelled()) {
                    return "Cancelled!";
                }

                // create the cursor for the results
                // cursor = AnyPlaceSeachingHelper.prepareSearchViewCursor(places);
                pois = places;

            } else if (searchType == SearchTypes.OUTDOOR_MODE) {
                // at a lower zoom level we use the Google Places API for search
                // in order to allow the user to search more coarsely for
                // locations

                // sleep for a while to avoid execution in case another task
                // started and check afterwards if you are cancelled
                Thread.sleep(500);
                if (isCancelled()) {
                    return "Cancelled!";
                }

                // Get a handler that can be used to post to the main thread
                Handler mainHandler = new Handler(ctx.getMainLooper());

                Runnable myRunnable = new Runnable() {

                    @Override
                    public void run() {
                        try {
                            List<IPoisClass> places = new ArrayList<IPoisClass>(1);
                            PoisModel pm = new PoisModel();
                            pm.name = "Searching through Google ...";
                            places.add(pm);
                            Cursor cursor = AnyPlaceSeachingHelper.prepareSearchViewCursor(places);
                            mListener.onUpdateStatus("Dummy Result", cursor);
                        } finally {
                            synchronized (sync) {
                                run = true;
                                sync.notifyAll();
                            }
                        }
                    }
                };

                mainHandler.post(myRunnable);

                // cursor = AnyplacePOIProvider.queryStatic(query,
                // AnyplacePOIProvider.POI_GOOGLE_PLACES, position);
                PlacesList places = GooglePlaces.queryStaticGoogle(query, position);
                if (isCancelled())
                    return "Cancelled!";

                // create the cursor for the results
                // cursor = AnyPlaceSeachingHelper.prepareSearchViewCursor(places.results);
                pois = places.results;

                synchronized (sync) {
                    while (run == false) {
                        sync.wait();
                    }
                }

            }

            if (isCancelled()) {
                return "Cancelled!";
            }

            return "Success!";

        } catch (ConnectTimeoutException e) {
            exceptionOccured = true;
            return "Connecting to the server is taking too long!";
        } catch (SocketTimeoutException e) {
            exceptionOccured = true;
            return "Communication with the server is taking too long!";
        } catch (IOException e) {
            exceptionOccured = true;
            return "Communication error[ " + e.getMessage() + " ]";
        } catch (InterruptedException e) {
            exceptionOccured = true;
            return "Suggestions task interrupted!";
        }

    }

    @Override
    protected void onProgressUpdate(Void... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(String result) {
        if (exceptionOccured) {
            // call the error listener
            mListener.onErrorOrCancel(result);
        } else {

            // call the success listener
            mListener.onSuccess(result, pois);

        }
    }

    @Override
    protected void onCancelled(String result) {
        // mListener.onErrorOrCancel(result);
    }

    @Override
    protected void onCancelled() { // just for < API 11
        // mListener.onErrorOrCancel("Anyplace Suggestions task cancelled!");
    }
}// end of suggestions task