package tof.cv.mpp;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.v4.app.ListFragment;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import java.util.ArrayList;
import java.util.Collections;
import tof.cv.mpp.Utils.DbAdapterLocation;
import tof.cv.mpp.Utils.GPS;
import tof.cv.mpp.adapter.StationLocationAdapter;
import tof.cv.mpp.bo.StationLocation;
import tof.cv.mpp.bo.StationLocationApi;
public class ClosestFragment extends ListFragment {
protected static final String TAG = "ClosestFragment";
private MyGPSLocationListener locationGpsListener;
private MyNetworkLocationListener locationNetworkListener;
private LocationManager locationManager;
private Button btnUpdate;
private Location bestLocationFound;
private boolean threadLock = false;
private boolean isFirst = false;
private MyProgressDialog m_ProgressDialog;
private Thread thread = null;
private StationLocationAdapter myLocationAdapter;
private String strCharacters;
private DbAdapterLocation mDbHelper;
ArrayList<StationLocation> stationList = new ArrayList<StationLocation>();
Cursor locationCursor;
private TextView tvEmpty;
private Button btEmpty;
StationLocation clicked;
private static final long INT_MINTIME = 3000;
private static final long INT_MINDISTANCE = 50;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_closest, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(R.string.nav_drawer_closest);
((AppCompatActivity) getActivity()).getSupportActionBar().setSubtitle(null);
m_ProgressDialog = new MyProgressDialog(getActivity());
mDbHelper = new DbAdapterLocation(getActivity());
tvEmpty = (TextView) getView().findViewById(R.id.empty_tv);
btEmpty = (Button) getView().findViewById(R.id.empty_bt);
btEmpty.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent myIntent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
});
btnUpdate = (Button) getView().findViewById(R.id.btn_update);
btnUpdate.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
if (!threadLock) {
notifyList(true);
btnUpdate.setVisibility(View.GONE);
}
}
});
locationManager = (LocationManager) getActivity().getSystemService(
Context.LOCATION_SERVICE);
locationGpsListener = new MyGPSLocationListener();
locationNetworkListener = new MyNetworkLocationListener();
myLocationAdapter = new StationLocationAdapter(getActivity(),
R.layout.row_closest, new ArrayList<StationLocation>());
setListAdapter(myLocationAdapter);
bestLocationFound = GPS.getLastLoc(this.getActivity());
if (bestLocationFound != null)
updateListToBestLocationNew(bestLocationFound);
}
public void onListItemClick(ListView l, View v, int position, long id) {
final CharSequence[] items = {getString(R.string.info), getString(R.string.closest_navigate),
getString(R.string.closest_map)};
final StationLocation clicked = (StationLocation) l
.getItemAtPosition(position);
AlertDialog.Builder builder = new AlertDialog.Builder(
this.getActivity());
builder.setTitle(clicked.getStation());
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
// Toast.makeText(getActivity().getApplicationContext(),
// items[item], Toast.LENGTH_SHORT).show();
switch (item) {
case 0:
Intent it = new Intent(getActivity(),
InfoStationActivity.class);
it.putExtra("Name", clicked.getStation());
it.putExtra("ID", clicked.getId());
//Log.e("CVE", "CLICK " + clicked.getId());
startActivity(it);
break;
case 1:
try {
Uri uri = Uri.parse("google.navigation:q="
+ ((double) clicked.getLat() / 1E6) + ","
+ ((double) clicked.getLon() / 1E6));
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
} catch (ActivityNotFoundException e) {
(Toast.makeText(getActivity(),
R.string.closest_navigate_err,
Toast.LENGTH_LONG)).show();
}
break;
case 2:
try {
Intent i = new Intent(
android.content.Intent.ACTION_VIEW, Uri
.parse("geo:0,0?q="
+ (clicked.getLat() / 1E6)
+ ","
+ (clicked.getLon() / 1E6)
+ " (" + clicked.getStation()
+ ")"));
/*
* Intent i = new Intent(getActivity(),
* MapStationActivity.class);
*
* i.putExtra("Name", clicked.getStation());
* i.putExtra("lat", (clicked.getLat() / 1E6));
*
* i.putExtra("lon", (clicked.getLon() / 1E6));
*/
startActivity(i);
} catch (ActivityNotFoundException e) {
(Toast.makeText(getActivity(), R.string.closest_map_err,
Toast.LENGTH_LONG)).show();
}
break;
}
}
});
builder.create().show();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(Menu.NONE, 0, Menu.NONE, R.string.refresh)
.setIcon(R.drawable.ic_menu_refresh)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0:
m_ProgressDialog = new MyProgressDialog(this.getActivity());
m_ProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
m_ProgressDialog.setCancelable(false);
m_ProgressDialog.setTitle(getString(R.string.patient));
m_ProgressDialog.setMessage(getString(R.string.closest_looking));
m_ProgressDialog.show();
downloadStationListFromApi();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private class MyGPSLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc) {
Log.v(TAG, "GPS");
locationManager.removeUpdates(locationNetworkListener);
if (loc != null) {
// GPS Location is considered as the best
// We can of course improve that.
bestLocationFound = loc;
btnUpdate.setVisibility(View.VISIBLE);
btnUpdate.setText(getActivity().getString(
R.string.closest_update_gps, loc.getAccuracy()));
if (!threadLock)
notifyList(false);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
}
private class MyNetworkLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc) {
if (loc != null && btnUpdate != null && getActivity() != null) {
bestLocationFound = loc;
btnUpdate.setVisibility(View.VISIBLE);
btnUpdate.setText(getActivity().getString(
R.string.closest_update_gps, loc.getAccuracy()));
if (!threadLock)
notifyList(false);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
private void updateListToBestLocationNew(final Location loc) {
startTime = System.currentTimeMillis();
final SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (mPrefs.getString("stations", "").length() > 1) {
StationLocationApi cache = new Gson().fromJson(mPrefs.getString("stations", ""), StationLocationApi.class);
stationList = cache.station;
myLocationAdapter.clear();
int i = 0;
for (StationLocation object : stationList) {
float[] results = new float[1];
Location.distanceBetween(loc.getLatitude(), loc.getLongitude(),
object.getLat(), object.getLon(),
results);
object.setAway(results[0]);
stationList.set(i, object);
i++;
}
Collections.sort(stationList);
for (StationLocation object : stationList) {
myLocationAdapter.add(object);
}
myLocationAdapter.notifyDataSetChanged();
Log.e("CVE", "Time With JSON from cache: " + (System.currentTimeMillis() - startTime));
} else
Ion.with(getActivity())
.load("http://api.irail.be/stations.php?format=json")
.as(new TypeToken<StationLocationApi>() {
})
.setCallback(new FutureCallback<StationLocationApi>() {
@Override
public void onCompleted(Exception e, StationLocationApi apiList) {
if (apiList != null && apiList.station != null) {
SharedPreferences.Editor ed = mPrefs.edit();
Gson gson = new Gson();
ed.putString("stations", gson.toJson(apiList));
ed.apply();
stationList = apiList.station;
myLocationAdapter.clear();
int i = 0;
for (StationLocation object : stationList) {
float[] results = new float[1];
Location.distanceBetween(loc.getLatitude(), loc.getLongitude(),
object.getLat(), object.getLon(),
results);
object.setAway(results[0]);
stationList.set(i, object);
i++;
}
Collections.sort(stationList);
for (StationLocation object : stationList) {
myLocationAdapter.add(object);
}
myLocationAdapter.notifyDataSetChanged();
Log.e("CVE", "Time With JSON from URL: " + (System.currentTimeMillis() - startTime));
}
}
});
getActivity().runOnUiThread(hideProgressdialog);
Log.v(TAG, "Finish to parse");
}
long startTime;
private Runnable lockOff = new Runnable() {
public void run() {
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
};
private Runnable lockOn = new Runnable() {
public void run() {
getActivity().getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
};
class MyProgressDialog extends ProgressDialog {
public MyProgressDialog(Context context) {
super(context);
}
public void onBackPressed() {
super.onBackPressed();
try {//Lazy catching - bug report from Play Store
if (thread != null)
thread.interrupt();
getActivity().runOnUiThread(hideProgressdialog);
thread.interrupt();
} catch (Exception e) {
e.printStackTrace();
}
return;
}
}
private Runnable hideProgressdialog = new Runnable() {
public void run() {
m_ProgressDialog.dismiss();
}
};
protected void downloadStationListFromApi() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.patient))
.setMessage(getString(R.string.closest_first_download))
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
/* Runnable fillDataRunnable = new Runnable() {
public void run() {
downloadStationListThread();
}
};
thread = new Thread(null, fillDataRunnable,
"MagentoBackground");
thread.start();*/
mDbHelper.open();
getActivity().runOnUiThread(lockOff);
DownloadAndParseStationList();
mDbHelper.open();
final Cursor locationCursor = mDbHelper.fetchAllLocations();
if (locationCursor.getCount() > 0) {
// TODO Refresh
mDbHelper.close();
} else {
Activity a = getActivity();
if (a != null) {
a.runOnUiThread(hideProgressdialog);
a.runOnUiThread(noConnexion);
}
}
getActivity().runOnUiThread(lockOn);
mDbHelper.close();
try {
m_ProgressDialog.hide();
m_ProgressDialog = new MyProgressDialog(
getActivity());
// Looper.prepare();
} catch (Exception e) {
e.printStackTrace();
}
m_ProgressDialog.setCancelable(false);
m_ProgressDialog
.setTitle(getString(R.string.patient));
m_ProgressDialog
.setMessage(getString(R.string.closest_downloading));
m_ProgressDialog.setMax(660);
m_ProgressDialog.show();
}
});
AlertDialog alert = builder.create();
alert.show();
}
/**
* Fill the list at the activity creation
*/
public void downloadStationListThread() {
mDbHelper.open();
getActivity().runOnUiThread(lockOff);
DownloadAndParseStationList();
mDbHelper.open();
final Cursor locationCursor = mDbHelper.fetchAllLocations();
if (locationCursor.getCount() > 0) {
// TODO Refresh
mDbHelper.close();
} else {
Activity a = getActivity();
if (a != null) {
a.runOnUiThread(hideProgressdialog);
a.runOnUiThread(noConnexion);
}
}
getActivity().runOnUiThread(lockOn);
mDbHelper.close();
}
/**
* Each time I come back in the activity, I listen to GPS
*/
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "RESUME");
String txt = "";
locationManager = (LocationManager) getActivity().getSystemService(
Context.LOCATION_SERVICE);
for (String aProvider : locationManager.getAllProviders())
txt += ("<br>"
+ aProvider
+ ": <b>"
+ (locationManager.isProviderEnabled(aProvider) ? "ON"
: "OFF") + "</b>");
txt += "<br><br>" + getString(R.string.closest_tuto_gps);
tvEmpty.setText(Html.fromHtml(txt));
try {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, INT_MINTIME, INT_MINDISTANCE,
locationGpsListener);
} catch (Exception e) {
Log.i("", "No GPS on this device");
}
try {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, INT_MINTIME, INT_MINDISTANCE,
locationNetworkListener);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Each time I leave the activity, I stop listening to GPS (battery)
*/
@Override
public void onPause() {
super.onPause();
if (locationManager != null) {
locationManager.removeUpdates(locationGpsListener);
locationManager.removeUpdates(locationNetworkListener);
}
locationManager = null;
}
/*
public void compareStationsListToMyLocation(Cursor locationCursor, int i,
double lat, double lon) {
locationCursor.moveToPosition(i);
String strName = locationCursor.getString(locationCursor
.getColumnIndex(DbAdapterLocation.KEY_STATION_NAME));
m_ProgressDialog.incrementProgressBy(1);
double iLat = locationCursor.getInt(locationCursor
.getColumnIndex(DbAdapterLocation.KEY_STATION_LAT));
double iLon = locationCursor.getInt(locationCursor
.getColumnIndex(DbAdapterLocation.KEY_STATION_LON));
String id = locationCursor.getString(locationCursor
.getColumnIndex(DbAdapterLocation.KEY_STATION_ID));
double dDis = StationLocationAdapter.distance(lat, lon, iLat / 1E6,
iLon / 1E6);
stationList.add(new StationLocation(strName, iLat, iLon, dDis + "", id));
}*/
public void DownloadAndParseStationList() {
try {
Ion.with(getActivity())
.load("http://api.irail.be/stations.php?format=json")
.as(new TypeToken<StationLocationApi>() {
})
.setCallback(new FutureCallback<StationLocationApi>() {
@Override
public void onCompleted(Exception e, StationLocationApi apiList) {
if(apiList == null || apiList.station == null){
m_ProgressDialog.hide();
return;
}
mDbHelper.open();
Log.e("CVE", "SIZE= " + apiList.station.size() + "");
if (apiList.station.size() > 0)
mDbHelper.deleteAllLocations();
for (final StationLocation anItem : apiList.station) {
mDbHelper.createStationLocation(anItem.getStation(), anItem.getId(), (int) (anItem.getLat() * 1E6),
(int) (anItem.getLon() * 1E6), 0.0);
/*getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
m_ProgressDialog.setMessage(anItem.getStation());
m_ProgressDialog.incrementProgressBy(1);
}
});*/
}
m_ProgressDialog.hide();
mDbHelper.close();
}
});
getActivity().runOnUiThread(hideProgressdialog);
Log.v(TAG, "Finish to parse");
} catch (Exception e) {
e.printStackTrace();
Log.v(TAG, "Connexion error");
try {
getActivity().runOnUiThread(noConnexion);
getActivity().runOnUiThread(hideProgressdialog);
} catch (Exception f) {
// Si il a quitté l'activité.
}
}
}
private Runnable noConnexion = new Runnable() {
public void run() {
getActivity().runOnUiThread(hideProgressdialog);
tvEmpty.setText(R.string.check_connection);
if (locationManager != null) {
locationManager.removeUpdates(locationGpsListener);
locationManager.removeUpdates(locationNetworkListener);
}
locationManager = null;
}
};
public void notifyList(boolean manual) {
/* threadLock = true;
// m_ProgressDialog.hide();
m_ProgressDialog = new MyProgressDialog(this.getActivity());
m_ProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
m_ProgressDialog.setCancelable(false);
m_ProgressDialog.setTitle(getString(R.string.txt_patient));
m_ProgressDialog.setMessage(getString(R.string.txt_fill_closest));
m_ProgressDialog.show();
// I only update automatically first time
if (!isFirst || manual) {
isFirst = true;
// Upate the list and notify Adapter
Runnable notifyListRunnable = new Runnable() {
public void run() {
updateListToBestLocation();
myLocationAdapter.clear();
//Log.e("CVE", "SIZE= " + stationList.size());
for (StationLocation object : stationList) {
myLocationAdapter.add(object);
}
myLocationAdapter.notifyDataSetChanged();
threadLock = false;
m_ProgressDialog.hide();
Log.e("CVE", "Time With Database: " + (System.currentTimeMillis() - startTime));
}
};
getActivity().runOnUiThread(notifyListRunnable);
}
threadLock = false;
m_ProgressDialog.hide();*/
}
}