Java tutorial
/* Copyright 2012 Sbastien Vrillaud Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.kochka.android.weightlogger; import java.io.File; import java.util.LinkedList; import org.kochka.android.weightlogger.adapter.MeasurementsListAdapter; import org.kochka.android.weightlogger.data.Measurement; import org.kochka.android.weightlogger.tools.Export; import org.kochka.android.weightlogger.tools.GarminConnect; import org.kochka.android.weightlogger.tools.StorageNotMountedException; import com.markupartist.android.widget.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.Toast; public class WeightLoggerActivity extends Activity { ListView mList; final int EXPORT_FIT = 0; final int EXPORT_CSV = 1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar); getMenuInflater().inflate(R.menu.home_actionbar, actionBar.asMenu()); mList = (ListView) findViewById(R.id.mListView); MeasurementsListAdapter adapter = new MeasurementsListAdapter(this); mList.setAdapter(adapter); mList.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> a, View v, int position, long id) { Intent i = new Intent(WeightLoggerActivity.this, ShowMeasurementActivity.class); i.putExtra("position", position); startActivityForResult(i, 0); } }); registerForContextMenu(mList); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { if (v.getId() == R.id.mListView) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; menu.setHeaderTitle(((Measurement) mList.getItemAtPosition(info.position)).getFormatedRecordedAt()); menu.add(Menu.NONE, 0, 0, R.string.edit); menu.add(Menu.NONE, 1, 1, R.string.delete); } } @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo menuInfo; menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); final Measurement measurement = (Measurement) mList.getItemAtPosition(menuInfo.position); switch (item.getItemId()) { case 0: Intent i = new Intent(this, EditMeasurementActivity.class); i.putExtra("id", measurement.getId()); startActivityForResult(i, 0); break; case 1: new AlertDialog.Builder(this).setTitle(R.string.confirm_delete) .setIcon(android.R.drawable.ic_dialog_alert) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { measurement.destroy(); ((MeasurementsListAdapter) mList.getAdapter()).refresh(); Toast.makeText(WeightLoggerActivity.this, R.string.record_deleted, Toast.LENGTH_SHORT) .show(); } }).setNegativeButton(android.R.string.no, null).show(); break; } return true; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { ((MeasurementsListAdapter) mList.getAdapter()).refresh(); } } /* Creates the menu items */ public boolean onCreateOptionsMenu(Menu menu) { MenuItem mClose = menu.add(0, 1, 1, R.string.quit); mClose.setIcon(android.R.drawable.ic_menu_close_clear_cancel); MenuItem mPref = menu.add(0, R.id.item_preferences, 2, R.string.pref); mPref.setIcon(android.R.drawable.ic_menu_preferences); return (super.onCreateOptionsMenu(menu)); } /* Handles menu selections */ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.item_add: startActivityForResult(new Intent(this, EditMeasurementActivity.class), 0); break; case R.id.item_graph: startActivity((new Intent(this, GraphActivity.class)).putExtra("type", "line")); break; case R.id.item_export: export(); break; case R.id.item_preferences: startActivityForResult(new Intent(this, EditPreferences.class), 0); break; case 1: this.finish(); return true; } return (super.onOptionsItemSelected(item)); } private void export() { final CharSequence[] items = { "FIT", "CSV", "Garmin Connect " }; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.export); builder.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { switch (item) { case 0: export(EXPORT_FIT, false); break; case 1: export(EXPORT_CSV, false); break; case 2: export(EXPORT_FIT, true); break; default: break; } } }); AlertDialog alert = builder.create(); alert.show(); } private void export(int type, boolean garmin_upload) { class ExportThread implements Runnable { private int type; private boolean garmin_upload; private GarminConnect gc; public ExportThread(int type, boolean garmin_upload) { this.type = type; this.garmin_upload = garmin_upload; } @Override public void run() { try { LinkedList<Measurement> measurements; String filename; String mime; String upload_message = ""; int icon; if (type == EXPORT_FIT) measurements = Measurement.getAllToExport(WeightLoggerActivity.this); else measurements = Measurement.getAll(WeightLoggerActivity.this); int measurements_count = measurements.size(); if (measurements_count == 0) throw new Exception(getString(R.string.no_export)); // FIT if (type == EXPORT_FIT) { // Test connectivity & Garmin account if (garmin_upload) { ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE); if (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting()) { SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences(WeightLoggerActivity.this); String username = preferences.getString("garmin_login", "").trim(); String password = preferences.getString("garmin_password", "").trim(); if (username.equals("") || password.equals("")) throw new Exception(getString(R.string.gc_configure_account)); this.gc = new GarminConnect(); if (!this.gc.signin(username, password)) throw new Exception(getString(R.string.gc_account_error)); } else throw new Exception(getString(R.string.network_error)); } // Build FIT file filename = Export.buildFitFile(WeightLoggerActivity.this, measurements); mime = "application/*"; icon = R.drawable.ic_stat_notify_fit; Measurement.setAllAsExported(WeightLoggerActivity.this); // Upload FIT file if (garmin_upload) { if (this.gc.uploadFitFile( Export.path(WeightLoggerActivity.this) + File.separator + filename)) upload_message = getString(R.string.export_upload_ok); else upload_message = getString(R.string.export_upload_failed); this.gc.close(); } // CSV } else { filename = Export.buildCsvFile(WeightLoggerActivity.this, measurements); mime = "text/csv"; icon = R.drawable.ic_stat_notify_csv; } // Notify NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE); String gen_text = getResources().getQuantityString(R.plurals.exported_records_count, measurements_count, measurements_count) + " : " + filename; Intent i = new Intent(Intent.ACTION_SEND); i.setType(mime); i.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.export_share_subject)); i.putExtra(Intent.EXTRA_TEXT, gen_text); i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile( new File(Export.path(WeightLoggerActivity.this) + File.separator + filename))); PendingIntent pi = PendingIntent.getActivity(WeightLoggerActivity.this, 0, i, 0); NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(WeightLoggerActivity.this); nBuilder.setSmallIcon(icon); nBuilder.setContentTitle(getString(R.string.file_generated)); nBuilder.setContentText((garmin_upload) ? upload_message : gen_text); nBuilder.setContentIntent(pi); notificationManager.notify(1, nBuilder.getNotification()); } catch (StorageNotMountedException e) { displayToast(getString(R.string.storage_not_mounted)); } catch (Exception e) { displayToast(e.getMessage()); } finally { WeightLoggerActivity.this.runOnUiThread(new Runnable() { public void run() { ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar); actionBar.setProgressBarVisibility(View.GONE); } }); } } private void displayToast(final String message) { WeightLoggerActivity.this.runOnUiThread(new Runnable() { public void run() { Toast.makeText(WeightLoggerActivity.this, message, Toast.LENGTH_SHORT).show(); } }); } } ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar); actionBar.setProgressBarVisibility(View.VISIBLE); Runnable r = new ExportThread(type, garmin_upload); new Thread(r).start(); } public static Intent createIntent(Context context) { Intent i = new Intent(context, WeightLoggerActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); return i; } }