package what.whatandroid.barcode; import android.content.ContentResolver; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteStatement; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.view.*; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import api.barcode.Barcode; import what.whatandroid.R; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * The barcode scanner fragment, user can view the list of saved barcodes, * edit them and be redirected to ZXing Barcode scanner to scan more */ public class BarcodeFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<Barcode>> { private BarcodeAdapter barcodeAdapter; private TextView noBarcodes; public BarcodeFragment(){ //Required empty ctor } @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setHasOptionsMenu(true); //See if we got an intent containing some barcodes to add, we also don't want to re-handle an //intent if orientation changed or such, so ignore it if we've got a saved state if (savedInstanceState == null){ Intent intent = getActivity().getIntent(); String action = intent.getAction(); String type = intent.getType(); if (Intent.ACTION_SEND.equals(action) && type != null && type.equals("text/csv")){ Uri history = intent.getParcelableExtra(Intent.EXTRA_STREAM); ContentResolver resolver = getActivity().getContentResolver(); if (history != null){ try { List<Barcode> barcodes = new ArrayList<Barcode>(); InputStream in = new BufferedInputStream(resolver.openInputStream(history)); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); for (String line = reader.readLine(); line != null; line = reader.readLine()){ String info[] = line.replaceAll("\"", "").split(","); //Read the barcode info for exported product barcodes only if (info[2].matches("(UPC|EAN|RSS)_.+")){ barcodes.add(new Barcode(info[0], new Date(Long.parseLong(info[3])))); } } new CreateBarcodesTask().execute(barcodes); } catch (Exception e){ e.printStackTrace(); } } } } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ View view = inflater.inflate(R.layout.fragment_list_view, container, false); ListView list = (ListView)view.findViewById(R.id.list); noBarcodes = (TextView)view.findViewById(R.id.no_content_notice); noBarcodes.setText("No barcodes"); barcodeAdapter = new BarcodeAdapter(getActivity(), noBarcodes); list.setAdapter(barcodeAdapter); return view; } @Override public void onResume(){ super.onResume(); //We always want to read the latest information from the database getLoaderManager().restartLoader(0, null, this); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ inflater.inflate(R.menu.barcodes, menu); } @Override public boolean onOptionsItemSelected(MenuItem item){ if (item.getItemId() == R.id.action_delete){ new DeleteBarcodeTask(getActivity()).execute(); barcodeAdapter.clear(); barcodeAdapter.notifyDataSetChanged(); noBarcodes.setVisibility(View.VISIBLE); return true; } else if (item.getItemId() == R.id.action_new){ new ScannerDialog().show(getChildFragmentManager(), "scanner_dialog"); return true; } return false; } @Override public Loader<List<Barcode>> onCreateLoader(int id, Bundle args){ return new BarcodeAsyncLoader(getActivity()); } @Override public void onLoadFinished(Loader<List<Barcode>> loader, List<Barcode> data){ barcodeAdapter.clear(); if (data == null || data.isEmpty()){ noBarcodes.setVisibility(View.VISIBLE); } else { noBarcodes.setVisibility(View.GONE); barcodeAdapter.addAll(data); } barcodeAdapter.notifyDataSetChanged(); } @Override public void onLoaderReset(Loader<List<Barcode>> loader){ } /** * Add some barcode to the database and the viewed list of barcodes */ public void addBarcode(Barcode b){ List<Barcode> barcodes = new ArrayList<Barcode>(); barcodes.add(b); new CreateBarcodesTask().execute(barcodes); } /** * Async task to write new barcodes to the database, if an entry already exists with the * same UPC the barcode is ignored. */ private class CreateBarcodesTask extends AsyncTask<List<Barcode>, Void, Boolean> { private BarcodeDatabaseHelper helper; public CreateBarcodesTask(){ helper = new BarcodeDatabaseHelper(getActivity()); } @Override protected Boolean doInBackground(List<Barcode>... params){ try { SQLiteDatabase database = helper.getWritableDatabase(); if (database != null){ SQLiteStatement statement = database.compileStatement("INSERT OR IGNORE INTO " + BarcodeDatabaseHelper.TABLE + "(" + BarcodeDatabaseHelper.COL_UPC + ", " + BarcodeDatabaseHelper.COL_DATE + ", " + BarcodeDatabaseHelper.COL_TERMS + ", " + BarcodeDatabaseHelper.COL_TAGS + ", " + BarcodeDatabaseHelper.COL_LABEL + ") VALUES(?, ?, ?, ?, ?);"); for (Barcode b : params[0]){ statement.bindString(1, b.getUpc()); statement.bindLong(2, b.getAdded().getTime()); statement.bindString(3, b.getSearchTerms()); statement.bindString(4, b.getSearchTags()); statement.bindString(5, b.getUserLabel()); statement.executeInsert(); } statement.close(); database.close(); } return true; } catch (SQLiteException e){ e.printStackTrace(); } return false; } @Override protected void onPostExecute(Boolean status){ if (status){ Toast.makeText(getActivity(), "Barcodes added", Toast.LENGTH_SHORT).show(); //Reload viewed barcodes getLoaderManager().restartLoader(0, null, BarcodeFragment.this); } else { Toast.makeText(getActivity(), "Could not add barcodes", Toast.LENGTH_SHORT).show(); } } } }