package org.redpin.android.ui;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import org.json.JSONException;
import org.redpin.android.Constants;
import org.redpin.android.R;
import org.redpin.android.core.Location;
import org.redpin.android.core.Measurement;
import org.redpin.android.core.User;
import org.redpin.android.core.Vector;
import org.redpin.android.core.measure.WiFiReading;
import org.redpin.android.json.GsonFactory;
import org.redpin.android.net.HttpPostCommand;
import org.redpin.android.net.InternetConnectionManager;
import org.redpin.android.net.wifi.WifiSniffer;
import org.redpin.base.core.History;
import org.redpin.base.core.Task;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.ActionBarActivity;
import android.util.FloatMath;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class LocateUserActivity extends ActionBarActivity implements SensorEventListener {
WifiSniffer mWifiService;
Location mLocation;
Vector<WiFiReading> vectorWifi;
Measurement measurement;
TextView txtLocationName;
Spinner spinnerStatus, spinnerPriority, spinnerTransportType;
Button btnRefresh;
User mCurrentUser;
private boolean isOnline = false;
private SensorManager sensorMan;
private Sensor accelerometer;
private float[] mGravity;
private float mAccel;
private float mAccelCurrent;
private float mAccelLast;
private Timer mTimer;
private static final String TAG = LocateUserActivity.class.getSimpleName();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.locate_user_layout);
txtLocationName = (TextView) findViewById(R.id.txtLocationName);
spinnerStatus = (Spinner) findViewById(R.id.spinnerStatus);
spinnerPriority = (Spinner) findViewById(R.id.spinnerPriority);
spinnerTransportType = (Spinner) findViewById(R.id.spinnerTransportType);
btnRefresh = (Button) findViewById(R.id.btnRefresh);
mTimer = new Timer();
btnRefresh.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mTimer.cancel();
if(mWifiService != null) {
mWifiService.forceMeasurement();
}
}
});
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (position == getCount()) {
((TextView)v.findViewById(android.R.id.text1)).setText("");
((TextView)v.findViewById(android.R.id.text1)).setHint(getItem(getCount())); //"Hint to be displayed"
}
((TextView)v.findViewById(android.R.id.text1)).setGravity(Gravity.CENTER);
return v;
}
@Override
public int getCount() {
return super.getCount()-1; // you dont display last item. It is used as hint.
}
};
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add("Porter dispatched");
adapter.add("Porter arrives");
adapter.add("Begin move");
adapter.add("Complete move");
adapter.add("Porter clears");
adapter.add("Job Status");
spinnerStatus.setAdapter(adapter);
spinnerStatus.setSelection(adapter.getCount());
mCurrentUser = new User();
if(getIntent().hasExtra("userId")) {
mCurrentUser.setRemoteId(getIntent().getIntExtra("userId", 0));
mCurrentUser.setUserName(getIntent().getStringExtra("userName"));
mCurrentUser.setName(getIntent().getStringExtra("name"));
}
bindTransportTypeSpinner();
bindPrioritySpinner();
startWifiSniffer();
new AlertDialog.Builder(this).setPositiveButton(
android.R.string.ok, null)
.setTitle("User Tracking").setMessage("Once connection to server is established, select task, press Start and roam around").create().show();
bindService(new Intent(this, InternetConnectionManager.class), mConnection, Context.BIND_AUTO_CREATE);
registerReceiver(connectionChangeReceiver, new IntentFilter(
InternetConnectionManager.CONNECTIVITY_ACTION));
btnRefresh.setEnabled(false);
/*sensorMan = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mAccel = 0.00f;
mAccelCurrent = SensorManager.GRAVITY_EARTH;
mAccelLast = SensorManager.GRAVITY_EARTH;*/
}
private void bindPrioritySpinner() {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (position == getCount()) {
((TextView)v.findViewById(android.R.id.text1)).setText("");
((TextView)v.findViewById(android.R.id.text1)).setHint(getItem(getCount())); //"Hint to be displayed"
}
((TextView)v.findViewById(android.R.id.text1)).setGravity(Gravity.CENTER);
return v;
}
@Override
public int getCount() {
return super.getCount()-1; // you dont display last item. It is used as hint.
}
};
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add("STAT");
adapter.add("ASAP");
adapter.add("Routine");
adapter.add("Priority Level");
spinnerPriority.setAdapter(adapter);
spinnerPriority.setSelection(adapter.getCount());
}
private void bindTransportTypeSpinner() {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (position == getCount()) {
((TextView)v.findViewById(android.R.id.text1)).setText("");
((TextView)v.findViewById(android.R.id.text1)).setHint(getItem(getCount())); //"Hint to be displayed"
}
((TextView)v.findViewById(android.R.id.text1)).setGravity(Gravity.CENTER);
return v;
}
@Override
public int getCount() {
return super.getCount()-1; // you dont display last item. It is used as hint.
}
};
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add("Patient in wheel chair");
adapter.add("Patient in bed");
adapter.add("Chart");
adapter.add("Blood products");
adapter.add("Equipment");
adapter.add("Transport Type");
spinnerTransportType.setAdapter(adapter);
spinnerTransportType.setSelection(adapter.getCount());
}
@Override
public void onResume() {
super.onResume();
//sensorMan.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
}
private void startWifiSniffer() {
bindService(new Intent(this, WifiSniffer.class), mWifiConnection,
Context.BIND_AUTO_CREATE);
registerReceiver(wifiReceiver,
new IntentFilter(WifiSniffer.WIFI_ACTION));
Log.i(TAG, "Started WifiSniffer");
}
private void stopWifiSniffer() {
if (mWifiService != null) {
mWifiService.stopMeasuring();
}
unbindService(mWifiConnection);
unregisterReceiver(wifiReceiver);
Log.i(TAG, "Stopped WifiSniffer");
}
@Override
protected void onPause() {
//sensorMan.unregisterListener(this);
super.onPause();
}
@Override
protected void onDestroy() {
stopWifiSniffer();
unbindService(mConnection);
unregisterReceiver(connectionChangeReceiver);
super.onDestroy();
}
private ServiceConnection mWifiConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
mWifiService = ((WifiSniffer.LocalBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mWifiService = null;
}
};
private BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Measurement m = mWifiService.retrieveLastMeasurement();
if (m == null)
return;
mWifiService.stopMeasuring();
scheduleScan();
new ServerTask(Constants.FIND_LOCATION_URL, m).execute();
}
};
private void scheduleScan() {
mTimer = null;
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
mWifiService.forceMeasurement();
}
}, 2000);
}
private class ServerTask extends AsyncTask<Void, Void, Location> {
private Gson gson = GsonFactory.getGsonInstance();
String url;
Measurement m;
public ServerTask(String url, Measurement m) {
this.url = url;
this.m = m;
}
@Override
protected Location doInBackground(Void... params) {
Location loc = null;
try {
String str = new HttpPostCommand<String>(this.url, gson.toJson(this.m, new TypeToken<Measurement>() { }.getType())) {
@Override
public String execute() throws IOException, JSONException {
return streamToString(requestStream());
}
}.execute();
loc = gson.fromJson(str, new TypeToken<Location>() { }.getType());
if(loc != null && loc.getRemoteId() > 0) {
History history = new History();
history.setDate(new Date());
history.setLocation(loc);
history.setUser(mCurrentUser);
Task task = new Task();
task.setComment("");
task.setTransportType(spinnerTransportType.getSelectedItem() == null ? "" : spinnerTransportType.getSelectedItem().toString());
task.setPriority(spinnerPriority.getSelectedItem() == null ? "" : spinnerPriority.getSelectedItem().toString());
task.setJobStatus(spinnerStatus.getSelectedItem() == null ? "" : spinnerStatus.getSelectedItem().toString());
history.setTask(task);
try {
new HttpPostCommand<String>(Constants.ADD_HISTORY_URL, gson.toJson(history, new TypeToken<History>() { }.getType())) {
@Override
public String execute() throws IOException, JSONException {
return streamToString(requestStream());
}
}.execute();
} catch(Exception e) { }
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return loc;
}
@Override
protected void onPostExecute(Location location) {
if(location != null && location.getSymbolicID() != null) {
txtLocationName.setText(location.getSymbolicID());
} else {
txtLocationName.setText("Unknown Location");
}
}
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
mGravity = event.values.clone();
float x = mGravity[0];
float y = mGravity[1];
float z = mGravity[2];
mAccelLast = mAccelCurrent;
mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z);
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta;
Log.d("onSensorChanged", System.currentTimeMillis()+","+mAccelCurrent +","+mAccel);
if(mAccel > 3) {
Toast.makeText(this, "Moved", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
* {@link InternetConnectionManager} {@link BroadcastReceiver} for
* retrieving Internet connection changes.
*/
private BroadcastReceiver connectionChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.hasExtra("isOnline")) {
isOnline = intent.getBooleanExtra("isOnline", false);
if(isOnline) {
btnRefresh.setEnabled(true);
}
}
}
};
/**
* {@link InternetConnectionManager} {@link ServiceConnection} to check current online state
*/
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
InternetConnectionManager mManager = ((InternetConnectionManager.LocalBinder)service).getService();
isOnline = mManager.isOnline();
if(isOnline) {
btnRefresh.setEnabled(true);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}