/** * 文 件 名: SuggestionService.java * 描 述: * 版 权: Copyright (c)20010-2011 motone All Rights Reserved. * 公 司: 摩通科技 * 作 者: 黄悦 * 版 本: 1.0 * 创建时间: 2010-12-15 * * 修改历史: * 时间 作者 版本 描述 * ------------------------------------------------------------------ * 2010-12-15 黄悦 1.0 1.0 Version */ package com.mogoo.launcher2; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Binder; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; import com.mogoo.launcher.R; import com.mogoo.launcher2.search.AppsSource; import com.mogoo.launcher2.search.Source; import com.mogoo.launcher2.search.WebSource; import com.mogoo.launcher2.utils.Mogoo_BitmapCache; public class Mogoo_SuggestionService extends Service { private SuggestionBinder mBinder = new SuggestionBinder(); private static final boolean DBG = false; private static final String LOG_TAG = "GoogleSearch"; private static final String USER_AGENT = "Android/1.0"; private static final int HTTP_TIMEOUT_MS = 1000; // TODO: this should be defined somewhere private static final String HTTP_TIMEOUT = "http.connection-manager.timeout"; private DefaultHttpClient mHttpClient; private String mSuggestUri; public static final int WEB_CURSOR_TYPE = 1; public static final int DEFAULT_CURSOR_TYPE = 0; public static final String KEYWORD_KEY = "query"; public static final String CURSOR_TYPE_KEY = "cursor_type"; private LauncherModel mLauncherModel; private Resources mRes; @Override public IBinder onBind(Intent intent) { int cursorType = intent.getIntExtra(CURSOR_TYPE_KEY, DEFAULT_CURSOR_TYPE); String keyword = intent.getStringExtra(KEYWORD_KEY); ArrayList<Source> sources = null; sources = queryApps(keyword); if (cursorType == WEB_CURSOR_TYPE) { ArrayList<Source> temp = queryWeb(keyword); if(temp != null){ sources.addAll(temp); temp.clear(); temp = null; } } if(mBinder.sources != null){ mBinder.sources.clear(); } mBinder.sources = null; mBinder.sources = sources; return mBinder; } @Override public void onCreate() { super.onCreate(); mHttpClient = new DefaultHttpClient(); HttpParams params = mHttpClient.getParams(); params.setLongParameter(HTTP_TIMEOUT, HTTP_TIMEOUT_MS); // NOTE: Do not look up the resource here; Localization changes may not // have completed // yet (e.g. we may still be reading the SIM card). mSuggestUri = null; } @Override public boolean onUnbind(Intent intent) { mHttpClient.clearResponseInterceptors(); mHttpClient.clearRequestInterceptors(); mHttpClient = null; mBinder = null; return super.onUnbind(intent); } public class SuggestionBinder extends Binder { private ArrayList<Source> sources; public Mogoo_SuggestionService getService() { return Mogoo_SuggestionService.this; } public ArrayList<Source> getSources() { return sources; } } private ArrayList<Source> queryApps(String query) { //add by 张永辉 改为从系统中读取 ArrayList<Source> sources = new ArrayList<Source>(); final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); final PackageManager packageManager = getPackageManager(); List<ResolveInfo> apps = packageManager .queryIntentActivities(mainIntent, 0); LauncherApplication application = (LauncherApplication) getApplication(); Mogoo_BitmapCache cache = application.getIconCache(); List<ApplicationInfo> appInfos = new ArrayList<ApplicationInfo>(); if (apps != null) { for (ResolveInfo ri : apps) { appInfos.add(new ApplicationInfo(ri, cache)); } } for(ApplicationInfo info:appInfos){ if (info.title != null && info.title.toString().toLowerCase().startsWith(query.toLowerCase())) { Drawable drawable = new BitmapDrawable(info.iconBitmap); AppsSource source = new AppsSource(info.title.toString(), drawable, info.intent); sources.add(source); } } return sources; //end } /** * Queries for a given search term and returns a cursor containing * suggestions ordered by best match. */ private ArrayList<Source> queryWeb(String query) { if (TextUtils.isEmpty(query)) { return null; } if (!isNetworkConnected()) { Log.i(LOG_TAG, "Not connected to network."); return null; } try { query = URLEncoder.encode(query, "UTF-8"); // NOTE: This code uses resources to optionally select the search // Uri, based on the // MCC value from the SIM. iThe default string will most likely be // fine. It is // paramerterized to accept info from the Locale, the language code // is the first // parameter (%1$s) and the country code is the second (%2$s). This // code *must* // function in the same way as a similar lookup in // com.android.browser.BrowserActivity#onCreate(). If you change // either of these functions, change them both. (The same is true // for the underlying // resource strings, which are stored in mcc-specific xml files.) if (mSuggestUri == null) { Locale l = Locale.US; String language = "en"; String country = "us"; // Chinese and Portuguese have two langauge variants. mSuggestUri = getBaseContext().getResources().getString( R.string.google_suggest_base, language, country) + "&q="; } String suggestUri = mSuggestUri + query; if (DBG) Log.d(LOG_TAG, "Sending request: " + suggestUri); HttpGet method = new HttpGet(suggestUri); HttpResponse response = mHttpClient.execute(method); if (response.getStatusLine().getStatusCode() == 200) { /* * Goto http://www.google.com/complete/search?json=true&q=foo to * see what the data format looks like. It's basically a json * array containing 4 other arrays. We only care about the * middle 2 which contain the suggestions and their popularity. */ JSONObject resultJson = new JSONObject(EntityUtils.toString(response.getEntity())); ArrayList<Source> sources = getWebContent(resultJson); resultJson = null; // JSONArray results = new // JSONArray(resultJson.getJSONArray("responseData").); // JSONArray suggestions = results.getJSONArray(1); // JSONArray popularity = results.getJSONArray(2); if (DBG) Log.d(LOG_TAG, "Got " + sources.size() + " results"); return sources;// new WebCursor(suggestions, popularity); } else { if (DBG) Log.d(LOG_TAG, "Request failed " + response.getStatusLine()); } response.getEntity().consumeContent(); response = null; method = null; } catch (UnsupportedEncodingException e) { Log.w(LOG_TAG, "Error", e); } catch (IOException e) { Log.w(LOG_TAG, "Error", e); } catch (JSONException e) { Log.w(LOG_TAG, "Error", e); } return null; } private ArrayList<Source> getWebContent(JSONObject resultJson) throws JSONException { int resultCode = resultJson.getInt("responseStatus"); /* * {"content":"<b>Q<\/b> Magazine the UK's biggest music magazines, * music news, reviews and world exclusives with the most important * bands on the planet.","GsearchResultClass":"GwebSearch * ","titleNoFormatting":"Q Magazine | Music news & reviews, music * videos, band pictures ...","title":"<b>Q<\/b> Magazine | Music news * & reviews, music videos, band pictures <b>... * <\/b>","cacheUrl":"http:\/\/www.google.com\/search?q=cache * :3aIeKl4cbKAJ :www.qthemusic.com","unescapedUrl":"http:\/\/www. * qthemusic.com \/","url":"http:\/\/www.qthemusic.com\/","visibleUrl * ":"www.qthemusic.com"} */ if (resultCode == 200) { ArrayList<Source> sources = new ArrayList<Source>(); JSONObject responseData = resultJson.getJSONObject("responseData"); JSONArray list = responseData.getJSONArray("results"); JSONObject item = null; Uri sourceIconUri = null; for (int i = 0; i < list.length(); i++) { item = list.getJSONObject(i); sourceIconUri = Uri.parse(item.getString("url")); WebSource source = WebSource.create(sourceIconUri, item.getString("title"), item.getString("content"), null, null); sources.add(source); } item = null; sourceIconUri = null; list = null; responseData = null; return sources; } return null; } private boolean isNetworkConnected() { NetworkInfo networkInfo = getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } private NetworkInfo getActiveNetworkInfo() { try { ConnectivityManager connectivity = (ConnectivityManager) getApplicationContext() .getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivity == null) { return null; } return connectivity.getActiveNetworkInfo(); } catch (Exception e) { Log.w(LOG_TAG, e); } return null; } }