Page MenuHomeGitPull.it

No OneTemporary

Size
39 KB
Referenced Files
None
Subscribers
None
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7769bd0..24ba670 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,104 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.reyboz.bustorino"
android:versionCode="22"
android:versionName="1.8.7">
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="23"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".ActivityMain"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="www.gtt.to.it"
android:pathPrefix="/cms/percorari/arrivi"
android:scheme="http"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="gtt.to.it"
android:pathPrefix="/cms/percorari/arrivi"
android:scheme="http"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="m.gtt.to.it"
android:pathPrefix="/m/it/arrivi.jsp"
android:scheme="http"/>
</intent-filter>
</activity>
<activity
android:name=".ActivityAbout"
android:label="@string/about"
android:parentActivityName=".ActivityMain"
android:theme="@style/AboutTheme">
<!-- API < 16: -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ActivityMain"/>
</activity>
<activity
android:name=".ActivityFavorites"
android:label="@string/title_activity_favorites"
android:parentActivityName=".ActivityMain"
android:theme="@style/FavTheme">
<!-- API < 16: -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ActivityMain"/>
</activity>
<provider
android:name=".middleware.AppDataProvider"
android:authorities="it.reyboz.bustorino.provider"
android:enabled="true"
android:exported="false">
</provider>
<service
android:name=".middleware.DatabaseUpdateService"
android:exported="false">
</service>
</application>
</manifest>
diff --git a/src/it/reyboz/bustorino/ActivityMain.java b/src/it/reyboz/bustorino/ActivityMain.java
index 8aeb737..c6b3840 100644
--- a/src/it/reyboz/bustorino/ActivityMain.java
+++ b/src/it/reyboz/bustorino/ActivityMain.java
@@ -1,583 +1,594 @@
/*
BusTO - Arrival times for Turin public transports.
Copyright (C) 2014 Valerio Bozzolan
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package it.reyboz.bustorino;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.NavUtils;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
//import com.melnykov.fab.FloatingActionButton;
import android.support.design.widget.FloatingActionButton;
import it.reyboz.bustorino.backend.ArrivalsFetcher;
import it.reyboz.bustorino.backend.FiveTScraperFetcher;
import it.reyboz.bustorino.backend.FiveTStopsFetcher;
import it.reyboz.bustorino.backend.GTTJSONFetcher;
import it.reyboz.bustorino.backend.GTTStopsFetcher;
import it.reyboz.bustorino.backend.StopsFinderByName;
import it.reyboz.bustorino.fragments.FragmentHelper;
import it.reyboz.bustorino.fragments.ResultListFragment;
import it.reyboz.bustorino.middleware.*;
public class ActivityMain extends GeneralActivity implements ResultListFragment.ResultFragmentListener {
/*
* Layout elements
*/
private EditText busStopSearchByIDEditText;
private EditText busStopSearchByNameEditText;
private ProgressBar progressBar;
private TextView howDoesItWorkTextView;
private Button hideHintButton;
private MenuItem actionHelpMenuItem;
private SwipeRefreshLayout swipeRefreshLayout;
private FloatingActionButton floatingActionButton;
private FragmentManager framan;
/*
* Search mode
*/
private static final int SEARCH_BY_NAME = 0;
private static final int SEARCH_BY_ID = 1;
private static final int SEARCH_BY_ROUTE = 2; // TODO: implement this (bug #1512948)
private int searchMode;
/*
* Options
*/
private final String OPTION_SHOW_LEGEND = "show_legend";
private final String LOCATION_PERMISSION_GIVEN = "loc_permission";
/* // useful for testing:
public class MockFetcher implements ArrivalsFetcher {
@Override
public Palina ReadArrivalTimesAll(String routeID, AtomicReference<result> res) {
SystemClock.sleep(5000);
res.set(result.SERVER_ERROR);
return new Palina();
}
}
private ArrivalsFetcher[] ArrivalFetchers = {new MockFetcher(), new MockFetcher(), new MockFetcher(), new MockFetcher(), new MockFetcher()};*/
private RecursionHelper<ArrivalsFetcher> ArrivalFetchersRecursionHelper = new RecursionHelper<>(new ArrivalsFetcher[] {new GTTJSONFetcher(), new FiveTScraperFetcher()});
private RecursionHelper<StopsFinderByName> StopsFindersByNameRecursionHelper = new RecursionHelper<>(new StopsFinderByName[] {new GTTStopsFetcher(), new FiveTStopsFetcher()});
private StopsDB stopsDB;
private UserDB userDB;
private FragmentHelper fh;
private GPSLocationAdapter locationHandler;
///////////////////////////////// EVENT HANDLERS ///////////////////////////////////////////////
/*
* @see swipeRefreshLayout
*/
private Handler handler = new Handler();
private final Runnable refreshing = new Runnable() {
public void run() {
new AsyncDataDownload(AsyncDataDownload.RequestType.ARRIVALS,fh).execute();
}
};
//// MAIN METHOD ///
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
framan = getSupportFragmentManager();
this.stopsDB = new StopsDB(getApplicationContext());
this.userDB = new UserDB(getApplicationContext());
setContentView(R.layout.activity_main);
busStopSearchByIDEditText = (EditText) findViewById(R.id.busStopSearchByIDEditText);
busStopSearchByNameEditText = (EditText) findViewById(R.id.busStopSearchByNameEditText);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
howDoesItWorkTextView = (TextView) findViewById(R.id.howDoesItWorkTextView);
hideHintButton = (Button) findViewById(R.id.hideHintButton);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.listRefreshLayout);
floatingActionButton = (FloatingActionButton) findViewById(R.id.floatingActionButton);
framan.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
Log.d("MainActivity, BusTO", "BACK STACK CHANGED");
}
});
busStopSearchByIDEditText.setSelectAllOnFocus(true);
busStopSearchByIDEditText
.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
// IME_ACTION_SEARCH alphabetical option
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
onSearchClick(v);
return true;
}
return false;
}
});
busStopSearchByNameEditText
.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
// IME_ACTION_SEARCH alphabetical option
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
onSearchClick(v);
return true;
}
return false;
}
});
// Called when the layout is pulled down
swipeRefreshLayout
.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
handler.post(refreshing);
}
});
/**
* @author Marco Gagino!!!
*/
//swipeRefreshLayout.setColorSchemeColors(R.color.blue_500, R.color.orange_500); // setColorScheme is deprecated, setColorSchemeColors isn't
swipeRefreshLayout.setColorSchemeResources(R.color.blue_500,R.color.orange_500);
fh = new FragmentHelper(this,R.id.listRefreshLayout,R.id.resultFrame,FragmentHelper.NO_FRAME);
setSearchModeBusStopID();
//---------------------------- START INTENT CHECK QUEUE ------------------------------------
// Intercept calls from URL intent
boolean tryedFromIntent = false;
String busStopID = null;
String busStopDisplayName = null;
Uri data = getIntent().getData();
if (data != null) {
busStopID = getBusStopIDFromUri(data);
tryedFromIntent = true;
}
// Intercept calls from other activities
if (!tryedFromIntent) {
Bundle b = getIntent().getExtras();
if (b != null) {
busStopID = b.getString("bus-stop-ID");
busStopDisplayName = b.getString("bus-stop-display-name");
/**
* I'm not very sure if you are coming from an Intent.
* Some launchers work in strange ways.
*/
tryedFromIntent = busStopID != null;
}
}
//---------------------------- END INTENT CHECK QUEUE --------------------------------------
if (busStopID == null) {
// Show keyboard if can't start from intent
showKeyboard();
// You haven't obtained anything... from an intent?
if (tryedFromIntent) {
// This shows a luser warning
ArrivalFetchersRecursionHelper.reset();
Toast.makeText(getApplicationContext(),
R.string.insert_bus_stop_number_error, Toast.LENGTH_SHORT).show();
}
} else {
// If you are here an intent has worked successfully
setBusStopSearchByIDEditText(busStopID);
/*
//THIS PART SHOULDN'T BE NECESSARY SINCE THE LAST SUCCESSFULLY SEARCHED BUS
// STOP IS ADDED AUTOMATICALLY
Stop nextStop = new Stop(busStopID);
// forcing it as user name even though it could be standard name, it doesn't really matter
nextStop.setStopUserName(busStopDisplayName);
//set stop as last succe
fh.setLastSuccessfullySearchedBusStop(nextStop);
*/
createFragmentForStop(busStopID);
}
//Try (hopefully) database update
//TODO: Start the service in foreground, check last time it ran before
DatabaseUpdateService.startDBUpdate(getApplicationContext());
- assertLocationPermissions();
+ if(getOption(LOCATION_PERMISSION_GIVEN,false)==false){
+ assertLocationPermissions();
+ }
locationHandler = new GPSLocationAdapter(getApplicationContext());
-
+ LocationManager locationManager = (LocationManager)
+ getSystemService(Context.LOCATION_SERVICE);
+ try {
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationHandler);
+ } catch (SecurityException ec){
+ //ignored
+ Log.w("Busto","Position request failed even though user accepted permission: "+ec.getMessage());
+ }
Log.d("MainActivity", "Created");
}
/**
* Reload bus stop timetable when it's fulled resumed from background.
*/
@Override
protected void onPostResume() {
super.onPostResume();
Log.d("ActivityMain", "onPostResume fired. Last successfully bus stop ID: " + fh.getLastSuccessfullySearchedBusStop());
if (searchMode == SEARCH_BY_ID && fh.getLastSuccessfullySearchedBusStop() != null) {
setBusStopSearchByIDEditText(fh.getLastSuccessfullySearchedBusStop().ID);
//new asyncWgetBusStopFromBusStopID(lastSuccessfullySearchedBusStop.ID, ArrivalFetchersRecursionHelper, lastSuccessfullySearchedBusStop);
new AsyncDataDownload(AsyncDataDownload.RequestType.ARRIVALS,fh).execute();
} else {
//we have new activity or we don't have a new searched stop.
//Let's search stops nearby
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
actionHelpMenuItem = menu.findItem(R.id.action_help);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case android.R.id.home:
// Respond to the action bar's Up/Home button
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.action_help:
showHints();
return true;
case R.id.action_favorites:
startActivity(new Intent(ActivityMain.this, ActivityFavorites.class));
return true;
case R.id.action_about:
startActivity(new Intent(ActivityMain.this, ActivityAbout.class));
return true;
case R.id.action_news:
openIceweasel("http://blog.reyboz.it/tag/busto/");
return true;
case R.id.action_bugs:
openIceweasel("https://bugs.launchpad.net/bus-torino");
return true;
case R.id.action_source:
openIceweasel("https://code.launchpad.net/bus-torino");
return true;
case R.id.action_licence:
openIceweasel("http://www.gnu.org/licenses/gpl-3.0.html");
return true;
case R.id.action_author:
openIceweasel("http://boz.reyboz.it?lovebusto");
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* OK this is pure shit
*
* @param v View clicked
*/
public void onSearchClick(View v) {
if (searchMode == SEARCH_BY_ID) {
String busStopID = busStopSearchByIDEditText.getText().toString();
//OLD ASYNCTASK
//new asyncWgetBusStopFromBusStopID(busStopID, ArrivalFetchersRecursionHelper, lastSuccessfullySearchedBusStop);
if(busStopID == null || busStopID.length() <= 0) {
showMessage(R.string.insert_bus_stop_number_error);
toggleSpinner(false);
} else
new AsyncDataDownload(AsyncDataDownload.RequestType.ARRIVALS,fh).execute(busStopID);
} else { // searchMode == SEARCH_BY_NAME
String query = busStopSearchByNameEditText.getText().toString();
//new asyncWgetBusStopSuggestions(query, stopsDB, StopsFindersByNameRecursionHelper);
new AsyncDataDownload(AsyncDataDownload.RequestType.STOPS,fh).execute(query);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case PERMISSION_REQUEST_POSITION:
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
setOption(LOCATION_PERMISSION_GIVEN,true);
+ locationHandler.startRequestingPosition();
} else {
//permission denied
setOption(LOCATION_PERMISSION_GIVEN,false);
}
//add other cases for permissions
}
}
@Override
public void createFragmentForStop(String ID) {
//new asyncWgetBusStopFromBusStopID(ID, ArrivalFetchersRecursionHelper,lastSuccessfullySearchedBusStop);
if(ID == null || ID.length() <= 0) {
// we're still in UI thread, no need to mess with Progress
showMessage(R.string.insert_bus_stop_number_error);
toggleSpinner(false);
} else
new AsyncDataDownload(AsyncDataDownload.RequestType.ARRIVALS,fh).execute(ID);
}
/**
* QR scan button clicked
*
* @param v View QRButton clicked
*/
public void onQRButtonClick(View v) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.initiateScan();
}
/**
* Receive the Barcode Scanner Intent
*
*/
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
Uri uri;
try {
uri = Uri.parse(scanResult != null ? scanResult.getContents() : null); // this apparently prevents NullPointerException. Somehow.
} catch (NullPointerException e) {
Toast.makeText(getApplicationContext(),
R.string.no_qrcode, Toast.LENGTH_SHORT).show();
return;
}
String busStopID = getBusStopIDFromUri(uri);
busStopSearchByIDEditText.setText(busStopID);
createFragmentForStop(busStopID);
}
public void onHideHint(View v) {
hideHints();
setOption(OPTION_SHOW_LEGEND, false);
}
public void onToggleKeyboardLayout(View v) {
if (searchMode == SEARCH_BY_NAME) {
setSearchModeBusStopID();
if (busStopSearchByIDEditText.requestFocus()) {
showKeyboard();
}
} else { // searchMode == SEARCH_BY_ID
setSearchModeBusStopName();
if (busStopSearchByNameEditText.requestFocus()) {
showKeyboard();
}
}
}
///////////////////////////////// OTHER STUFF //////////////////////////////////////////////////
@Override
public void addLastStopToFavorites() {
if(fh.getLastSuccessfullySearchedBusStop() != null) {
new AsyncAddToFavorites(this).execute(fh.getLastSuccessfullySearchedBusStop());
}
}
////////////////////////////////////// GUI HELPERS /////////////////////////////////////////////
@Override
public void showKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View view = searchMode == SEARCH_BY_ID ? busStopSearchByIDEditText : busStopSearchByNameEditText;
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
@Override
public void showMessage(int messageID) {
Toast.makeText(getApplicationContext(), messageID, Toast.LENGTH_SHORT).show();
}
private void setSearchModeBusStopID() {
searchMode = SEARCH_BY_ID;
busStopSearchByNameEditText.setVisibility(View.GONE);
busStopSearchByNameEditText.setText("");
busStopSearchByIDEditText.setVisibility(View.VISIBLE);
floatingActionButton.setImageResource(R.drawable.alphabetical);
}
private void setSearchModeBusStopName() {
searchMode = SEARCH_BY_NAME;
busStopSearchByIDEditText.setVisibility(View.GONE);
busStopSearchByIDEditText.setText("");
busStopSearchByNameEditText.setVisibility(View.VISIBLE);
floatingActionButton.setImageResource(R.drawable.numeric);
}
/**
* Having that cursor at the left of the edit text makes me cancer.
* @param busStopID bus stop ID
*/
private void setBusStopSearchByIDEditText(String busStopID) {
busStopSearchByIDEditText.setText(busStopID);
busStopSearchByIDEditText.setSelection(busStopID.length());
}
private void showHints() {
howDoesItWorkTextView.setVisibility(View.VISIBLE);
hideHintButton.setVisibility(View.VISIBLE);
actionHelpMenuItem.setVisible(false);
}
private void hideHints() {
howDoesItWorkTextView.setVisibility(View.GONE);
hideHintButton.setVisibility(View.GONE);
actionHelpMenuItem.setVisible(true);
}
//TODO: toggle spinner from mainActivity
@Override
public void toggleSpinner(boolean enable) {
if (enable) {
//already set by the RefreshListener when needed
//swipeRefreshLayout.setRefreshing(true);
progressBar.setVisibility(View.VISIBLE);
} else {
swipeRefreshLayout.setRefreshing(false);
progressBar.setVisibility(View.GONE);
}
}
private void prepareGUIForBusLines() {
swipeRefreshLayout.setEnabled(true);
swipeRefreshLayout.setVisibility(View.VISIBLE);
actionHelpMenuItem.setVisible(true);
}
private void prepareGUIForBusStops() {
swipeRefreshLayout.setEnabled(false);
swipeRefreshLayout.setVisibility(View.VISIBLE);
actionHelpMenuItem.setVisible(false);
}
/**
* This provides a temporary fix to make the transition
* to a single asynctask go smoother
* @param fragmentType the type of fragment created
*/
@Override
public void readyGUIfor(String fragmentType) {
hideKeyboard();
if(fragmentType==null) Log.e("ActivityMain","Problem with fragmentType");
else
switch (fragmentType){
case ResultListFragment.TYPE_LINES:
prepareGUIForBusLines();
if (getOption(OPTION_SHOW_LEGEND, true)) {
showHints();
}
break;
case ResultListFragment.TYPE_STOPS:
prepareGUIForBusStops();
break;
default:
Log.e("BusTO Activity","Called readyGUI with unsupported type of Fragment");
return;
}
// Shows hints
}
/**
* Open an URL in the default browser.
*
* @param url URL
*/
public void openIceweasel(String url) {
Intent browserIntent1 = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent1);
}
///////////////////// INTENT HELPER ////////////////////////////////////////////////////////////
/**
* Try to extract the bus stop ID from a URi
*
* @param uri The URL
* @return bus stop ID or null
*/
public static String getBusStopIDFromUri(Uri uri) {
String busStopID;
// everithing catches fire when passing null to a switch.
String host = uri.getHost();
if(host == null) {
Log.e("ActivityMain", "Not an URL: " + uri);
return null;
}
switch(host) {
case "m.gtt.to.it":
// http://m.gtt.to.it/m/it/arrivi.jsp?n=1254
busStopID = uri.getQueryParameter("n");
if (busStopID == null) {
Log.e("ActivityMain", "Expected ?n from: " + uri);
}
break;
case "www.gtt.to.it":
case "gtt.to.it":
// http://www.gtt.to.it/cms/percorari/arrivi?palina=1254
busStopID = uri.getQueryParameter("palina");
if (busStopID == null) {
Log.e("ActivityMain", "Expected ?palina from: " + uri);
}
break;
default:
Log.e("ActivityMain", "Unexpected intent URL: " + uri);
busStopID = null;
}
return busStopID;
}
}
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java b/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java
index 9653bb6..92a78ce 100644
--- a/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java
+++ b/src/it/reyboz/bustorino/middleware/DatabaseUpdateService.java
@@ -1,225 +1,228 @@
/*
BusTO (middleware)
Copyright (C) 2018 Fabio Mazza
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package it.reyboz.bustorino.middleware;
import android.app.IntentService;
import android.content.*;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.Fetcher;
import it.reyboz.bustorino.backend.FiveTAPIFetcher;
import it.reyboz.bustorino.backend.Route;
import it.reyboz.bustorino.backend.Stop;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
import static it.reyboz.bustorino.middleware.NextGenDB.Contract.*;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
*/
public class DatabaseUpdateService extends IntentService {
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
private static final String ACTION_UPDATE = "it.reyboz.bustorino.middleware.action.UPDATE_DB";
private static final String DB_VERSION = "NextGenDB.GTTVersion";
private static final String DEBUG_TAG = "DatabaseService_BusTO";
// TODO: Rename parameters
private static final String TRIAL = "it.reyboz.bustorino.middleware.extra.TRIAL";
private static final int MAX_TRIALS = 5;
public DatabaseUpdateService() {
super("DatabaseUpdateService");
}
private int updateTrial;
/**
* Starts this service to perform action Foo with the given parameters. If
* the service is already performing a task this action will be queued.
*
* @see IntentService
*/
public static void startDBUpdate(Context context) {
startDBUpdate(context,0);
}
public static void startDBUpdate(Context con, int trial){
Intent intent = new Intent(con, DatabaseUpdateService.class);
intent.setAction(ACTION_UPDATE);
intent.putExtra(TRIAL,trial);
con.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_UPDATE.equals(action)) {
Log.d(DEBUG_TAG,"Started action update");
SharedPreferences shPr = getSharedPreferences(getString(R.string.mainSharedPreferences),MODE_PRIVATE);
int versionDB = shPr.getInt(DB_VERSION,-1);
final int trial = intent.getIntExtra(TRIAL,-1);
updateTrial = trial;
int newVersion = getNewVersion(trial);
Log.d(DEBUG_TAG,"newDBVersion: "+newVersion+" oldVersion: "+versionDB);
if(versionDB==-1 || newVersion>versionDB){
Log.d(DEBUG_TAG,"Downloading the bus stops info");
final AtomicReference<Fetcher.result> gres = new AtomicReference<>();
- getContentResolver().delete(Uri.parse("content://"+AppDataProvider.AUTHORITY+"/stops"),null,null);
if(!performDBUpdate(gres)) restartDBUpdateifPossible(trial,gres);
/*switch (gres.get()){
case SERVER_ERROR:
restartDBUpdateifPossible(trial);
break;
case PARSER_ERROR:
break;
case EMPTY_RESULT_SET:
break;
case QUERY_TOO_SHORT:
break;
case SERVER_ERROR_404:
break;
}*/
else {
SharedPreferences.Editor ed = shPr.edit();
ed.putInt(DB_VERSION,newVersion);
// BY COMMENTING THIS, THE APP WILL CONTINUOUSLY UPDATE THE DATABASE
ed.apply();
}
} else {
Log.d(DEBUG_TAG,"No update needed");
}
Log.d(DEBUG_TAG,"Finished update");
}
}
}
public boolean performDBUpdate(AtomicReference<Fetcher.result> gres){
final FiveTAPIFetcher f = new FiveTAPIFetcher();
final ArrayList<Stop> stops = f.getAllStopsFromGTT(gres);
//final ArrayList<ContentProviderOperation> cpOp = new ArrayList<>();
if(gres.get()!= Fetcher.result.OK){
Log.w(DEBUG_TAG,"Something went wrong downloading");
return false;
}
final NextGenDB dbHelp = new NextGenDB(getApplicationContext());
final SQLiteDatabase db = dbHelp.getWritableDatabase();
//Empty the needed tables
db.beginTransaction();
- db.execSQL("DELETE FROM "+StopsTable.TABLE_NAME);
- db.delete(LinesTable.TABLE_NAME,null,null);
+ //db.execSQL("DELETE FROM "+StopsTable.TABLE_NAME);
+ //db.delete(LinesTable.TABLE_NAME,null,null);
//put new data
long startTime = System.currentTimeMillis();
Log.d(DEBUG_TAG,"Inserting "+stops.size()+" stops");
for (final Stop s : stops) {
final ContentValues cv = new ContentValues();
cv.put(StopsTable.COL_ID, s.ID);
cv.put(StopsTable.COL_NAME, s.getStopDefaultName());
if (s.location != null)
cv.put(StopsTable.COL_LOCATION, s.location);
cv.put(StopsTable.COL_LAT, s.getLatitude());
cv.put(StopsTable.COL_LONG, s.getLongitude());
if (s.getAbsurdGTTPlaceName() != null) cv.put(StopsTable.COL_PLACE, s.getAbsurdGTTPlaceName());
cv.put(StopsTable.COL_LINES_STOPPING, s.routesThatStopHereToString());
if (s.type != null) cv.put(StopsTable.COL_TYPE, s.type.getCode());
//Log.d(DEBUG_TAG,cv.toString());
//cpOp.add(ContentProviderOperation.newInsert(uritobeused).withValues(cv).build());
//valuesArr[i] = cv;
- db.insert(StopsTable.TABLE_NAME, null, cv);
+ db.replace(StopsTable.TABLE_NAME,null,cv);
}
db.setTransactionSuccessful();
db.endTransaction();
long endTime = System.currentTimeMillis();
Log.d(DEBUG_TAG,"Inserting stops took: "+((double) (endTime-startTime)/1000)+" s");
final ArrayList<Route> routes = f.getAllLinesFromGTT(gres);
if(routes==null){
Log.w(DEBUG_TAG,"Something went wrong downloading the lines");
return false;
}
db.beginTransaction();
startTime = System.currentTimeMillis();
for (Route r: routes){
final ContentValues cv = new ContentValues();
cv.put(LinesTable.COLUMN_NAME,r.name);
switch (r.type){
case BUS:
cv.put(LinesTable.COLUMN_TYPE,"URBANO");
break;
case RAILWAY:
cv.put(LinesTable.COLUMN_TYPE,"FERROVIA");
break;
case LONG_DISTANCE_BUS:
cv.put(LinesTable.COLUMN_TYPE,"EXTRA");
break;
}
cv.put(LinesTable.COLUMN_DESCRIPTION,r.description);
- db.insert(LinesTable.TABLE_NAME,null,cv);
+ //db.insert(LinesTable.TABLE_NAME,null,cv);
+ int rows = db.update(LinesTable.TABLE_NAME,cv,LinesTable.COLUMN_NAME+" = ?",new String[]{r.name});
+ if(rows<1){ //we haven't changed anything
+ db.insert(LinesTable.TABLE_NAME,null,cv);
+ }
}
db.setTransactionSuccessful();
db.endTransaction();
endTime = System.currentTimeMillis();
Log.d(DEBUG_TAG,"Inserting lines took: "+((double) (endTime-startTime)/1000)+" s");
return true;
}
private int getNewVersion(int trial){
AtomicReference<Fetcher.result> gres = new AtomicReference<>();
String networkRequest = FiveTAPIFetcher.performAPIRequest(FiveTAPIFetcher.QueryType.STOPS_VERSION,null,gres);
if(networkRequest == null){
restartDBUpdateifPossible(trial,gres);
return -2;
}
boolean needed;
try {
JSONObject resp = new JSONObject(networkRequest);
return resp.getInt("id");
} catch (JSONException e) {
e.printStackTrace();
Log.e(DEBUG_TAG,"Error: wrong JSON response\nResponse:\t"+networkRequest);
return -2;
}
}
private void restartDBUpdateifPossible(int currentTrial,AtomicReference<Fetcher.result> res){
if (currentTrial<MAX_TRIALS && res.get()!= Fetcher.result.PARSER_ERROR){
Log.d(DEBUG_TAG,"Update failed, starting new trial ("+currentTrial+")");
startDBUpdate(getApplicationContext(),++currentTrial);
}
}
}
diff --git a/src/it/reyboz/bustorino/middleware/GPSLocationAdapter.java b/src/it/reyboz/bustorino/middleware/GPSLocationAdapter.java
index 59ae17a..e849147 100644
--- a/src/it/reyboz/bustorino/middleware/GPSLocationAdapter.java
+++ b/src/it/reyboz/bustorino/middleware/GPSLocationAdapter.java
@@ -1,48 +1,55 @@
package it.reyboz.bustorino.middleware;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
+import android.util.Log;
public class GPSLocationAdapter implements LocationListener {
private Context con;
private LocationManager locMan;
public GPSLocationAdapter(Context con) {
this.con = con;
locMan = (LocationManager) con.getSystemService(Context.LOCATION_SERVICE);
}
- public void requestPosition(){
-
+ public boolean startRequestingPosition(){
+ try {
+ locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10, this);
+ return true;
+ } catch (SecurityException exc){
+ exc.printStackTrace();
+ return false;
+ }
}
@Override
public void onLocationChanged(Location location) {
-
+ Log.d("GPSLocationListener","found location:\nlat: "+location.getLatitude()+" lon: "+location.getLongitude()+"\naccuracy: "+location.getAccuracy());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
-
+ startRequestingPosition();
}
@Override
public void onProviderDisabled(String provider) {
-
+ locMan.removeUpdates(this);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Apr 22, 15:03 (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1862827
Default Alt Text
(39 KB)

Event Timeline