com.android.dialer.lookup.openstreetmap.OpenStreetMapForwardLookup.java Source code

Java tutorial

Introduction

Here is the source code for com.android.dialer.lookup.openstreetmap.OpenStreetMapForwardLookup.java

Source

/*
 * Copyright (C) 2014 The OmniROM Project
 * Copyright (C) 2014 Xiao-Long Chen <chillermillerlong@hotmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Partially based on OmniROM's implementation

package com.android.dialer.lookup.openstreetmap;

import android.content.Context;
import android.location.Location;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.util.Log;

import com.android.dialer.calllog.ContactInfo;
import com.android.dialer.lookup.ContactBuilder;
import com.android.dialer.lookup.ForwardLookup;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale;

public class OpenStreetMapForwardLookup extends ForwardLookup {
    private static final String TAG = OpenStreetMapForwardLookup.class.getSimpleName();

    /** Search within radius (meters) */
    private static final int RADIUS = 30000;

    /** Query URL */
    private static final String LOOKUP_URL = "http://overpass-api.de/api/interpreter";

    private static final String LOOKUP_QUERY = "[out:json];node[name~\"%s\"][phone](around:%d,%f,%f);out body;";

    private static final String RESULT_ELEMENTS = "elements";
    private static final String RESULT_TAGS = "tags";
    private static final String TAG_NAME = "name";
    private static final String TAG_PHONE = "phone";
    private static final String TAG_HOUSENUMBER = "addr:housenumber";
    private static final String TAG_STREET = "addr:street";
    private static final String TAG_CITY = "addr:city";
    private static final String TAG_POSTCODE = "addr:postcode";
    private static final String TAG_WEBSITE = "website";

    public OpenStreetMapForwardLookup(Context context) {
    }

    @Override
    public ContactInfo[] lookup(Context context, String filter, Location lastLocation) {

        // The OSM API doesn't support case-insentive searches, but does
        // support regular expressions.
        String regex = "";
        for (int i = 0; i < filter.length(); i++) {
            char c = filter.charAt(i);
            regex += "[" + Character.toUpperCase(c) + Character.toLowerCase(c) + "]";
        }

        String request = String.format(Locale.ENGLISH, LOOKUP_QUERY, regex, RADIUS, lastLocation.getLatitude(),
                lastLocation.getLongitude());

        try {
            String httpResponse = httpPostRequest(request);

            JSONObject results = new JSONObject(httpResponse);

            return getEntries(results);
        } catch (IOException e) {
            Log.e(TAG, "Failed to execute query", e);
        } catch (JSONException e) {
            Log.e(TAG, "JSON error", e);
        }

        return null;
    }

    private ContactInfo[] getEntries(JSONObject results) throws JSONException {
        ArrayList<ContactInfo> details = new ArrayList<ContactInfo>();

        JSONArray elements = results.getJSONArray(RESULT_ELEMENTS);

        for (int i = 0; i < elements.length(); i++) {
            try {
                JSONObject element = elements.getJSONObject(i);
                JSONObject tags = element.getJSONObject(RESULT_TAGS);

                String displayName = tags.getString(TAG_NAME);
                String phoneNumber = tags.getString(TAG_PHONE);

                // Take the first number if there are multiple
                if (phoneNumber.contains(";")) {
                    phoneNumber = phoneNumber.split(";")[0];
                    phoneNumber = phoneNumber.trim();
                }

                // The address is split
                String addressHouseNumber = tags.optString(TAG_HOUSENUMBER, null);
                String addressStreet = tags.optString(TAG_STREET, null);
                String addressCity = tags.optString(TAG_CITY, null);
                String addressPostCode = tags.optString(TAG_POSTCODE, null);

                String address = String.format("%s %s, %s %s", addressHouseNumber != null ? addressHouseNumber : "",
                        addressStreet != null ? addressStreet : "", addressCity != null ? addressCity : "",
                        addressPostCode != null ? addressPostCode : "");

                address = address.trim().replaceAll("\\s+", " ");

                if (address.length() == 0) {
                    address = null;
                }

                String website = tags.optString(TAG_WEBSITE, null);

                ContactBuilder builder = new ContactBuilder(ContactBuilder.FORWARD_LOOKUP, null, phoneNumber);

                builder.setName(ContactBuilder.Name.createDisplayName(displayName));
                builder.addPhoneNumber(ContactBuilder.PhoneNumber.createMainNumber(phoneNumber));

                ContactBuilder.Address a = new ContactBuilder.Address();
                a.formattedAddress = address;
                a.city = addressCity;
                a.street = addressStreet;
                a.postCode = addressPostCode;
                a.type = StructuredPostal.TYPE_WORK;
                builder.addAddress(a);

                ContactBuilder.WebsiteUrl w = new ContactBuilder.WebsiteUrl();
                w.url = website;
                w.type = Website.TYPE_HOMEPAGE;
                builder.addWebsite(w);

                builder.setPhotoUri(ContactBuilder.PHOTO_URI_BUSINESS);

                details.add(builder.build());
            } catch (JSONException e) {
                Log.e(TAG, "Skipping the suggestions at index " + i, e);
            }
        }

        if (details.size() > 0) {
            return details.toArray(new ContactInfo[details.size()]);
        } else {
            return null;
        }
    }

    private String httpPostRequest(String query) throws IOException {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(LOOKUP_URL);

        post.setEntity(new StringEntity(query));

        return EntityUtils.toString(client.execute(post).getEntity());
    }
}