package com.ushahidi.android.app; import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.List; import android.app.AlertDialog; import android.app.ProgressDialog; 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.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.provider.BaseColumns; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import com.ushahidi.android.app.data.Database; import com.ushahidi.android.app.data.DeploymentProvider; import com.ushahidi.android.app.data.DeploymentsData; import com.ushahidi.android.app.net.Deployments; import com.ushahidi.android.app.util.ApiUtils; import com.ushahidi.android.app.util.Util; public class DeploymentSearch extends Dashboard implements LocationListener { private int deploymentId = 0; private TextView mTextView; private TextView mEmptyList; private ListView mListView; private final String[] items = { "50", "100", "250", "500", "750", "1000", "1500" }; private static final int DIALOG_DISTANCE = 0; private static final int DIALOG_CLEAR_DEPLOYMENT = 1; private static final int DIALOG_ADD_DEPLOYMENT = 2; private boolean refreshState = false; private boolean checkin = false; private LocationManager mLocationMgr = null; private static Location location; private String distance = ""; // Context menu items private static final int DELETE = Menu.FIRST + 1; private Handler mHandler; private DeploymentAdapter deploymentAdapter; private List<DeploymentsData> mDeployments; private static final String TAG = DeploymentSearch.class.getSimpleName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.deployment_search); setTitleFromActivityLabel(R.id.title_text); promptForDeployment(); mTextView = (TextView)findViewById(R.id.search_deployment); mListView = (ListView)findViewById(R.id.deployment_list); mEmptyList = (TextView)findViewById(R.id.empty_list_for_deployments); mDeployments = new ArrayList<DeploymentsData>(); deploymentAdapter = new DeploymentAdapter(this); registerForContextMenu(mListView); mHandler = new Handler(); mTextView.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable arg0) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { showResults(s.toString()); } }); // Define the on-click listener for the list items mListView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final String deploymentId = mDeployments.get(position).getId(); if (isDeploymentActive(Integer.parseInt(deploymentId))) { goToReports(); } else { ReportsTask reportsTask = new ReportsTask(); reportsTask.appContext = DeploymentSearch.this; reportsTask.id = String.valueOf(deploymentId); reportsTask.execute(); } } }); showResults(""); displayEmptyListText(); } // menu stuff @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { menu.add(Menu.NONE, DELETE, Menu.NONE, R.string.delete); } public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item .getMenuInfo(); deploymentId = Integer.parseInt(mDeployments.get(info.position).getId()); switch (item.getItemId()) { // context menu selected case DELETE: // Delete by ID mHandler.post(mDeleteDeploymentById); return (true); } return true; } /** * Delete individual messages 0 - Successfully deleted. 1 - There is nothing * to be deleted. */ final Runnable mDeleteDeploymentById = new Runnable() { public void run() { boolean result = false; result = MainApplication.mDb.deleteDeploymentById(String.valueOf(deploymentId)); try { if (result) { Util.showToast(DeploymentSearch.this, R.string.deployment_deleted); showResults(""); displayEmptyListText(); } else { Util.showToast(DeploymentSearch.this, R.string.deployment_deleted_failed); } } catch (Exception e) { return; } } }; private void updateRefreshStatus() { findViewById(R.id.refresh_report_btn) .setVisibility(refreshState ? View.GONE : View.VISIBLE); findViewById(R.id.title_refresh_progress).setVisibility( refreshState ? View.VISIBLE : View.GONE); } public void displayEmptyListText() { if (mListView.getCount() == 0) { mEmptyList.setVisibility(View.VISIBLE); mTextView.setVisibility(View.GONE); } else { mEmptyList.setVisibility(View.GONE); mTextView.setVisibility(View.VISIBLE); } } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.deployments_search_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.clear_deployments) { createDialog(DIALOG_CLEAR_DEPLOYMENT); return true; } else { return super.onOptionsItemSelected(item); } } @Override public void promptForDeployment() { // Show a toast the user that they search for public Ushahidi // deployments if (Preferences.domain.length() == 0 || Preferences.domain.equals("http://")) { Util.showToast(this, R.string.deployment_search); } } @Override public void onResume() { super.onResume(); } @Override public void onStart() { super.onStart(); } @Override public void onDestroy() { super.onDestroy(); stopLocating(); } public void clearAll() { if (mListView.getCount() == 0) { Util.showToast(this, R.string.no_items_cleared); } else { MainApplication.mDb.deleteAllDeployment(); MainApplication.mDb.clearData(); deploymentAdapter.removeItems(); deploymentAdapter.notifyDataSetChanged(); showResults(""); displayEmptyListText(); // clear the stuff that has been initialized in the // sharedpreferences. Preferences.activeDeployment = 0; Preferences.domain = ""; Preferences.deploymentLatitude = "0.0"; Preferences.deploymentLongitude = "0.0"; Preferences.saveSettings(this); Util.showToast(this, R.string.items_cleared); } } /** * Searches the dictionary and displays results for the given query. * * @param query The search query */ private void showResults(String query) { Cursor cursor = null; Log.i("DeploymentSearch", "String:3 " + query); if (TextUtils.isEmpty(query)) { cursor = MainApplication.mDb.fetchAllDeployments(); } else { Log.i("DeploymentSearch", "String:2 " + query); try { cursor = managedQuery(DeploymentProvider.CONTENT_URI, null, null, new String[] { query }, null); } catch (IllegalArgumentException e) { Log.d(TAG, "Illegal URL: " + DeploymentProvider.CONTENT_URI.toString()); } } // clear everything in the list view if (deploymentAdapter != null) { deploymentAdapter.removeItems(); deploymentAdapter.notifyDataSetChanged(); } mDeployments.clear(); if (cursor != null) { Log.i("DeploymentSearch", "String: " + query); if (cursor.moveToFirst()) { int deploymentIdIndex = cursor.getColumnIndexOrThrow(BaseColumns._ID); int deploymentNameIndex = cursor.getColumnIndexOrThrow(Database.DEPLOYMENT_NAME); int deploymentDescIndex = cursor.getColumnIndexOrThrow(Database.DEPLOYMENT_DESC); int deploymentUrlIndex = cursor.getColumnIndexOrThrow(Database.DEPLOYMENT_URL); if (deploymentAdapter != null) { deploymentAdapter.removeItems(); deploymentAdapter.notifyDataSetChanged(); } mDeployments.clear(); do { DeploymentsData deploymentsData = new DeploymentsData(); mDeployments.add(deploymentsData); deploymentsData.setId(cursor.getString(deploymentIdIndex)); deploymentsData.setName(cursor.getString(deploymentNameIndex)); deploymentsData.setDesc(cursor.getString(deploymentDescIndex)); deploymentsData.setUrl(cursor.getString(deploymentUrlIndex)); deploymentAdapter.addItem(deploymentsData); } while (cursor.moveToNext()); } cursor.close(); deploymentAdapter.notifyDataSetChanged(); mListView.setAdapter(deploymentAdapter); displayEmptyListText(); // There are no results } } /** * Create an alert dialog */ protected void createDialog(int d) { switch (d) { case DIALOG_DISTANCE: AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.select_distance); builder.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { distance = items[item]; setDeviceLocation(); } }); AlertDialog alert = builder.create(); alert.show(); break; case DIALOG_CLEAR_DEPLOYMENT: AlertDialog.Builder clearBuilder = new AlertDialog.Builder(this); clearBuilder .setMessage(getString(R.string.confirm_clear)) .setCancelable(false) .setPositiveButton(getString(R.string.status_yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { clearAll(); showResults(""); } }) .setNegativeButton(getString(R.string.status_no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog clearDialog = clearBuilder.create(); clearDialog.show(); break; case DIALOG_ADD_DEPLOYMENT: LayoutInflater factory = LayoutInflater.from(this); final View textEntryView = factory.inflate(R.layout.deployment_add, null); final EditText deploymentUrl = (EditText)textEntryView .findViewById(R.id.deployment_description_edit); final EditText deploymentName = (EditText)textEntryView .findViewById(R.id.deployment_url_edit); // Validate fields deploymentUrl.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (TextUtils.isEmpty(deploymentUrl.getText().toString())) { deploymentUrl.setText("http://"); } return false; } }); final AlertDialog.Builder addBuilder = new AlertDialog.Builder(this); addBuilder .setTitle(R.string.add_deployment) .setView(textEntryView) .setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // validate URL if ((ApiUtils.validateUshahidiInstance(deploymentUrl.getText() .toString())) && !(TextUtils.isEmpty(deploymentName.getText().toString()))) { MainApplication.mDb.addDeployment(deploymentName.getText() .toString(), deploymentUrl.getText().toString()); showResults(""); } else { Util.showToast(DeploymentSearch.this, R.string.fix_error); } } }) .setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.cancel(); } }); AlertDialog deploymentDialog = addBuilder.create(); deploymentDialog.show(); break; } } /** * Do something when the refresh icon is pressed */ @Override public void onRefreshReports(View v) { createDialog(DIALOG_DISTANCE); } public void onAddDeployment(View v) { createDialog(DIALOG_ADD_DEPLOYMENT); } public void goToReports() { Intent launchIntent; Bundle bundle = new Bundle(); bundle.putInt("tab_index", 0); launchIntent = new Intent(this, IncidentTab.class); launchIntent.putExtra("tab", bundle); startActivityForResult(launchIntent, 0); setResult(RESULT_OK); finish(); } /** * Clear saved reports */ public void clearCachedReports() { // delete unset photo for (int i = 0; i < Preferences.fileName.size(); i++) { File f = new File(Preferences.fileName.get(i)); if (f != null) { if (f.exists()) { f.delete(); } } } // clear persistent data SharedPreferences.Editor editor = getPreferences(0).edit(); editor.putString("title", ""); editor.putString("desc", ""); editor.putString("date", ""); editor.putString("selectedphoto", ""); editor.putInt("requestedcode", 0); editor.commit(); } /** * Fetch deployments * * @author eyedol * @return 0 -- Successfully fetches details of a deployment * @return 1 -- Failed to fetch details of a deployment. * @return 2 -- No internet connection */ public void activateDeployment(String id) { final Cursor cursor; cursor = MainApplication.mDb.fetchDeploymentById(id); String url = ""; String latitude; String longitude; if (cursor != null) { if (cursor.moveToFirst()) { int urlIndex = cursor.getColumnIndexOrThrow(Database.DEPLOYMENT_URL); int latitudeIndex = cursor.getColumnIndexOrThrow(Database.DEPLOYMENT_LATITUDE); int longitudeIndex = cursor.getColumnIndexOrThrow(Database.DEPLOYMENT_LONGITUDE); do { url = cursor.getString(urlIndex); latitude = cursor.getString(latitudeIndex); longitude = cursor.getString(longitudeIndex); Preferences.activeDeployment = Util.toInt(id); Preferences.domain = url; Preferences.deploymentLatitude = latitude; Preferences.deploymentLongitude = longitude; } while (cursor.moveToNext()); } cursor.close(); Preferences.saveSettings(this); Preferences.loadSettings(this); } } Runnable mIsCheckinsEnabled = new Runnable() { public void run() { if (checkin) { Preferences.isCheckinEnabled = 1; } else { Preferences.isCheckinEnabled = 0; } Preferences.saveSettings(DeploymentSearch.this); } }; /** * Checks if checkins is enabled on the configured Ushahidi deployment. */ public void isCheckinsEnabled() { if (ApiUtils.isCheckinEnabled(this)) { Preferences.isCheckinEnabled = 1; } else { Preferences.isCheckinEnabled = 0; } Preferences.saveSettings(this); } // thread class private class RefreshDeploymentTask extends AsyncTask<Void, Void, Boolean> { protected Boolean status; protected Context appContext; private Deployments deployments; protected String distance; protected Location location; @Override protected void onPreExecute() { refreshState = true; updateRefreshStatus(); deployments = new Deployments(appContext); } @Override protected Boolean doInBackground(Void... params) { status = deployments.fetchDeployments(distance, location); return status; } @Override protected void onPostExecute(Boolean result) { if (!status) { Util.showToast(appContext, R.string.could_not_fetch_data); } else { Util.showToast(appContext, R.string.deployment_fetched_successful); } showResults(""); refreshState = false; updateRefreshStatus(); } } /** * Check if a deployment is the active one * * @author eyedol */ public boolean isDeploymentActive(long id) { Preferences.loadSettings(this); if (Preferences.activeDeployment == id) { return true; } return false; } // thread class private class ReportsTask extends AsyncTask<Void, Void, Integer> { protected Integer status; private ProgressDialog dialog; protected Context appContext; protected String id; @Override protected void onPreExecute() { this.dialog = ProgressDialog.show(appContext, getString(R.string.please_wait), getString(R.string.loading), true); } @Override protected Integer doInBackground(Void... params) { activateDeployment(id); isCheckinsEnabled(); if (Preferences.isCheckinEnabled == 0) { status = ApiUtils.processReports(appContext); } else { status = ApiUtils.processCheckins(appContext); } return status; } @Override protected void onPostExecute(Integer result) { try { this.dialog.cancel(); if (result == 4) { Util.showToast(appContext, R.string.internet_connection); } else if (result == 3) { Util.showToast(appContext, R.string.invalid_ushahidi_instance); } else if (result == 2) { Util.showToast(appContext, R.string.ushahidi_sync); } else if (result == 1) { Util.showToast(appContext, R.string.could_not_fetch_reports); } else if (result == 0) { clearCachedReports(); goToReports(); } } catch (IllegalArgumentException e) { Log.e(TAG, "IllegalArgumentException " + e.toString()); } } } /** Location stuff **/ // Fetches the current location of the device. protected void setDeviceLocation() { mLocationMgr = (LocationManager)getSystemService(Context.LOCATION_SERVICE); // Get last known location from either GPS or Network provider Location loc = null; boolean netAvail = (mLocationMgr.getProvider(LocationManager.NETWORK_PROVIDER) != null); boolean gpsAvail = (mLocationMgr.getProvider(LocationManager.GPS_PROVIDER) != null); if (gpsAvail) { loc = mLocationMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER); } else if (netAvail) { loc = mLocationMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } // Just use last location if it's less than 10 minutes old if (loc != null && ((new Date()).getTime() - loc.getTime() < 10 * 60 * 1000)) { onLocationChanged(loc); } else { if (gpsAvail) { mLocationMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } if (netAvail) { mLocationMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); } } } public void stopLocating() { if (mLocationMgr != null) { try { mLocationMgr.removeUpdates(this); } catch (Exception ex) { ex.printStackTrace(); } mLocationMgr = null; } } public void onLocationChanged(Location loc) { if (loc != null) { location = loc; RefreshDeploymentTask deploymentTask = new RefreshDeploymentTask(); deploymentTask.appContext = DeploymentSearch.this; deploymentTask.location = location; deploymentTask.distance = distance; deploymentTask.execute(); stopLocating(); } } public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } }