Java tutorial
/* * 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; } } }