Loading src/com/android/dialer/lookup/LookupSettings.java +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ public final class LookupSettings { public static final String RLP_YELLOWPAGES_CA = "YellowPages_CA"; public static final String RLP_ZABASEARCH = "ZabaSearch"; public static final String RLP_CYNGN_CHINESE = "CyngnChinese"; public static final String RLP_DASTELEFONBUCH = "DasTelefonbuch"; public static final String RLP_DEFAULT = RLP_OPENCNAM; private LookupSettings() { Loading src/com/android/dialer/lookup/ReverseLookup.java +6 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.dialer.lookup; import com.android.dialer.calllog.ContactInfo; import com.android.dialer.lookup.cyngn.CyngnChineseReverseLookup; import com.android.dialer.lookup.dastelefonbuch.TelefonbuchReverseLookup; import com.android.dialer.lookup.opencnam.OpenCnamReverseLookup; import com.android.dialer.lookup.whitepages.WhitePagesReverseLookup; import com.android.dialer.lookup.yellowpages.YellowPagesReverseLookup; Loading Loading @@ -52,6 +53,8 @@ public abstract class ReverseLookup { INSTANCE = new ZabaSearchReverseLookup(context); } else if (provider.equals(LookupSettings.RLP_CYNGN_CHINESE)) { INSTANCE = new CyngnChineseReverseLookup(context); } else if (provider.equals(LookupSettings.RLP_DASTELEFONBUCH)) { INSTANCE = new TelefonbuchReverseLookup(context); } } Loading @@ -76,6 +79,9 @@ public abstract class ReverseLookup { } else if (provider.equals(LookupSettings.RLP_CYNGN_CHINESE) && INSTANCE instanceof CyngnChineseReverseLookup) { return true; } else if (provider.equals(LookupSettings.RLP_DASTELEFONBUCH) && INSTANCE instanceof TelefonbuchReverseLookup) { return true; } else { return false; } Loading src/com/android/dialer/lookup/dastelefonbuch/TelefonbuchApi.java 0 → 100644 +165 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 Danny Baumann <dannybaumann@web.de> * * 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. */ package com.android.dialer.lookup.dastelefonbuch; import android.content.Context; import android.net.Uri; import com.android.dialer.lookup.LookupSettings; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TelefonbuchApi { private static final String TAG = TelefonbuchApi.class.getSimpleName(); private static final String REVERSE_LOOKUP_URL = "http://www.dastelefonbuch.de/?s=a20000" + "&cmd=search&sort_ok=0&sp=55&vert_ok=0&aktion=23"; private static final String USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0"; private TelefonbuchApi() { } public static ContactInfo reverseLookup(Context context, String number) throws IOException { Uri uri = Uri.parse(REVERSE_LOOKUP_URL) .buildUpon() .appendQueryParameter("kw", number) .build(); String output = httpGet(uri.toString()); String name = parseName(output); if (name == null) { return null; } String phoneNumber = parseNumber(output); String address = parseAddress(output); ContactInfo info = new ContactInfo(); info.name = name; info.address = address; info.formattedNumber = phoneNumber != null ? phoneNumber : number; info.website = uri.toString(); return info; } private static String httpGet(String url) throws IOException { HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(url); get.setHeader("User-Agent", USER_AGENT); HttpResponse response = client.execute(get); int status = response.getStatusLine().getStatusCode(); // Android's org.apache.http doesn't have the RedirectStrategy class if (status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY) { Header[] headers = response.getHeaders("Location"); if (headers != null && headers.length != 0) { String newUrl = headers[headers.length - 1].getValue(); return httpGet(newUrl); } else { return null; } } if (status != HttpStatus.SC_OK) { return null; } return EntityUtils.toString(response.getEntity()); } private static String parseName(String output) { Pattern regex = Pattern.compile("<a id=\"name0.*?>\\s*\n?(.*?)\n?\\s*</a>", Pattern.DOTALL); Matcher m = regex.matcher(output); if (m.find()) { return m.group(1).trim().replaceAll("&", "&"); } return null; } private static String parseNumber(String output) { Pattern regex = Pattern.compile("<span\\s+class=\"ico fon.*?>.*<span>(.*?)</span>", Pattern.DOTALL); Matcher m = regex.matcher(output); if (m.find()) { return m.group(1).trim(); } return null; } private static String parseAddress(String output) { String regexBase = "<span\\s+itemprop=\"%s\"\\s?>(.*?)</span>"; Pattern regexAddress = Pattern.compile( String.format(regexBase, "street-address"), Pattern.DOTALL); Matcher addressMatcher = regexAddress.matcher(output); if (!addressMatcher.find()) { return null; } Pattern regexPostal = Pattern.compile( String.format(regexBase, "postal-code"), Pattern.DOTALL); Matcher postalMatcher = regexPostal.matcher(output); if (!postalMatcher.find()) { return null; } Pattern regexLocation = Pattern.compile( String.format(regexBase, "locality"), Pattern.DOTALL); Matcher locationMatcher = regexLocation.matcher(output); if (!locationMatcher.find()) { return null; } StringBuilder sb = new StringBuilder(); sb.append(addressMatcher.group(1).trim()).append(", "); sb.append(postalMatcher.group(1).trim()).append(" "); sb.append(locationMatcher.group(1).trim()); return sb.toString(); } public static class ContactInfo { String name; String city; String address; String formattedNumber; String website; } } src/com/android/dialer/lookup/dastelefonbuch/TelefonbuchReverseLookup.java 0 → 100644 +92 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 Danny Baumann <dannybaumann@web.de> * * 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. */ package com.android.dialer.lookup.dastelefonbuch; import android.content.Context; import android.net.Uri; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import android.util.Pair; import com.android.dialer.calllog.ContactInfo; import com.android.dialer.lookup.ContactBuilder; import com.android.dialer.lookup.ReverseLookup; import java.io.IOException; public class TelefonbuchReverseLookup extends ReverseLookup { private static final String TAG = TelefonbuchReverseLookup.class.getSimpleName(); public TelefonbuchReverseLookup(Context context) { } /** * Perform phone number lookup. * * @param context The application context * @param normalizedNumber The normalized phone number * @param formattedNumber The formatted phone number * @return The phone number info object */ public Pair<ContactInfo, Object> lookupNumber(Context context, String normalizedNumber, String formattedNumber) { TelefonbuchApi.ContactInfo info = null; if (normalizedNumber.startsWith("+") && !normalizedNumber.startsWith("+49")) { // Das Telefonbuch only supports German numbers return null; } try { info = TelefonbuchApi.reverseLookup(context, normalizedNumber); } catch (IOException e) { return null; } if (info == null) { return null; } ContactBuilder builder = new ContactBuilder( ContactBuilder.REVERSE_LOOKUP, normalizedNumber, formattedNumber); ContactBuilder.Name n = new ContactBuilder.Name(); n.displayName = info.name; builder.setName(n); ContactBuilder.PhoneNumber pn = new ContactBuilder.PhoneNumber(); pn.number = info.formattedNumber; pn.type = Phone.TYPE_MAIN; builder.addPhoneNumber(pn); if (info.address != null) { ContactBuilder.Address a = new ContactBuilder.Address(); a.formattedAddress = info.address; a.type = StructuredPostal.TYPE_HOME; builder.addAddress(a); } ContactBuilder.WebsiteUrl w = new ContactBuilder.WebsiteUrl(); w.url = info.website; w.type = Website.TYPE_PROFILE; builder.addWebsite(w); return Pair.create(builder.build(), null); } } Loading
src/com/android/dialer/lookup/LookupSettings.java +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ public final class LookupSettings { public static final String RLP_YELLOWPAGES_CA = "YellowPages_CA"; public static final String RLP_ZABASEARCH = "ZabaSearch"; public static final String RLP_CYNGN_CHINESE = "CyngnChinese"; public static final String RLP_DASTELEFONBUCH = "DasTelefonbuch"; public static final String RLP_DEFAULT = RLP_OPENCNAM; private LookupSettings() { Loading
src/com/android/dialer/lookup/ReverseLookup.java +6 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.dialer.lookup; import com.android.dialer.calllog.ContactInfo; import com.android.dialer.lookup.cyngn.CyngnChineseReverseLookup; import com.android.dialer.lookup.dastelefonbuch.TelefonbuchReverseLookup; import com.android.dialer.lookup.opencnam.OpenCnamReverseLookup; import com.android.dialer.lookup.whitepages.WhitePagesReverseLookup; import com.android.dialer.lookup.yellowpages.YellowPagesReverseLookup; Loading Loading @@ -52,6 +53,8 @@ public abstract class ReverseLookup { INSTANCE = new ZabaSearchReverseLookup(context); } else if (provider.equals(LookupSettings.RLP_CYNGN_CHINESE)) { INSTANCE = new CyngnChineseReverseLookup(context); } else if (provider.equals(LookupSettings.RLP_DASTELEFONBUCH)) { INSTANCE = new TelefonbuchReverseLookup(context); } } Loading @@ -76,6 +79,9 @@ public abstract class ReverseLookup { } else if (provider.equals(LookupSettings.RLP_CYNGN_CHINESE) && INSTANCE instanceof CyngnChineseReverseLookup) { return true; } else if (provider.equals(LookupSettings.RLP_DASTELEFONBUCH) && INSTANCE instanceof TelefonbuchReverseLookup) { return true; } else { return false; } Loading
src/com/android/dialer/lookup/dastelefonbuch/TelefonbuchApi.java 0 → 100644 +165 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 Danny Baumann <dannybaumann@web.de> * * 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. */ package com.android.dialer.lookup.dastelefonbuch; import android.content.Context; import android.net.Uri; import com.android.dialer.lookup.LookupSettings; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TelefonbuchApi { private static final String TAG = TelefonbuchApi.class.getSimpleName(); private static final String REVERSE_LOOKUP_URL = "http://www.dastelefonbuch.de/?s=a20000" + "&cmd=search&sort_ok=0&sp=55&vert_ok=0&aktion=23"; private static final String USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0"; private TelefonbuchApi() { } public static ContactInfo reverseLookup(Context context, String number) throws IOException { Uri uri = Uri.parse(REVERSE_LOOKUP_URL) .buildUpon() .appendQueryParameter("kw", number) .build(); String output = httpGet(uri.toString()); String name = parseName(output); if (name == null) { return null; } String phoneNumber = parseNumber(output); String address = parseAddress(output); ContactInfo info = new ContactInfo(); info.name = name; info.address = address; info.formattedNumber = phoneNumber != null ? phoneNumber : number; info.website = uri.toString(); return info; } private static String httpGet(String url) throws IOException { HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(url); get.setHeader("User-Agent", USER_AGENT); HttpResponse response = client.execute(get); int status = response.getStatusLine().getStatusCode(); // Android's org.apache.http doesn't have the RedirectStrategy class if (status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY) { Header[] headers = response.getHeaders("Location"); if (headers != null && headers.length != 0) { String newUrl = headers[headers.length - 1].getValue(); return httpGet(newUrl); } else { return null; } } if (status != HttpStatus.SC_OK) { return null; } return EntityUtils.toString(response.getEntity()); } private static String parseName(String output) { Pattern regex = Pattern.compile("<a id=\"name0.*?>\\s*\n?(.*?)\n?\\s*</a>", Pattern.DOTALL); Matcher m = regex.matcher(output); if (m.find()) { return m.group(1).trim().replaceAll("&", "&"); } return null; } private static String parseNumber(String output) { Pattern regex = Pattern.compile("<span\\s+class=\"ico fon.*?>.*<span>(.*?)</span>", Pattern.DOTALL); Matcher m = regex.matcher(output); if (m.find()) { return m.group(1).trim(); } return null; } private static String parseAddress(String output) { String regexBase = "<span\\s+itemprop=\"%s\"\\s?>(.*?)</span>"; Pattern regexAddress = Pattern.compile( String.format(regexBase, "street-address"), Pattern.DOTALL); Matcher addressMatcher = regexAddress.matcher(output); if (!addressMatcher.find()) { return null; } Pattern regexPostal = Pattern.compile( String.format(regexBase, "postal-code"), Pattern.DOTALL); Matcher postalMatcher = regexPostal.matcher(output); if (!postalMatcher.find()) { return null; } Pattern regexLocation = Pattern.compile( String.format(regexBase, "locality"), Pattern.DOTALL); Matcher locationMatcher = regexLocation.matcher(output); if (!locationMatcher.find()) { return null; } StringBuilder sb = new StringBuilder(); sb.append(addressMatcher.group(1).trim()).append(", "); sb.append(postalMatcher.group(1).trim()).append(" "); sb.append(locationMatcher.group(1).trim()); return sb.toString(); } public static class ContactInfo { String name; String city; String address; String formattedNumber; String website; } }
src/com/android/dialer/lookup/dastelefonbuch/TelefonbuchReverseLookup.java 0 → 100644 +92 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 Danny Baumann <dannybaumann@web.de> * * 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. */ package com.android.dialer.lookup.dastelefonbuch; import android.content.Context; import android.net.Uri; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import android.util.Pair; import com.android.dialer.calllog.ContactInfo; import com.android.dialer.lookup.ContactBuilder; import com.android.dialer.lookup.ReverseLookup; import java.io.IOException; public class TelefonbuchReverseLookup extends ReverseLookup { private static final String TAG = TelefonbuchReverseLookup.class.getSimpleName(); public TelefonbuchReverseLookup(Context context) { } /** * Perform phone number lookup. * * @param context The application context * @param normalizedNumber The normalized phone number * @param formattedNumber The formatted phone number * @return The phone number info object */ public Pair<ContactInfo, Object> lookupNumber(Context context, String normalizedNumber, String formattedNumber) { TelefonbuchApi.ContactInfo info = null; if (normalizedNumber.startsWith("+") && !normalizedNumber.startsWith("+49")) { // Das Telefonbuch only supports German numbers return null; } try { info = TelefonbuchApi.reverseLookup(context, normalizedNumber); } catch (IOException e) { return null; } if (info == null) { return null; } ContactBuilder builder = new ContactBuilder( ContactBuilder.REVERSE_LOOKUP, normalizedNumber, formattedNumber); ContactBuilder.Name n = new ContactBuilder.Name(); n.displayName = info.name; builder.setName(n); ContactBuilder.PhoneNumber pn = new ContactBuilder.PhoneNumber(); pn.number = info.formattedNumber; pn.type = Phone.TYPE_MAIN; builder.addPhoneNumber(pn); if (info.address != null) { ContactBuilder.Address a = new ContactBuilder.Address(); a.formattedAddress = info.address; a.type = StructuredPostal.TYPE_HOME; builder.addAddress(a); } ContactBuilder.WebsiteUrl w = new ContactBuilder.WebsiteUrl(); w.url = info.website; w.type = Website.TYPE_PROFILE; builder.addWebsite(w); return Pair.create(builder.build(), null); } }