| @@ -0,0 +1,213 @@ | ||
| /* | ||
| * Copyright 2010-2012 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker; | ||
|
|
||
| import ru.spb.osll.tracker.R; | ||
| import ru.spb.osll.tracker.exception.ExceptionHandler; | ||
| import ru.spb.osll.tracker.preferences.Settings; | ||
| import ru.spb.osll.tracker.preferences.SettingsActivity; | ||
| import ru.spb.osll.tracker.preferences.Settings.ITrackerAppSettings; | ||
| import ru.spb.osll.tracker.services.RequestService; | ||
| import ru.spb.osll.tracker.utils.TrackerUtil; | ||
| import android.app.Activity; | ||
| import android.content.BroadcastReceiver; | ||
| import android.content.Context; | ||
| import android.content.Intent; | ||
| import android.content.IntentFilter; | ||
| import android.os.Bundle; | ||
| import android.util.Log; | ||
| import android.view.View; | ||
| import android.widget.Button; | ||
| import android.widget.TextView; | ||
| import android.widget.Toast; | ||
|
|
||
| public class TrackerActivity extends Activity { | ||
| public static String LOG = "Tracker"; | ||
|
|
||
| private TextView mLogView; | ||
| private BroadcastReceiver mTrackerReceiver = new TrackerReceiver(); | ||
|
|
||
| @Override | ||
| public void onCreate(Bundle savedInstanceState) { | ||
| super.onCreate(savedInstanceState); | ||
| setContentView(R.layout.main); | ||
| Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); | ||
| registerReceiver(mTrackerReceiver, new IntentFilter(TrackerReceiver.ACTION_MESS)); | ||
|
|
||
| mLogView = (TextView) findViewById(R.id.TextField); | ||
| initialization(); | ||
|
|
||
| Settings settings = new Settings(this); | ||
| if (settings.isSettingsEmpty()){ | ||
| settings.setDefaultSettrings(); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| protected void onDestroy() { | ||
| super.onDestroy(); | ||
| unregisterReceiver(mTrackerReceiver); | ||
| } | ||
|
|
||
| private void initialization(){ | ||
| Log.v(LOG, "TrackerActivity - initialization"); | ||
|
|
||
| Button btnService = (Button) findViewById(R.id.start_button); | ||
| btnService.setOnClickListener(new View.OnClickListener() { | ||
| public void onClick(View v) { | ||
| startTracker(); | ||
| } | ||
| }); | ||
|
|
||
| final Button stopBtn = (Button) findViewById(R.id.stop_button); | ||
| stopBtn.setOnClickListener(new View.OnClickListener() { | ||
| @Override | ||
| public void onClick(View v) { | ||
| stopTracker(); | ||
| } | ||
| }); | ||
|
|
||
| final Button settingsBtn = (Button) findViewById(R.id.settings_button); | ||
| settingsBtn.setOnClickListener(new View.OnClickListener() { | ||
| @Override | ||
| public void onClick(View v) { | ||
| if (TrackerUtil.isServiceRunning(TrackerActivity.this, RequestService.class)) { | ||
| showToast(TrackerUtil.MESS_SETTINGS_NOT_AVAILABLE); | ||
| } else { | ||
| startActivity(new Intent(TrackerActivity.this, SettingsActivity.class)); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| final Button creenBtn = (Button) findViewById(R.id.screeen_down_button); | ||
| creenBtn.setOnClickListener(new View.OnClickListener() { | ||
| @Override | ||
| public void onClick(View v) { | ||
| TrackerUtil.hideApplication(TrackerActivity.this); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| private void startTracker(){ | ||
| if (TrackerUtil.isServiceRunning(this, RequestService.class)){ | ||
| showToast(TrackerUtil.MESS_TRACKER_ALREADY_RUNNING); | ||
| } else if (TrackerUtil.isOnline(this)){ | ||
| showToast(TrackerUtil.MESS_TRACKER_START); | ||
| clearLogView(); | ||
| TrackerUtil.notify(this); | ||
| startService(new Intent(this, RequestService.class)); | ||
|
|
||
| if (Settings.getPreferences(this).getBoolean(ITrackerAppSettings.IS_HIDE_APP, true)){ | ||
| TrackerUtil.hideApplication(TrackerActivity.this); | ||
| } | ||
| } else if (!TrackerUtil.isOnline(this)){ | ||
| showToast(TrackerUtil.MESS_FAIL_CONNECTION); | ||
| } | ||
| } | ||
|
|
||
| private void stopTracker(){ | ||
| if (TrackerUtil.isServiceRunning(this, RequestService.class)){ | ||
| showToast(TrackerUtil.MESS_TRACKER_STOP); | ||
| TrackerUtil.disnotify(this); | ||
| stopService(new Intent(this, RequestService.class)); | ||
| } | ||
| } | ||
|
|
||
| private void showToast(final String mess){ | ||
| runOnUiThread(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| Toast.makeText(TrackerActivity.this, mess, Toast.LENGTH_SHORT).show(); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| private static int lineCount = 0; | ||
| private static final int maxLines = 16; | ||
| public void appendToLogView(final String mess){ | ||
| if (lineCount > maxLines){ | ||
| clearLogView(); | ||
| lineCount = 0; | ||
| } | ||
| appendToLogViewInternal(mess); | ||
| lineCount++; | ||
| } | ||
|
|
||
| private void appendToLogViewInternal(final String mess){ | ||
| runOnUiThread(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| mLogView.append("\n" + mess); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| private void clearLogView(){ | ||
| runOnUiThread(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| mLogView.setText(""); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| public class TrackerReceiver extends BroadcastReceiver { | ||
| public static final String ACTION_MESS = "action.mess"; | ||
| public static final String TYPE_MESS = "type.mess"; | ||
| public static final String TYPE_OPEATION = "type.operation"; | ||
| public static final int ID_SHOW_TOAST = 0; | ||
| public static final int ID_APPEND_TO_LOG = 1; | ||
| public static final int ID_LOG_AND_TOAST = 2; | ||
|
|
||
| @Override | ||
| public void onReceive(Context context, Intent intent) { | ||
| final String mess = intent.getStringExtra(TYPE_MESS); | ||
| final int type = intent.getIntExtra(TYPE_OPEATION, -1); | ||
| switch (type) { | ||
| case ID_SHOW_TOAST: | ||
| showToast(mess); | ||
| break; | ||
| case ID_APPEND_TO_LOG: | ||
| appendToLogView(mess); | ||
| break; | ||
| case ID_LOG_AND_TOAST: | ||
| showToast(mess); | ||
| appendToLogView(mess); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,86 @@ | ||
| /* | ||
| * Copyright 2010-2012 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.exception; | ||
|
|
||
| import ru.spb.osll.tracker.R; | ||
| import android.app.Activity; | ||
| import android.content.Intent; | ||
| import android.os.Bundle; | ||
| import android.text.method.ScrollingMovementMethod; | ||
| import android.view.View; | ||
| import android.widget.TextView; | ||
|
|
||
| public class ExceptionActivity extends Activity{ | ||
| public static String STACKTRACE = "stacktrace"; | ||
|
|
||
| public void onCreate(Bundle icicle) { | ||
| super.onCreate(icicle); | ||
| setContentView(R.layout.exception_view); | ||
| final String stackTrace = getIntent().getStringExtra(STACKTRACE); | ||
| final TextView exeptionTextView = (TextView)findViewById(R.id.exeption_text); | ||
|
|
||
| exeptionTextView.setMovementMethod(ScrollingMovementMethod.getInstance()); | ||
| exeptionTextView.setClickable(false); | ||
| exeptionTextView.setLongClickable(false); | ||
|
|
||
| exeptionTextView.append("Tracker has been crached!"); | ||
| exeptionTextView.append(stackTrace); | ||
|
|
||
| findViewById(R.id.send).setOnClickListener( | ||
| new View.OnClickListener() { | ||
| public void onClick(View view) { | ||
| Intent sendIntent = new Intent(Intent.ACTION_SEND); | ||
| sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "geo2tag@lists.osll.spb.ru" }); | ||
| sendIntent.putExtra(Intent.EXTRA_TEXT, stackTrace); | ||
| sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Tracker exception report"); | ||
| sendIntent.setType("message/rfc822"); | ||
| startActivity(sendIntent); | ||
| finish(); | ||
| } | ||
| } | ||
| ); | ||
|
|
||
| findViewById(R.id.cancel).setOnClickListener( | ||
| new View.OnClickListener() { | ||
| public void onClick(View view) { | ||
| finish(); | ||
| } | ||
| } | ||
| ); | ||
| } | ||
|
|
||
|
|
||
| } |
| @@ -0,0 +1,66 @@ | ||
| /* | ||
| * Copyright 2010-2011 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.exception; | ||
|
|
||
| import java.io.PrintWriter; | ||
| import java.io.StringWriter; | ||
| import java.lang.Thread.UncaughtExceptionHandler; | ||
|
|
||
| import android.content.Context; | ||
| import android.content.Intent; | ||
| import android.os.Process; | ||
|
|
||
| public class ExceptionHandler implements UncaughtExceptionHandler { | ||
| private final Context m_context; | ||
|
|
||
| public ExceptionHandler(Context context) { | ||
| m_context = context; | ||
| } | ||
|
|
||
| public void uncaughtException(Thread thread, Throwable exception) { | ||
| StringWriter stackTrace = new StringWriter(); | ||
| exception.printStackTrace(new PrintWriter(stackTrace)); | ||
| System.err.println(stackTrace); | ||
|
|
||
| Intent intent = new Intent(m_context, ExceptionActivity.class); | ||
| intent.putExtra(ExceptionActivity.STACKTRACE, stackTrace.toString()); | ||
| m_context.startActivity(intent); | ||
|
|
||
| Process.killProcess(Process.myPid()); | ||
| System.exit(10); | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,69 @@ | ||
| /* | ||
| * Copyright 2010-2011 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.gui; | ||
|
|
||
| import android.app.AlertDialog; | ||
| import android.content.Context; | ||
| import android.content.DialogInterface; | ||
|
|
||
| public class RadioButtonDialog{ | ||
| protected Context myContext; | ||
| private String myTitle; | ||
| private String[] myItems; | ||
| private int mySelectedItem; | ||
|
|
||
| public RadioButtonDialog(Context context, String title, String[] items, int selectedItem){ | ||
| myContext = context; | ||
| myTitle = title; | ||
| myItems = items; | ||
| mySelectedItem = selectedItem; | ||
| } | ||
|
|
||
| protected void itemSelected(DialogInterface dialog, int item){ | ||
| dialog.dismiss(); | ||
| } | ||
|
|
||
| public void show(){ | ||
| AlertDialog.Builder builder = new AlertDialog.Builder(myContext); | ||
| builder.setTitle(myTitle); | ||
| builder.setSingleChoiceItems(myItems, mySelectedItem, new DialogInterface.OnClickListener() { | ||
| public void onClick(DialogInterface dialog, int item) { | ||
| itemSelected(dialog, item); | ||
| } | ||
| }); | ||
| builder.create().show(); | ||
| } | ||
| } |
| @@ -0,0 +1,101 @@ | ||
| /* | ||
| * Copyright 2010-2012 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.preferences; | ||
|
|
||
| import org.xml.sax.Attributes; | ||
| import org.xml.sax.SAXException; | ||
| import org.xml.sax.helpers.DefaultHandler; | ||
|
|
||
| import ru.spb.osll.tracker.preferences.Settings.ITrackerAppSettings; | ||
| import ru.spb.osll.tracker.preferences.Settings.ITrackerNetSettings; | ||
| import android.content.SharedPreferences.Editor; | ||
|
|
||
| public class ConfigFeedParser extends DefaultHandler implements IXMLSettrings { | ||
| private Editor m_configEditor; | ||
| private StringBuffer m_sb; | ||
|
|
||
| public ConfigFeedParser(Editor configEditor) { | ||
| m_configEditor = configEditor; | ||
| } | ||
|
|
||
| @Override | ||
| public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { | ||
| super.startElement(uri, localName, qName, atts); | ||
| m_sb = new StringBuffer(); | ||
| } | ||
|
|
||
| @Override | ||
| public void endElement(String uri, String localName, String qName) throws SAXException { | ||
| super.endElement(uri, localName, qName); | ||
| if (localName.equals(config)){ | ||
| m_configEditor.commit(); | ||
| } else if (localName.equals(login)){ | ||
| m_configEditor.putString(ITrackerNetSettings.LOGIN, m_sb.toString()); | ||
| } else if (localName.equals(password)){ | ||
| m_configEditor.putString(ITrackerNetSettings.PASSWORD, m_sb.toString()); | ||
| } else if (localName.equals(channel)){ | ||
| m_configEditor.putString(ITrackerNetSettings.CHANNEL, m_sb.toString()); | ||
| } else if (localName.equals(server_url)){ | ||
| m_configEditor.putString(ITrackerNetSettings.SERVER_URL, m_sb.toString()); | ||
| } else if (localName.equals(time_tick)){ | ||
| m_configEditor.putInt(ITrackerNetSettings.TIME_TICK, Integer.parseInt(m_sb.toString())); | ||
| } else if (localName.equals(show_tick)){ | ||
| boolean val = m_sb.toString().equals("true") ? true : false; | ||
| m_configEditor.putBoolean(ITrackerAppSettings.IS_SHOW_TICKS, val); | ||
| } else if (localName.equals(hide_app)){ | ||
| boolean val = m_sb.toString().equals("true") ? true : false; | ||
| m_configEditor.putBoolean(ITrackerAppSettings.IS_HIDE_APP, val); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void characters(char ch[], int start, int length) { | ||
| String str = new String(ch, start, length); | ||
| m_sb.append(str); | ||
| } | ||
| } | ||
|
|
||
| interface IXMLSettrings{ | ||
| String config = "config"; | ||
| String login = "login"; | ||
| String password = "password"; | ||
| String channel = "channel"; | ||
| String server_url = "server_url"; | ||
| String time_tick = "time_tick"; | ||
| String show_tick = "show_tick"; | ||
| String hide_app = "hide_app"; | ||
| } | ||
|
|
| @@ -0,0 +1,114 @@ | ||
| /* | ||
| * Copyright 2010-2012 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.preferences; | ||
|
|
||
| import javax.xml.parsers.SAXParser; | ||
| import javax.xml.parsers.SAXParserFactory; | ||
|
|
||
| import org.xml.sax.InputSource; | ||
| import org.xml.sax.XMLReader; | ||
|
|
||
| import ru.spb.osll.tracker.R; | ||
| import ru.spb.osll.tracker.TrackerActivity; | ||
| import android.content.Context; | ||
| import android.content.SharedPreferences; | ||
| import android.content.SharedPreferences.Editor; | ||
| import android.util.Log; | ||
|
|
||
| public class Settings { | ||
| private Context m_context; | ||
| private static final String SETTINGS_STATUS = "settings_status"; | ||
|
|
||
| public Settings(Context context){ | ||
| m_context = context; | ||
| } | ||
|
|
||
| public SharedPreferences getPreferences(){ | ||
| return m_context.getSharedPreferences(ITrackerNetSettings.TRACKER_SETTINGS, 0); | ||
| } | ||
|
|
||
| public Editor getPreferencesEditor(){ | ||
| return getPreferences().edit(); | ||
| } | ||
|
|
||
| public boolean isSettingsEmpty(){ | ||
| return getPreferences().getBoolean(SETTINGS_STATUS, true); | ||
| } | ||
|
|
||
| public void setDefaultSettrings(){ | ||
| Editor editor = getPreferencesEditor(); | ||
| loadFromXMLFile(editor); | ||
| editor.putBoolean(SETTINGS_STATUS, false); | ||
| editor.commit(); | ||
| } | ||
|
|
||
| private void loadFromXMLFile(Editor configEditor) { | ||
| try { | ||
| InputSource is = | ||
| new InputSource(m_context.getResources().openRawResource(R.raw.tracker)); | ||
| SAXParserFactory factory = SAXParserFactory.newInstance(); | ||
| SAXParser parser = factory.newSAXParser(); | ||
| XMLReader xmlreader = parser.getXMLReader(); | ||
| xmlreader.setContentHandler(new ConfigFeedParser(configEditor)); | ||
| xmlreader.parse(is); | ||
| } catch (Exception e) { | ||
| Log.v(TrackerActivity.LOG, "loadFromXMLFile - exception: " + e.getMessage()); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| public static SharedPreferences getPreferences(Context c){ | ||
| return new Settings(c).getPreferences(); | ||
| } | ||
|
|
||
| public interface ITrackerNetSettings{ | ||
| String TRACKER_SETTINGS = "tracker_settings"; | ||
|
|
||
| String LOGIN = "login"; | ||
| String PASSWORD = "password"; | ||
| String CHANNEL = "channel"; | ||
| String SERVER_URL = "server_url"; | ||
| String TIME_TICK = "time_request"; | ||
| String RADIUS = "radius"; | ||
| String URI = "uri"; | ||
| } | ||
|
|
||
| public interface ITrackerAppSettings{ | ||
| String IS_SHOW_TICKS = "is_show_ticks"; | ||
| String IS_HIDE_APP = "is_hide_app"; | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,173 @@ | ||
| /* | ||
| * Copyright 2010-2011 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.preferences; | ||
|
|
||
| import ru.spb.osll.tracker.R; | ||
| import ru.spb.osll.tracker.gui.RadioButtonDialog; | ||
| import ru.spb.osll.tracker.preferences.Settings.ITrackerAppSettings; | ||
| import ru.spb.osll.tracker.preferences.Settings.ITrackerNetSettings; | ||
| import ru.spb.osll.tracker.utils.TrackerUtil; | ||
| import android.app.Activity; | ||
| import android.content.Context; | ||
| import android.content.DialogInterface; | ||
| import android.content.SharedPreferences; | ||
| import android.content.SharedPreferences.Editor; | ||
| import android.os.Bundle; | ||
| import android.view.View; | ||
| import android.widget.Button; | ||
| import android.widget.CheckBox; | ||
| import android.widget.EditText; | ||
| import android.widget.Toast; | ||
|
|
||
| public class SettingsActivity extends Activity implements ITrackerNetSettings, ITrackerAppSettings { | ||
|
|
||
| @Override | ||
| public void onCreate(Bundle savedInstanceState) { | ||
| super.onCreate(savedInstanceState); | ||
| setContentView(R.layout.settings); | ||
|
|
||
| setTitle("Tracker Settings"); | ||
| initializeFields(); | ||
| initializeTimeTickBtn(); | ||
|
|
||
| Button btnOk = (Button) findViewById(R.id.button_ok); | ||
| btnOk.setOnClickListener(new View.OnClickListener() { | ||
| @Override | ||
| public void onClick(View v) { | ||
| savePreferences(); | ||
| runOnUiThread(m_saveToast); | ||
| finish(); | ||
| } | ||
| }); | ||
|
|
||
| Button btnCancel = (Button) findViewById(R.id.button_cancel); | ||
| btnCancel.setOnClickListener(new View.OnClickListener() { | ||
| @Override | ||
| public void onClick(View v) { | ||
| finish(); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| private int m_timeTick; | ||
| private void initializeFields(){ | ||
| initField(LOGIN, R.id.edit_login); | ||
| initField(PASSWORD, R.id.edit_password); | ||
| initField(CHANNEL, R.id.edit_channel); | ||
| initField(SERVER_URL, R.id.edit_server_address); | ||
|
|
||
| initCheckBox(IS_HIDE_APP, R.id.checkbox_hide); | ||
| initCheckBox(IS_SHOW_TICKS, R.id.checkbox_tick); | ||
| } | ||
|
|
||
| private void initializeTimeTickBtn(){ | ||
| m_timeTick = new Settings(this).getPreferences().getInt(TIME_TICK, 0); | ||
|
|
||
| Button btnTick = (Button) findViewById(R.id.button_settings_tick); | ||
| btnTick.setText(Integer.toString(m_timeTick)); | ||
| btnTick.setOnClickListener(new View.OnClickListener() { | ||
| @Override | ||
| public void onClick(View v) { | ||
| new TimeTickDialog(SettingsActivity.this, getIdx(m_timeTick)).show(); | ||
| } | ||
| }); | ||
|
|
||
| } | ||
|
|
||
| private void savePreferences(){ | ||
| Editor prefEditor = new Settings(this).getPreferencesEditor(); | ||
| saveField(LOGIN, R.id.edit_login, prefEditor); | ||
| saveField(PASSWORD, R.id.edit_password, prefEditor); | ||
| saveField(CHANNEL, R.id.edit_channel, prefEditor); | ||
| saveField(SERVER_URL, R.id.edit_server_address, prefEditor); | ||
| prefEditor.putInt(TIME_TICK, m_timeTick); | ||
|
|
||
| saveCheckBox(IS_HIDE_APP, R.id.checkbox_hide, prefEditor); | ||
| saveCheckBox(IS_SHOW_TICKS, R.id.checkbox_tick, prefEditor); | ||
|
|
||
| prefEditor.commit(); | ||
| } | ||
|
|
||
| private Runnable m_saveToast = new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| Toast.makeText(SettingsActivity.this, TrackerUtil.MESS_SETTINGS_SAVED, Toast.LENGTH_SHORT).show(); | ||
| } | ||
| }; | ||
|
|
||
| private void initField(String key, int idField){ | ||
| SharedPreferences settings = new Settings(this).getPreferences(); | ||
| String str = settings.getString(key, "?????"); | ||
| ((EditText) findViewById(idField)).setText(str); | ||
| } | ||
|
|
||
| private void initCheckBox(String key, int id){ | ||
| SharedPreferences settings = new Settings(this).getPreferences(); | ||
| ((CheckBox) findViewById(id)).setChecked(settings.getBoolean(key, false)); | ||
| } | ||
|
|
||
| private void saveField(String key, int idField, Editor prefEditor){ | ||
| String str = ((EditText) findViewById(idField)).getText().toString().trim(); | ||
| prefEditor.putString(key, str); | ||
| } | ||
|
|
||
| private void saveCheckBox(String key, int id, Editor prefEditor){ | ||
| boolean status = ((CheckBox) findViewById(id)).isChecked(); | ||
| prefEditor.putBoolean(key, status); | ||
| } | ||
|
|
||
|
|
||
| String[] args = {"1", "2", "3", "4", "5", "10", "20", "30", "40", "50", "60"}; | ||
| private int getIdx(int val){ | ||
| for (int i = 0; i < args.length; i++){ | ||
| if (args[i].equals(Integer.toString(val))) | ||
| return i; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| class TimeTickDialog extends RadioButtonDialog{ | ||
| public TimeTickDialog(Context context, int selectedItem) { | ||
| super(context, "Tick interval", args, selectedItem); | ||
| } | ||
| @Override | ||
| protected void itemSelected(DialogInterface dialog, int item) { | ||
| super.itemSelected(dialog, item); | ||
| m_timeTick = Integer.parseInt(args[item]); | ||
| ((Button) findViewById(R.id.button_settings_tick)).setText(Integer.toString(m_timeTick)); | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,131 @@ | ||
| /* | ||
| * Copyright 2010-2012 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| * PROJ: OSLL/geo2tag | ||
| */ | ||
|
|
||
| package ru.spb.osll.tracker.services; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import ru.spb.osll.tracker.TrackerActivity; | ||
| import ru.spb.osll.tracker.exception.ExceptionHandler; | ||
| import android.app.Service; | ||
| import android.content.Context; | ||
| import android.content.Intent; | ||
| import android.location.Location; | ||
| import android.location.LocationListener; | ||
| import android.location.LocationManager; | ||
| import android.os.Bundle; | ||
| import android.os.IBinder; | ||
| import android.util.Log; | ||
|
|
||
| class LocationService extends Service { | ||
|
|
||
| private boolean isDeviceReady = false; | ||
|
|
||
| @Override | ||
| public void onCreate() { | ||
| Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); | ||
| } | ||
|
|
||
| @Override | ||
| public void onStart(Intent intent, int startId) { | ||
| super.onStart(intent, startId); | ||
| Log.d(TrackerActivity.LOG, "LocationService.onStart()"); | ||
| LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); | ||
| locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener); | ||
| locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener); | ||
| } | ||
|
|
||
| @Override | ||
| public void onDestroy() { | ||
| Log.d(TrackerActivity.LOG, "LocationService.onDestroy()"); | ||
| LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); | ||
| locationManager.removeUpdates(mLocationListener); | ||
| } | ||
|
|
||
| private LocationListener mLocationListener = new LocationListener() { | ||
| public void onLocationChanged(Location location) { | ||
| if (!isDeviceReady && location != null) { | ||
| isDeviceReady = true; | ||
| } else if (isDeviceReady && location == null) { | ||
| isDeviceReady = false; | ||
| } | ||
| } | ||
|
|
||
| public void onStatusChanged(String provider, int status, Bundle extras) { | ||
| Log.d(TrackerActivity.LOG, "onStatusChanged: " + provider + ", " + status); | ||
| } | ||
|
|
||
| public void onProviderEnabled(String provider) { | ||
| Log.d(TrackerActivity.LOG, "onProviderEnabled: " + provider); | ||
| } | ||
|
|
||
| public void onProviderDisabled(String provider) { | ||
| Log.d(TrackerActivity.LOG, "onProviderDisabled: " + provider); | ||
| } | ||
| }; | ||
|
|
||
| public boolean isDeviceReady(){ | ||
| return isDeviceReady; | ||
| } | ||
|
|
||
| protected Location getLocation() { | ||
| Location bestResult = null; | ||
| long minTime = 30 * 1000; // 1 sec | ||
| float bestAccuracy = Float.MAX_VALUE; | ||
| long bestTime = Long.MIN_VALUE; | ||
|
|
||
| LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); | ||
| List<String> matchingProviders = locationManager.getAllProviders(); | ||
| for (String provider : matchingProviders) { | ||
| Location location = locationManager.getLastKnownLocation(provider); | ||
| if (location != null) { | ||
| float accuracy = location.getAccuracy(); | ||
| long time = location.getTime(); | ||
| if ((time > minTime && accuracy < bestAccuracy)) { | ||
| bestResult = location; | ||
| bestAccuracy = accuracy; | ||
| bestTime = time; | ||
| } else if (time < minTime && bestAccuracy == Float.MAX_VALUE | ||
| && time > bestTime) { | ||
| bestResult = location; | ||
| bestTime = time; | ||
| } | ||
| } | ||
| } | ||
| return bestResult; | ||
| } | ||
|
|
||
| @Override | ||
| public IBinder onBind(Intent intent) { | ||
| return null; | ||
| } | ||
| } |
| @@ -0,0 +1,248 @@ | ||
| /* | ||
| * Copyright 2010-2012 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| package ru.spb.osll.tracker.services; | ||
|
|
||
| import java.util.Date; | ||
|
|
||
| import org.json.JSONObject; | ||
|
|
||
| import ru.spb.osll.json.*; | ||
| import ru.spb.osll.tracker.TrackerActivity; | ||
| import ru.spb.osll.tracker.TrackerActivity.TrackerReceiver; | ||
| import ru.spb.osll.tracker.preferences.Settings; | ||
| import ru.spb.osll.tracker.preferences.Settings.ITrackerAppSettings; | ||
| import ru.spb.osll.tracker.preferences.Settings.ITrackerNetSettings; | ||
| import ru.spb.osll.tracker.utils.AndroidJGeoLogger; | ||
| import ru.spb.osll.tracker.utils.TrackerUtil; | ||
| import android.content.Context; | ||
| import android.content.Intent; | ||
| import android.content.SharedPreferences; | ||
| import android.location.Location; | ||
| import android.os.IBinder; | ||
| import android.util.Log; | ||
|
|
||
| public class RequestService extends LocationService { | ||
|
|
||
| static { | ||
| ru.spb.osll.log.Log.setLogger(new AndroidJGeoLogger()); | ||
| } | ||
|
|
||
| private String mAuthToken; | ||
| private SettingsCache mSCache; | ||
| private boolean mTrackerStatus = false; | ||
|
|
||
| @Override | ||
| public void onStart(Intent intent, int startId) { | ||
| Log.v(TrackerActivity.LOG, "RequestService.onStart()"); | ||
| super.onStart(intent, startId); | ||
| mSCache = new SettingsCache(this); | ||
|
|
||
| mTrackerStatus = true; | ||
| new Thread(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| try { | ||
| mAuthToken = login(); | ||
| applyChannel(); | ||
| subscribeToChannel(); | ||
| track(); | ||
| } catch (TrackerException e) { | ||
| TrackerUtil.disnotify(RequestService.this); | ||
| sendToastAndLog(e.getMessage()); | ||
| stopSelf(); | ||
| } | ||
| } | ||
| }).start(); | ||
| } | ||
|
|
||
| @Override | ||
| public void onDestroy() { | ||
| Log.v(TrackerActivity.LOG, "RequestService.onDestroy()"); | ||
| mTrackerStatus = false; | ||
| super.onDestroy(); | ||
| } | ||
|
|
||
| @Override | ||
| public IBinder onBind(Intent intent) { | ||
| return null; | ||
| } | ||
|
|
||
| /** | ||
| * login method | ||
| * @return authToken string if login successful, null - otherwise | ||
| */ | ||
| private String login() throws TrackerException { | ||
| final JsonBaseRequest req = new JsonLoginRequest(mSCache.login, mSCache.pass, mSCache.serverUrl); | ||
| final JsonLoginResponse res = new JsonLoginResponse(); | ||
| safeSendingRequest(req, res, "Login is failed", Errno.SUCCESS); | ||
| sendToLog("Login successful"); | ||
| return res.getAuthString(); | ||
| } | ||
|
|
||
| /** | ||
| * @param authToken | ||
| * @return <code>TRUE</code> if new channel successefully added or channel already exists | ||
| */ | ||
| private void applyChannel() throws TrackerException { | ||
| final JsonBaseRequest req = new JsonApplyChannelRequest(mAuthToken, mSCache.channel, | ||
| "G2T tracker channel", "http://osll.spb.ru/", 3000, mSCache.serverUrl); | ||
| final JsonApplyChannelResponse res = new JsonApplyChannelResponse(); | ||
| safeSendingRequest(req, res, "Channel preparation failed", | ||
| Errno.SUCCESS, Errno.CHANNEL_ALREADY_EXIST_ERROR); | ||
| sendToLog("Channel prepared"); | ||
| } | ||
|
|
||
| private void subscribeToChannel() throws TrackerException { | ||
| final JsonBaseRequest req = new JsonSubscribeRequest(mAuthToken, | ||
| mSCache.channel, mSCache.serverUrl); | ||
| final JsonSubscribeResponse res = new JsonSubscribeResponse(); | ||
| safeSendingRequest(req, res, "Channel preparation failed", | ||
| Errno.SUCCESS, Errno.CHANNEL_ALREADY_SUBSCRIBED_ERROR); | ||
| sendToLog("Channel successfully checked"); | ||
| } | ||
|
|
||
| public void track() throws TrackerException { | ||
| int failCount = 0; | ||
| while (mTrackerStatus){ | ||
| try { | ||
| boolean success = applyMark(mAuthToken); | ||
| failCount = success ? 0 : failCount + 1; | ||
| if (failCount > 20) { | ||
| throw new TrackerException("Connection failed"); | ||
| } | ||
| Thread.sleep(mSCache.trackInterval*1000); | ||
| } catch (InterruptedException e) { | ||
| mTrackerStatus = false; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private boolean applyMark(String authToken){ | ||
| if (!isDeviceReady()) { | ||
| return false; | ||
| } | ||
|
|
||
| final Location location = getLocation(); | ||
| final double lat = location.getLatitude(); | ||
| final double lon = location.getLongitude(); | ||
| final double alt = 0.0; | ||
|
|
||
| JSONObject JSONResponse = new JsonApplyMarkRequest( | ||
| authToken, mSCache.channel, "title", "unknown", | ||
| "this tag was generated automaticaly by tracker application", | ||
| lat, lon, alt, TrackerUtil.getTime(new Date()), mSCache.serverUrl).doRequest(); | ||
|
|
||
| if (JSONResponse != null){ | ||
| Log.d(TrackerActivity.LOG, JSONResponse.toString()); | ||
| JsonApplyMarkResponse response = new JsonApplyMarkResponse(); | ||
| response.parseJson(JSONResponse); | ||
| sendToLog(TrackerUtil.convertLocation(lat, lon)); | ||
| return response.getErrno() == Errno.SUCCESS; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| private void sendToLog(String mess) { | ||
| sendMess(TrackerReceiver.ID_APPEND_TO_LOG, mess); | ||
| } | ||
|
|
||
| private void sendToastAndLog(String mess) { | ||
| sendMess(TrackerReceiver.ID_LOG_AND_TOAST, mess); | ||
| } | ||
|
|
||
| private void sendMess(int operationId, String mess) { | ||
| Intent intent = new Intent(TrackerReceiver.ACTION_MESS); | ||
| intent.putExtra(TrackerReceiver.TYPE_OPEATION, operationId); | ||
| intent.putExtra(TrackerReceiver.TYPE_MESS, mess); | ||
| sendBroadcast(intent); | ||
| } | ||
|
|
||
| /* | ||
| * Safe sending requests | ||
| * If after 3 attempts response is't received - throws TrackerException | ||
| */ | ||
| private final int ATTEMPTS = 3; | ||
| private void safeSendingRequest(JsonBaseRequest request, | ||
| JsonBaseResponse response, String errorMsg, int... possibleErrnos) | ||
| throws TrackerException { | ||
| JSONObject JSONResponse = null; | ||
| for (int i = 0; i < ATTEMPTS && JSONResponse == null; i++) { | ||
| JSONResponse = request.doRequest(); | ||
| } | ||
| if (JSONResponse == null){ | ||
| throw new TrackerException(errorMsg); | ||
| } | ||
| Log.d(TrackerActivity.LOG, JSONResponse.toString()); | ||
| response.parseJson(JSONResponse); | ||
| int errno = response.getErrno(); | ||
| Log.d(TrackerActivity.LOG, "Errno: " + Errno.getErrorByCode(errno)); | ||
| for (int err : possibleErrnos) { | ||
| if (err == errno) return; | ||
| } | ||
|
|
||
| throw new TrackerException(errorMsg); | ||
| } | ||
|
|
||
| @SuppressWarnings("serial") | ||
| private static class TrackerException extends Exception { | ||
| public TrackerException(String error) { | ||
| super(error); | ||
| } | ||
| } | ||
|
|
||
| class SettingsCache { | ||
| public String login; | ||
| public String pass; | ||
| public String channel; | ||
| public String serverUrl; | ||
| public int trackInterval; | ||
| public boolean isShowTick; | ||
|
|
||
| public SettingsCache(Context c){ | ||
| SharedPreferences settings = new Settings(c).getPreferences(); | ||
| login = settings.getString(ITrackerNetSettings.LOGIN, ""); | ||
| pass = settings.getString(ITrackerNetSettings.PASSWORD, ""); | ||
| channel = settings.getString(ITrackerNetSettings.CHANNEL, ""); | ||
| serverUrl = settings.getString(ITrackerNetSettings.SERVER_URL, ""); | ||
| trackInterval = settings.getInt(ITrackerNetSettings.TIME_TICK, 30); | ||
| isShowTick = settings.getBoolean(ITrackerAppSettings.IS_SHOW_TICKS, false); | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "SettingsCache [login=" + login + ", pass=" + pass | ||
| + ", channel=" + channel + ", serverUrl=" + serverUrl | ||
| + ", trackInterval=" + trackInterval + ", isShowTick=" | ||
| + isShowTick + "]"; | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,92 @@ | ||
| /* | ||
| * Copyright 2012 Vasily Romanikhin vasily.romanikhin@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.utils; | ||
|
|
||
| import android.util.Log; | ||
| import ru.spb.osll.log.Logger; | ||
|
|
||
| public class AndroidJGeoLogger implements Logger { | ||
|
|
||
| @Override | ||
| public void println(int level, String tag, int v) { | ||
| log(level, tag, v); | ||
| } | ||
|
|
||
| @Override | ||
| public void println(int level, String tag, double v) { | ||
| log(level, tag, v); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public void println(int level, String tag, float v) { | ||
| log(level, tag, v); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public void println(int level, String tag, byte v) { | ||
| log(level, tag, v); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public void println(int level, String tag, boolean v) { | ||
| log(level, tag, v); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public void println(int level, String tag, String v) { | ||
| log(level, tag, v); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public void println(int level, String tag, Throwable t) { | ||
| t.printStackTrace(); | ||
| Log.e(tag, "Throwable:", t); | ||
| } | ||
|
|
||
| private void log(int level, String tag, Object msg){ | ||
| if (level == Logger.DEBUG) { | ||
| Log.d(tag, msg.toString()); | ||
| } else { | ||
| Log.e(tag, msg.toString()); | ||
| } | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,160 @@ | ||
| /* | ||
| * Copyright 2010-2012 Vasily Romanikhin bac1ca89@gmail.com | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions and the following disclaimer. | ||
| * 2. Redistributions in binary form must reproduce the above copyright | ||
| * notice, this list of conditions and the following disclaimer in the | ||
| * documentation and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR | ||
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * 3. The name of the author may not be used to endorse or promote | ||
| * products derived from this software without specific prior written | ||
| * permission. | ||
| * | ||
| * The advertising clause requiring mention in adverts must never be included. | ||
| */ | ||
|
|
||
| /*! --------------------------------------------------------------- | ||
| * PROJ: OSLL/geo2tag | ||
| * ---------------------------------------------------------------- */ | ||
|
|
||
| package ru.spb.osll.tracker.utils; | ||
|
|
||
| import java.io.FileOutputStream; | ||
| import java.io.IOException; | ||
| import java.io.OutputStreamWriter; | ||
| import java.io.PrintWriter; | ||
| import java.text.DateFormat; | ||
| import java.text.SimpleDateFormat; | ||
| import java.util.Date; | ||
|
|
||
| import ru.spb.osll.tracker.R; | ||
| import ru.spb.osll.tracker.TrackerActivity; | ||
| import android.app.ActivityManager; | ||
| import android.app.Notification; | ||
| import android.app.NotificationManager; | ||
| import android.app.PendingIntent; | ||
| import android.app.ActivityManager.RunningServiceInfo; | ||
| import android.app.Service; | ||
| import android.content.Context; | ||
| import android.content.Intent; | ||
| import android.location.Location; | ||
| import android.net.ConnectivityManager; | ||
| import android.net.NetworkInfo; | ||
|
|
||
| public class TrackerUtil { | ||
|
|
||
| // | ||
| // TODO move to JGeo | ||
| // | ||
| private static DateFormat dateFormat = new SimpleDateFormat("dd MM yyyy HH:MM:ss.SSS"); | ||
| public static String getTime(Date date){ | ||
| return dateFormat.format(date); | ||
| } | ||
|
|
||
| public static final int TRACKER_NOTIFY_ID = 1; | ||
| public static void notify(Context c){ | ||
| NotificationManager nm = (NotificationManager)c.getSystemService(Context.NOTIFICATION_SERVICE); | ||
| String title = "Geo2Tag Traker service"; | ||
| String expandedText = "Geo2Tag Traker service is running"; | ||
| Notification notification = new Notification(R.drawable.icon, title, System.currentTimeMillis()); | ||
| Intent i = new Intent(c, TrackerActivity.class); | ||
| PendingIntent launchIntent = PendingIntent.getActivity(c, 0, i, 0); | ||
| notification.setLatestEventInfo(c, title, expandedText, launchIntent); | ||
| nm.notify(TRACKER_NOTIFY_ID,notification); | ||
| } | ||
|
|
||
| public static void disnotify(Context c){ | ||
| NotificationManager nm = (NotificationManager)c.getSystemService(Context.NOTIFICATION_SERVICE); | ||
| nm.cancel(TRACKER_NOTIFY_ID); | ||
| } | ||
|
|
||
| public static String convertLocation(double latitude, double longitude){ | ||
| StringBuffer strBuffer = new StringBuffer(); | ||
| strBuffer.append("lat: ").append(Location.convert(latitude, Location.FORMAT_MINUTES)). | ||
| append(" lon: ").append(Location.convert(longitude, Location.FORMAT_MINUTES)); | ||
| return strBuffer.toString(); | ||
| } | ||
|
|
||
| public static void hideApplication(Context c){ | ||
| Intent intent = new Intent(Intent.ACTION_MAIN); | ||
| intent.addCategory(Intent.CATEGORY_HOME); | ||
| c.startActivity(intent); | ||
| } | ||
|
|
||
| public static boolean isOnline(Context c) { | ||
| ConnectivityManager cm = (ConnectivityManager)c.getSystemService(Context.CONNECTIVITY_SERVICE); | ||
| NetworkInfo nInfo = cm.getActiveNetworkInfo(); | ||
| if (nInfo != null && nInfo.isConnected()) { | ||
| return true; | ||
| } | ||
| else { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| @SuppressWarnings("static-access") | ||
| public static boolean isServiceRunning(Context c, Class<? extends Service> clazz){ | ||
| ActivityManager manager = (ActivityManager) c.getSystemService(c.ACTIVITY_SERVICE); | ||
| for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { | ||
| if (clazz.getName().equals(service.service.getClassName())) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| public class Logger { | ||
| private PrintWriter m_logger; | ||
|
|
||
| public Logger(String logPath){ | ||
| try { | ||
| m_logger = new PrintWriter(new OutputStreamWriter(new FileOutputStream(logPath, true), "UTF-8")); | ||
| m_logger.println(dateFormat.format(new Date()) + " \t -------------- START LOG -------------"); | ||
| } catch (IOException e) { | ||
| e.printStackTrace(); | ||
| } | ||
| } | ||
|
|
||
| public void println(String str){ | ||
| m_logger.println(dateFormat.format(new Date()) + "\t\t:" + str); | ||
| } | ||
|
|
||
| public void destroy(){ | ||
| if (m_logger != null) | ||
| m_logger.close(); | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * TODO move message to loc files | ||
| */ | ||
| // messages | ||
| public static final String MESS_FAIL_CONNECTION = "Connection fail..."; | ||
| public static final String MESS_FAIL_CONNECTION_TO_SERVER = "Fail connection to server..."; | ||
| public static final String MESS_FAIL_ADDUSER = "add user fail:"; | ||
| public static final String MESS_FAIL_APPLY_CHANNEL = "apply channel fail:"; | ||
| public static final String MESS_FAIL_APPLY_MARK = "apply mark fail:"; | ||
|
|
||
| public static final String MESS_TRACKER_ALREADY_RUNNING = "Tracker is already running..."; | ||
| public static final String MESS_TRACKER_START = "Tracker is running..."; | ||
| public static final String MESS_TRACKER_STOP = "Tracker stopped..."; | ||
|
|
||
| public static final String MESS_SETTINGS_SAVED = "Settings saved!"; | ||
| public static final String MESS_SETTINGS_NOT_AVAILABLE = "Settings are not available! Stop the tracker..."; | ||
| } |