com.hhunj.hhudata.ForegroundService.java Source code

Java tutorial

Introduction

Here is the source code for com.hhunj.hhudata.ForegroundService.java

Source

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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.hhunj.hhudata;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.PowerManager.WakeLock;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpUriRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.hhunj.hhudata.R;
import com.hhunj.hhudata.alarm.IncomingMessageView;
import com.hhunj.hhudata.alarm.LatestReceiver;
import com.hhunj.hhudata.alarm.AndroidHttpClient;
import com.hhunj.hhudata.alarm.RepeatingAlarm;
import com.hhunj.hhudata.db.Constants;
import com.hhunj.hhudata.db.ContactColumn;
import com.hhunj.hhudata.db.DBUtils;
import com.hhunj.hhudata.db.NotePad;
import com.hhunj.hhudata.db.SearchBookContentsResult;
import com.hhunj.hhudata.db.ContactsProvider;
import com.hhunj.hhudata.util.MyTimer;

import android.app.AlarmManager;
import java.util.TimeZone;
import java.util.Calendar;

import android.database.SQLException;
import java.util.Date;

import android.media.RingtoneManager;

import com.hhunj.hhudata.bean.Host;

// Need the following import to get access to the app resources, since this
// class is in a sub-package.

/**
 * This is an example of implementing an application service that can run in the
 * "foreground". It shows how to code this to work well by using the improved
 * Android 2.0 APIs when available and otherwise falling back to the original
 * APIs. Yes: you can take this exact code, compile it against the Android 2.0
 * SDK, and it will against everything down to Android 1.0.
 */
public class ForegroundService extends Service {
    static final String ACTION_FOREGROUND = "com.hhunj.hhudata.FOREGROUND";

    private static final Class[] mStartForegroundSignature = new Class[] { int.class, Notification.class };
    private static final Class[] mStopForegroundSignature = new Class[] { boolean.class };

    private NotificationManager mNM;
    private Method mStartForeground;
    private Method mStopForeground;
    private Object[] mStartForegroundArgs = new Object[2];
    private Object[] mStopForegroundArgs = new Object[1];

    private Settings m_settings;

    private boolean m_httpConnect = true;

    //static final String default_phonenum = "5556";// 13338620269
    public HashMap<Integer, ContactColumn.ContactInfo> m_contactmap;

    Toast mToast;

    private String isbn; // reginid

    private int m_port = 16666;
    private String m_address = "192.168.2.103";

    private long m_aquirespan = 20; // sec
    private long m_alamspan = 10; // min
    private Date m_workStartTime = new Date();
    private Date m_workEndTime = new Date();
    private boolean m_alarmInWorktime = true;

    private AlarmManager mAlarmManager;
    private NetworkThread networkThread;

    static final String TAG = "ForegroundService";
    private static final String USER_AGENT = "Hydromap (Android)";

    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
            case R.id.search_book_contents_succeeded:
                handleSearchResults((JSONObject) message.obj);
                resetForNewQuery();
                m_httpConnect = true;
                break;
            // 
            case R.id.search_book_contents_failed: {
                if (m_httpConnect == true) {
                    String s = "" + message.toString();
                    try {
                        sendSMS(s);
                    } catch (IllegalArgumentException e2) {

                        // ....
                        // ...
                        int aa = 0;

                    }

                }
                m_httpConnect = false;

            }

                break;
            }

            /*
            Intent intent = new Intent(ForegroundService.this, LatestReceiver.class);
            //   PendingIntent sender = PendingIntent.getBroadcast(ForegroundService.this, 0, intent, 0);      
            //   sender.notify();         
                
                
            //Intent intent = new Intent("com.hhunj.hhudata.LATESTUPDATE");
            //   intent.putExtra("data_title", ""); 
            //intent.putExtra("data_text", ""); 
            sendBroadcast(intent); 
            */

        }
    };

    @Override
    public void onCreate() {
        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        try {
            mStartForeground = getClass().getMethod("startForeground", mStartForegroundSignature);
            mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);
        } catch (NoSuchMethodException e) {
            // Running on an older platform.
            mStartForeground = mStopForeground = null;
        }

        resetForNewQuery();

        m_contactmap = ContactsProvider.configCheckedItemList(this);
        m_settings = new Settings(this);

        //   clockRing();   
    }

    // 
    private void resetForNewQuery() {

        networkThread = null;

        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        DBUtils dbUtils = new DBUtils(this);
        long hostid = pref.getLong("hostid", -1);
        Host h = dbUtils.hostDelegate.getHost(hostid);
        if (h == null) {
            h = Host.getdefaultHost();
        }

        m_address = h.getHost();

        //m_rss = Constants.getRss(pref);
        m_port = h.getPort();
        m_aquirespan = h.getAquirespan();
        m_alamspan = h.getAlamspan();
        m_workStartTime = h.getWorkStartTime();
        m_workEndTime = h.getWorkEndTime();
        m_alarmInWorktime = h.getAlarmInWorktime();
        mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    }

    //,8,...
    boolean IsDuringWorkHours(Date dt) {

        /*
        // UTC
        Calendar calendar = Calendar.getInstance();
        int offset = calendar.get(Calendar.ZONE_OFFSET);
        int dst = calendar.get(Calendar.DST_OFFSET);
            
        calendar.setTimeInMillis(dt.getTime());
        calendar.add(Calendar.MILLISECOND, (offset + dst));
        Date resultDate = calendar.getTime(); 
        //   int offset=dt.getTimezoneOffset();
            
        */

        int hour = dt.getHours();
        int minute = dt.getMinutes();
        int ftime = hour * 100 + minute;
        int fstart = m_workStartTime.getHours() * 100 + m_workStartTime.getMinutes();
        int fend = m_workEndTime.getHours() * 100 + m_workEndTime.getMinutes();

        return (ftime >= fstart && ftime < fend);

    }

    protected void clockRing() {
        Intent intent = new Intent(this, RepeatingAlarm.class);

        PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);

        long firstTime = m_workStartTime.getTime();
        long elaps = 24 * 60 * 60 * 1000;
        //long elaps = 15 * 1000;
        // Schedule the alarm!
        AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, elaps, sender);

        // Tell the user about what we did.
        if (mToast != null) {
            mToast.cancel();
        }
        mToast = Toast.makeText(this, "R.string.repeating_scheduled", Toast.LENGTH_LONG);
        mToast.show();

    }

    private void launchSearch() {
        if (networkThread == null) {
            String query = "queryTextView.getText().toString()";
            if (query != null && query.length() > 0) {
                networkThread = new NetworkThread(m_address, m_port, isbn, query, handler);
                networkThread.start();
            }
        }
    }

    // This is the old onStart method that will be called on the pre-2.0
    // platform. On 2.0 or later we override onStartCommand() so this
    // method will not be called.
    @Override
    public void onStart(Intent intent, int startId) {
        handleCommand(intent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleCommand(intent);
        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

    void handleCommand(Intent intent) {
        if (intent == null) {
            return;
        }
        if (ACTION_FOREGROUND.equals(intent.getAction())) {
            // In this sample, we'll use the same text for the ticker and the
            // expanded notification
            CharSequence text = getText(R.string.foreground_service_started);

            // Set the icon, scrolling text and timestamp
            Notification notification = new Notification(R.drawable.stat_sample, text, System.currentTimeMillis());

            // The PendingIntent to launch our activity if the user selects this
            // notification
            PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainTab.class), 0);//

            // Set the info for the views that show in the notification panel.
            notification.setLatestEventInfo(this, getText(R.string.local_service_label), text, contentIntent);

            startForegroundCompat(R.string.foreground_service_started, notification);

        }
        /*
         * else if (ACTION_BACKGROUND.equals(intent.getAction())) {
         * stopForegroundCompat(R.string.foreground_service_started); }
         */

    }

    /**
     * This is a wrapper around the new startForeground method, using the older
     * APIs if it is not available.
     */
    void startForegroundCompat(int id, Notification notification) {
        // If we have the new startForeground API, then use it.
        if (mStartForeground != null) {
            mStartForegroundArgs[0] = Integer.valueOf(id);
            mStartForegroundArgs[1] = notification;
            try {
                mStartForeground.invoke(this, mStartForegroundArgs);
            } catch (InvocationTargetException e) {
                // Should not happen.
                Log.w("ApiDemos", "Unable to invoke startForeground", e);
            } catch (IllegalAccessException e) {
                // Should not happen.
                Log.w("ApiDemos", "Unable to invoke startForeground", e);
            }
            m_settings.start();
            return;
        }

        // Fall back on the old API.
        setForeground(true);
        mNM.notify(id, notification);

        m_settings.start();
    }

    /**
     * This is a wrapper around the new stopForeground method, using the older
     * APIs if it is not available.
     */
    void stopForegroundCompat(int id) {
        // If we have the new stopForeground API, then use it.
        if (mStopForeground != null) {
            mStopForegroundArgs[0] = Boolean.TRUE;
            try {
                mStopForeground.invoke(this, mStopForegroundArgs);
            } catch (InvocationTargetException e) {
                // Should not happen.
                Log.w("ApiDemos", "Unable to invoke stopForeground", e);
            } catch (IllegalAccessException e) {
                // Should not happen.
                Log.w("ApiDemos", "Unable to invoke stopForeground", e);
            }
            m_settings.stop();
            return;

        }
        m_settings.stop();

        // Fall back on the old API. Note to cancel BEFORE changing the
        // foreground state, since we could be killed at that point.
        mNM.cancel(id);
        setForeground(false);
    }

    @Override
    public void onDestroy() {
        // Make sure our notification is gone.
        stopForegroundCompat(R.string.foreground_service_started);

    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    // //////////////////////////////////////
    //()"",
    private String updatedb(List<SearchBookContentsResult> items) {

        String sMessage = "";
        ContentResolver resolver = getApplicationContext().getContentResolver();

        ContentValues values = new ContentValues();

        for (int i = 0; i < items.size(); i++) {

            SearchBookContentsResult res = items.get(i);
            if (res == null)
                continue;
            long stationid = Long.parseLong(res.getPageNumber());

            values.put(NotePad.Notes.TITLE, res.getName());
            values.put(NotePad.Notes.NOTE, "");

            values.put(NotePad.Notes.LONGITUTE, 108.0);
            values.put(NotePad.Notes.LATITUDE, 32.0);
            values.put(NotePad.Notes.SPEED, 55);
            values.put(NotePad.Notes.ALTITUDE, 55);

            values.put(NotePad.Notes.CREATEDDATE, res.getRectime().getTime());

            values.put(NotePad.Notes._ID, stationid);// id

            Uri urlNote = NotePad.Notes.CONTENT_URI;

            Uri myUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, stationid);

            //?????
            Cursor cur = resolver.query(myUri, NotePad.Notes.PROJECTION, null, null, null);
            if (cur == null) {
                // 
            }
            if (cur != null && cur.moveToFirst()) {
                long id = cur.getLong(NotePad.Notes._ID_COLUMN);
                Date oldtime = new Date(cur.getLong(cur.getColumnIndex(NotePad.Notes.CREATEDDATE)));
                boolean oldalarm = (cur.getInt(NotePad.Notes.ALARM_COLUMN) == 0) ? false : true;

                long dif = (res.getRectime().getTime() - oldtime.getTime()) / (60 * 1000);

                // 
                dif = ((new Date()).getTime() - oldtime.getTime()) / (60 * 1000);
                boolean newalarm = false;//
                if (dif > m_alamspan) {
                    // ...
                    if (oldalarm == false) {
                        Log.w(TAG, "over time err--------");
                        // String phoneNumber ="13338620269";
                        sMessage += "---" + id + "---";
                        newalarm = true;
                    } else {
                        newalarm = true;
                    }

                }

                values.put(NotePad.Notes.ALARM, newalarm);
                int count = resolver.update(myUri, values, null, null);
                if (count == 0) {

                }

            } else {
                values.put(NotePad.Notes.ALARM, false);
                try {
                    myUri = resolver.insert(urlNote, values);
                } catch (IllegalArgumentException e) {
                    throw e;
                } catch (SQLException e2) {
                    int aa = 0;
                    throw e2;
                }
            }
        }
        return sMessage;
    }

    private void sendSMS(String message) {

        if (message == "")
            return;

        //String stext  =  "  " +m_contactmap.size();

        //notification ,title
        showNotification("hhudata", message);

        if (m_alarmInWorktime) {//
            Date dt = new Date();
            if (IsDuringWorkHours(dt) == false) {
                return;
            } else {
                //alarm.

            }
        }

        if (message.length() > 140) {
            //....
            return;
        }

        // ---sends an SMS message to another device---
        SmsManager sms = SmsManager.getDefault();
        String SENT_SMS_ACTION = "SENT_SMS_ACTION";
        String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";

        // create the sentIntent parameter
        Intent sentIntent = new Intent(SENT_SMS_ACTION);
        PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent, 0);

        // create the deilverIntent parameter
        Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
        PendingIntent deliverPI = PendingIntent.getBroadcast(this, 0, deliverIntent, 0);

        // register the Broadcast Receivers
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context _context, Intent _intent) {
                switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS sent success actions", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "SMS generic failure actions", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "SMS radio off failure actions", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "SMS null PDU failure actions", Toast.LENGTH_SHORT).show();
                    break;
                }
            }
        }, new IntentFilter(SENT_SMS_ACTION));
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context _context, Intent _intent) {
                Toast.makeText(getBaseContext(), "SMS delivered actions", Toast.LENGTH_SHORT).show();
            }
        }, new IntentFilter(DELIVERED_SMS_ACTION));

        // if message's length more than 70 ,
        // then call divideMessage to dive message into several part ,and call
        // sendTextMessage()
        // else direct call sendTextMessage()

        Iterator it = m_contactmap.keySet().iterator();
        while (it.hasNext()) {
            ContactColumn.ContactInfo info = m_contactmap.get(it.next());
            if (info.mobile == null)
                continue;
            String mobile = info.mobile.trim();
            if (mobile.length() >= 4) {
                if (message.length() > 70) {

                    ArrayList<String> msgs = sms.divideMessage(message);
                    for (String msg : msgs) {
                        sms.sendTextMessage(mobile, null, msg, sentPI, deliverPI);
                    }
                } else {
                    sms.sendTextMessage(mobile, null, message, sentPI, deliverPI);
                }
            }
        }

    }

    protected void showNotification(CharSequence from, CharSequence message) {
        // look up the notification manager service
        NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        // The PendingIntent to launch our activity if the user selects this
        // notification

        //,
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, IncomingMessageView.class), 0);

        // The ticker text, this uses a formatted string so our message could be
        // localized
        String tickerText = getString(R.string.imcoming_message_ticker_text, message);

        // construct the Notification object.
        Notification notif = new Notification(R.drawable.stat_sample, tickerText, System.currentTimeMillis());

        // Set the info for the views that show in the notification panel.
        notif.setLatestEventInfo(this, from, message, contentIntent);

        //   

        //
        Date dt = new Date();
        if (IsDuringWorkHours(dt)) {
            notif.defaults |= (Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
        } else {
            notif.defaults |= (Notification.DEFAULT_VIBRATE);
        }

        // after a 100ms delay, vibrate for 250ms, pause for 100 ms and
        // then vibrate for 500ms.//
        notif.vibrate = new long[] { 100, 250, 100, 500 };

        nm.notify(R.string.imcoming_message_ticker_text, notif);
    }

    private MediaPlayer ring() throws Exception, IOException {

        Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        MediaPlayer player = new MediaPlayer();

        player.setDataSource(this, alert);

        final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

        if (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) != 0) {

            player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);

            player.setLooping(true);

            player.prepare();

            player.start();

        }

        return player;

    }

    // Currently there is no way to distinguish between a query which had no
    // results and a book
    // which is not searchable - both return zero results.
    private void handleSearchResults(JSONObject json) {
        try {

            String s = json.toString();
            int count = json.getInt("number_of_results");

            if (count > 0) {
                JSONArray results = json.getJSONArray("search_results");

                // SearchBookContentsResult.setQuery(queryTextView.getText().toString());
                List<SearchBookContentsResult> items = new ArrayList<SearchBookContentsResult>(0);
                for (int x = 0; x < count; x++) {
                    JSONObject sr = results.getJSONObject(x);
                    if (sr != null) {
                        items.add(parseResult(sr));
                    }

                }
                // ...
                // ,...
                String message = updatedb(items);
                if (message != "") {
                    // ...
                    Log.w(TAG, "over time err--------");
                    sendSMS(m_address + ": " + message + "over time");
                }

                //....
                m_httpConnect = false;
                resetForNewQuery();
            } else
            // 
            {

                // ....
                // 
                String searchable = json.optString("searchable");

            }

        } catch (JSONException e) {

            // ....
            // ...

        } catch (IllegalArgumentException e2) {

            // ....
            // ...

            int aa = 0;

        }

    }

    public static Date JsonToDateTime(String jsonDate) {
        if (jsonDate == "null") {
            return null;
        }

        String value = jsonDate.substring(6, jsonDate.length() - 2);

        // DateTimeKind kind = DateTimeKind.Utc;

        int kind = 0;
        long h = 0;
        long m = 0;
        int index = value.indexOf('+', 1);
        if (index == -1) {
            index = value.indexOf('-', 1);
        } else {
            kind = 1;
        }

        if (index != -1) {
            if (kind == 0) {
                kind = -1;
            }

            String offset = value.substring(index + 1);
            String hour = offset.substring(0, 2);
            String minite = offset.substring(2);

            h = Long.parseLong(hour) * 3600 * 1000;
            m = Long.parseLong(minite) * 60 * 1000;

        }

        value = value.substring(0, index);
        long javaScriptTicks = kind * Long.parseLong(value) + h + m;
        // getTime()  : 1228494414199 197011
        Date utcDateTime = new Date((javaScriptTicks));

        return utcDateTime;
    }

    // Available fields: page_id, page_number, page_url, snippet_text
    private SearchBookContentsResult parseResult(JSONObject json) {
        try {
            String pageId = json.getString("page_id");
            String pageNumber = json.getString("page_number");
            if (pageNumber.length() > 0) {
                // pageNumber = getString(R.string.msg_sbc_page) + ' ' +
                // pageNumber;
            } else {
                // This can happen for text on the jacket, and possibly other
                // reasons.
                // pageNumber = getString(R.string.msg_sbc_unknown_page);
                pageNumber = null;
            }

            // Remove all HTML tags and encoded characters. Ideally the server
            // would do this.
            String snippet = json.optString("snippet_text");
            boolean valid = true;
            if (snippet.length() > 0) {
                /*
                 * snippet = TAG_PATTERN.matcher(snippet).replaceAll("");
                 * snippet = LT_ENTITY_PATTERN.matcher(snippet).replaceAll("<");
                 * snippet = GT_ENTITY_PATTERN.matcher(snippet).replaceAll(">");
                 * snippet =
                 * QUOTE_ENTITY_PATTERN.matcher(snippet).replaceAll("'");
                 * snippet =
                 * QUOT_ENTITY_PATTERN.matcher(snippet).replaceAll("\"");
                 */
            } else {
                snippet = '(' + getString(R.string.msg_sbc_snippet_unavailable) + ')';
                valid = false;
            }
            // new Date(+/\d+/.exec(value)[1]);

            Date date = JsonToDateTime(json.getString("rectime"));
            if (date == null)
                return null;

            return new SearchBookContentsResult(pageId, pageNumber, snippet, valid, date);

        } catch (JSONException e) {

            Date date = new Date();
            // Never seen in the wild, just being complete.
            return new SearchBookContentsResult(getString(R.string.msg_sbc_no_page_returned), "", "", false, date);
        }
    }

    // ///////////////////////////////////////////////////////////////////
    // NetworkThread
    private static final class NetworkThread extends Thread {
        private final String isbn;
        private final String query;
        private final Handler handler;
        private final String address;
        private final int port;

        NetworkThread(String address, int port, String isbn, String query, Handler handler) {
            this.isbn = isbn;
            this.query = query;
            this.handler = handler;
            this.address = address;
            this.port = port;
        }

        @Override
        public void run() {

            qureyAlarm();

        }

        void qureyAlarm() {
            AndroidHttpClient client = null;
            try {
                // These return a JSON result which describes if and where the
                // query was found. This API may
                // break or disappear at any time in the future. Since this is
                // an API call rather than a
                // website, we don't use LocaleManager to change the TLD.
                URI uri;

                uri = new URI("http", null, address, port, "/hhudata/alarm.ashx", "", null);

                // 
                HttpUriRequest get = new HttpGet(uri);
                get.setHeader("cookie", getCookie(uri.toString()));
                client = AndroidHttpClient.newInstance(USER_AGENT);
                HttpResponse response = client.execute(get);
                if (response.getStatusLine().getStatusCode() == 200) {
                    // url
                    HttpEntity entity = response.getEntity();

                    ByteArrayOutputStream jsonHolder = new ByteArrayOutputStream();
                    entity.writeTo(jsonHolder);
                    jsonHolder.flush();

                    JSONObject json = new JSONObject(jsonHolder.toString(getEncoding(entity)));
                    jsonHolder.close();
                    Message message = Message.obtain(handler, R.id.search_book_contents_succeeded);
                    message.obj = json;
                    message.sendToTarget();
                } else {
                    // 
                    Log.w(TAG, "HTTP returned " + response.getStatusLine().getStatusCode() + " for " + uri);
                    Message message = Message.obtain(handler, R.id.search_book_contents_failed);
                    message.sendToTarget();

                }

            } catch (Exception e) {
                Log.w(TAG, "Error accessing book search", e);
                Message message = Message.obtain(handler, R.id.search_book_contents_failed);
                message.sendToTarget();
            } finally {
                if (client != null) {
                    client.close();
                }
            }
        }

        // Book Search requires a cookie to work, which we store persistently.
        // If the cookie does
        // not exist, this could be the first search or it has expired. Either
        // way, do a quick HEAD
        // request to fetch it, save it via the CookieSyncManager to flash, then
        // return it.
        private static String getCookie(String url) {
            String cookie = CookieManager.getInstance().getCookie(url);
            if (cookie == null || cookie.length() == 0) {
                Log.d(TAG, "Book Search cookie was missing or expired");
                HttpUriRequest head = new HttpHead(url);
                AndroidHttpClient client = AndroidHttpClient.newInstance(USER_AGENT);
                try {
                    HttpResponse response = client.execute(head);
                    if (response.getStatusLine().getStatusCode() == 200) {
                        Header[] cookies = response.getHeaders("set-cookie");
                        for (Header theCookie : cookies) {
                            CookieManager.getInstance().setCookie(url, theCookie.getValue());
                        }
                        CookieSyncManager.getInstance().sync();
                        cookie = CookieManager.getInstance().getCookie(url);
                    }
                } catch (IOException e) {
                    Log.w(TAG, "Error setting book search cookie", e);
                }
                client.close();
            }
            return cookie;
        }

        private static String getEncoding(HttpEntity entity) {
            // FIXME: The server is returning ISO-8859-1 but the content is
            // actually windows-1252.
            // Once Jeff fixes the HTTP response, remove this hardcoded value
            // and go back to getting
            // the encoding dynamically.
            return "windows-1252";
            // HeaderElement[] elements = entity.getContentType().getElements();
            // if (elements != null && elements.length > 0) {
            // String encoding =
            // elements[0].getParameterByName("charset").getValue();
            // if (encoding != null && encoding.length() > 0) {
            // return encoding;
            // }
            // }
            // return "UTF-8";
        }
    }

    // ///////////////////////////////////////////////////
    // Settings
    class Settings implements MyTimer.CallBack {

        private Context mContext;
        public static final long timer_span = 200;// milisec
        //   public static final long lanch_sever_sec = 20;// sec 30*60
        private WakeLock mWakeLock = null;
        long m_startTime;
        long m_timeelaps = 0;

        long timercounts = 0;
        Location m_lastLocation = null;

        MyTimer mTimer;

        public void timerCallBack() {
            long cycleT = m_aquirespan * 1000 / timer_span;
            if (cycleT >= 1) {
                if (timercounts % (cycleT) == 0) {
                    launchSearch();
                }
            }
            timercounts += 1;

        }

        Settings(Context cxt) {
            this.mContext = cxt;
        }

        // gps
        public void start() {
            mTimer = new MyTimer(timer_span, this);
            mTimer.startTimer();
            m_startTime = System.currentTimeMillis();

        };

        void stop() {

            mTimer.stopTimer();
        }

        long getCurentTimeElpas() {
            return m_timeelaps + System.currentTimeMillis() - m_startTime;
        }

    }

}