]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blobdiff - QRScanner/mobile/src/main/java/cz/cvut/fel/dce/qrscanner/PreviewActivity.java
Implement viewing of the item compartment number
[hornmich/skoda-qr-demo.git] / QRScanner / mobile / src / main / java / cz / cvut / fel / dce / qrscanner / PreviewActivity.java
index 88e4cb4bed8eca6ae7dde5c9e49d3a61967cfdb1..077656f4dfaa481d06898968976744d1b22b4588 100644 (file)
@@ -2,159 +2,287 @@ package cz.cvut.fel.dce.qrscanner;
 
 import android.content.Context;
 import android.content.Intent;
-import android.content.res.AssetManager;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.RectF;
+import android.media.AudioManager;
 import android.net.Uri;
-import android.os.Environment;
-import android.support.annotation.Nullable;
+import android.os.AsyncTask;
 import android.support.v7.app.ActionBarActivity;
 import android.os.Bundle;
 import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewTreeObserver;
 import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
 import android.widget.Toast;
 
-import com.sun.pdfview.PDFFile;
-import com.sun.pdfview.PDFPage;
-
-import net.sf.andpdf.nio.ByteBuffer;
-
-import org.apache.commons.io.IOUtils;
+import cz.cvut.fel.dce.qrscanner.mupdf.MuPDFActivity;
+import cz.cvut.fel.dce.qrscanner.pdfviewer.PdfPageView;
 
+import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
 import java.io.IOException;
-import java.io.InputStream;
 
-
-public class PreviewActivity extends ActionBarActivity {
+/**
+ * An activity for component picture preview with menu for selecting documents to be shown.
+ *
+ * The activity is designed to be called via an Intent with a component identifier string passed
+ * with the key COMPONENT_ID.
+ *
+ * The activity loads the component picture from the PDF file asynchronously to not block the UI.
+ */
+public class PreviewActivity extends ActionBarActivity implements ViewTreeObserver.OnGlobalLayoutListener {
+       /**
+        * An activity tag for debug, error and info messages.
+        */
        public static final String TAG = "PreviewActivity";
+       /**
+        * The path to the storage folder, where the application stores its data.
+        * <p>This path should not be hardcoded like this, but the Android API functions were returning
+        * paths tht were not valid on our Android devices.</p>
+        */
+       public static final String STORAGE_PATH = "/storage/sdcard0/Pictures";
+       /**
+        * The path in the application data folder, where the component database is.
+        */
        public static final String SKODA_DOCS_PATH_EXTENSION = "/skoda/components/";
-       public static final String SKODA_COMP_PICTURE_NAME = "Abbildung.png";
+       /**
+        * The name of the PDF file containing the pisture of the component.
+        */
+       public static final String SKODA_COMP_PICTURE_NAME = "Abbildung.pdf";
+       /**
+        * The name of the PDF file containing the manufacturing process description.
+        */
+       public static final String SKODA_COMP_MANUFACTURING = "Arbeitseinleitung.pdf";
+       /**
+        * The name of the PDF file containing the manufacturing process description with pictures.
+        */
+       public static final String SKODA_COMP_MANUFACT_IMAGES = "Bild_Arbeitseinleitung.pdf";
+       /**
+        * The name of the PDF file containing the contacts for the component manufacturer.
+        */
+       public static final String SKODA_COMP_CONTACTS = "Angaben.pdf";
+       /**
+        * The name of the PDF file containing the manufacturing guide.
+        */
+       public static final String SKODA_COMP_MANUFACT_GUIDE = "Werkstatt_Einleitung.pdf";
+       /**
+        * The Key of the Component Identifier value, passed as a data to the activity launch intent.
+        */
+       public static final String COMP_ID_INTENT_KEY = "COMPONENT_ID";
+       /**
+        * The name of the file containing aditional information about the component.
+        */
+       public static final String SKODA_COMPONENT_INFO_NAME = "iteminfo.txt";
+
+       /**
+        * The widget for showing the component preview image.
+        */
+       private ImageView mPreviewImg;
+       /**
+        * The container for progress bar widget and text view.
+        * <p>Those two are in the container to make them easily disappear and appear when needed.</p>
+        */
+       private RelativeLayout mProgressContainer;
+       /**
+        * The observer of the view tree for detection of the end of the View tree loading.
+        */
+       private ViewTreeObserver mPreviewImgObserver;
+       /**
+        * The path to the directory containing documents for the component.
+        */
+       private String mComponentRootPath;
+       /**
+        * Widget containing loaded page from a PDF file.
+        */
+       private PdfPageView mPdfView;
+       /**
+        * Flag signalling whether the PDF page has been loaded.
+        */
+       private boolean mPdfLoaded;
+       /**
+        * The widget showing the value of the components compartment.
+        */
+       private TextView mCompartmentValue;
+
 
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_preview);
+               mPdfLoaded = false;
+               mPreviewImg = (ImageView) findViewById(R.id.imgComponent);
+               mProgressContainer = (RelativeLayout) findViewById(R.id.progress_container);
+               mCompartmentValue = (TextView) findViewById(R.id.compartment_value);
+
+               if (mProgressContainer == null) {
+                       Log.e(TAG, "Progress container not found in the activity layout.");
+                       finish();
+               }
+               if (mPreviewImg == null) {
+                       Log.e(TAG, "ImageView for preview image could not be found in the activity layout.");
+                       finish();
+               }
+               if (mCompartmentValue == null) {
+                       Log.e(TAG, "TextView for compartment value could not be found in the activity layout.");
+                       finish();
+               }
+
+
+               mPreviewImgObserver = mPreviewImg.getViewTreeObserver();
+               Log.d(TAG, "Registering mPreviewImgObserver OnGlobalLayoutListener.");
+               mPreviewImgObserver.addOnGlobalLayoutListener(this);
+
                Intent intent = getIntent();
-               String comp_id = intent.getStringExtra("COMPONENT_ID");
-               if (comp_id != null) {
-                       Log.i(TAG, "Received component id: " + comp_id);
-                       String path = "/storage/sdcard0/Pictures" + SKODA_DOCS_PATH_EXTENSION + comp_id + "/";
-                       String picturePath = path + SKODA_COMP_PICTURE_NAME;
-                       Log.i(TAG, "Path to files: " + picturePath);
-                       Bitmap previewBitmap = new BitmapFactory().decodeFile(picturePath);
-                       if (previewBitmap != null) {
-                               ImageView previewImg = (ImageView) findViewById(R.id.imgComponent);
-                               previewImg.setImageBitmap(previewBitmap);
-                               Uri uri = Uri.parse(path + "Bild_Arbeitseinleitung.pdf");
-                               Intent pdfIntent = new Intent(this,MuPDFActivity.class);
-                               pdfIntent.setAction(Intent.ACTION_VIEW);
-                               pdfIntent.setData(uri);
-                               startActivity(intent);
-                       }
-                       else {
-                               Toast toast = Toast.makeText(getApplicationContext(), "File not found", Toast.LENGTH_LONG);
+               String mComponentId = intent.getStringExtra(COMP_ID_INTENT_KEY);
+
+               if (mComponentId != null) {
+                       Log.i(TAG, "Received component id: " + mComponentId);
+                       mComponentRootPath = STORAGE_PATH + SKODA_DOCS_PATH_EXTENSION + mComponentId + "/";
+                       File rootPath = new File(mComponentRootPath);
+                       if (!rootPath.isDirectory()) {
+                               Log.e(TAG, "Component database root directory " + rootPath.getAbsolutePath() + " does not exist.");
+                               Toast toast = Toast.makeText(getApplicationContext(), "Component not found", Toast.LENGTH_LONG);
                                toast.show();
                                finish();
                        }
                }
                else {
-                       Log.i(TAG, "No component id received");
+                       Log.e(TAG, "No component id received.");
+                       finish();
+               }
+               File infoFile = new File(mComponentRootPath + SKODA_COMPONENT_INFO_NAME);
+               if (!infoFile.exists()) {
+                       Log.e(TAG, "Aditional information file " + infoFile.getAbsolutePath() + " does not exist.");
+                       Toast toast = Toast.makeText(getApplicationContext(), "Database not complete", Toast.LENGTH_LONG);
+                       toast.show();
+                       finish();
+               }
+               try {
+                       BufferedReader br = new BufferedReader(new FileReader(infoFile));
+                       String compartmentLine = br.readLine();
+                       if (compartmentLine != null) {
+                               mCompartmentValue.setText(compartmentLine);
+                       }
+                       else {
+                               mCompartmentValue.setText("-");
+                       }
+               } catch (FileNotFoundException e) {
+                       Log.e(TAG, "Aditional information file " + infoFile.getAbsolutePath() + " does not exist.");
+                       Toast toast = Toast.makeText(getApplicationContext(), "Database not complete", Toast.LENGTH_LONG);
+                       toast.show();
+                       e.printStackTrace();
+                       finish();
+               } catch (IOException e) {
+                       Log.e(TAG, "Error while reading the aditional information file " + infoFile.getAbsolutePath());
+                       Toast toast = Toast.makeText(getApplicationContext(), "Database reading failed", Toast.LENGTH_LONG);
+                       toast.show();
+                       e.printStackTrace();
                        finish();
                }
-       }
 
+       }
 
        @Override
-       public boolean onCreateOptionsMenu(Menu menu) {
-               // Inflate the menu; this adds items to the action bar if it is present.
-               getMenuInflater().inflate(R.menu.menu_preview, menu);
-               return true;
+       protected void onDestroy() {
+               super.onDestroy();
+               Log.d(TAG, "Unregister mPreviewImgObserver OnGlobalLayoutListener.");
+               if (mPreviewImgObserver != null && mPreviewImgObserver.isAlive()) {
+                       mPreviewImgObserver.removeOnGlobalLayoutListener(this);
+               }
        }
 
        @Override
-       public boolean onOptionsItemSelected(MenuItem item) {
-               // Handle action bar item clicks here. The action bar will
-               // automatically handle clicks on the Home/Up button, so long
-               // as you specify a parent activity in AndroidManifest.xml.
-               int id = item.getItemId();
-
-               //noinspection SimplifiableIfStatement
-               if (id == R.id.action_settings) {
-                       return true;
+       public void onGlobalLayout() {
+               if (mPdfLoaded) {
+                       Log.d(TAG, "PDF file already loaded.");
+                       return;
                }
+               try {
+                       String picturePath = mComponentRootPath + SKODA_COMP_PICTURE_NAME;
+                       Log.i(TAG, "Path to component files: " + picturePath);
+                       Log.d(TAG, "Loading PDF file " + picturePath);
+                       mPdfView = new PdfPageView(getApplicationContext(), picturePath);
+                       mPdfView.setPage(0);
+                       new LoadPageTask().execute();
+
+                       mPdfLoaded = true;
 
-               return super.onOptionsItemSelected(item);
+               } catch (Exception e) {
+                       Log.e(TAG, "Component picture loading from PDF file failed: " + e.getMessage());
+                       Toast toast = Toast.makeText(getApplicationContext(), "Component preview could not be loaded.", Toast.LENGTH_LONG);
+                       toast.show();
+                       e.printStackTrace();
+               }
        }
 
        /**
-        * Use this to load a pdf file from your assets and render it to a Bitmap.
-        *
-        * @param context
-        *            current context.
-        * @param filePath
-        *            of the pdf file in the assets.
-        * @return a bitmap.
+        * Called when the user touches the button Contacts.
         */
-       @Nullable
-       private static Bitmap renderToBitmap(Context context, String filePath) {
-               Bitmap bi = null;
-               InputStream inStream = null;
-               try {
-                       Log.d(TAG, "Attempting to copy this file: " + filePath);
-                       inStream = new FileInputStream(new File(filePath));
-                       bi = renderToBitmap(context, inStream);
-               } catch (IOException e) {
-                       e.printStackTrace();
-               } finally {
-                       try {
-                               if (inStream != null) {
-                                       inStream.close();
-                               }
-                       } catch (IOException e) {
-                               // do nothing because the stream has already been closed
-                       }
-               }
-               return bi;
+       public void showContacts(View view) {
+               showPDF(mComponentRootPath + SKODA_COMP_CONTACTS);
        }
 
        /**
-        * Use this to render a pdf file given as InputStream to a Bitmap.
-        *
-        * @param context
-        *            current context.
-        * @param inStream
-        *            the inputStream of the pdf file.
-        * @return a bitmap.
+        * Called when the user touches the button Manufacturing.
         */
-       @Nullable
-       private static Bitmap renderToBitmap(Context context, InputStream inStream) {
-               Bitmap bi = null;
-               try {
-                       byte[] decode = IOUtils.toByteArray(inStream);
-                       ByteBuffer buf = ByteBuffer.wrap(decode);
-                       PDFFile pdfFile = new PDFFile(buf);
-                       int numPages = pdfFile.getNumPages();
-                       Log.i(TAG, "Num pages: " + Integer.toString(numPages));
-                       PDFPage mPdfPage = new PDFFile(buf).getPage(0);
-                       float width = mPdfPage.getWidth();
-                       float height = mPdfPage.getHeight();
-                       RectF clip = null;
-                       bi = mPdfPage.getImage((int) (width), (int) (height), clip, false,
-                                       true);
-               } catch (IOException e) {
-                       e.printStackTrace();
-               } finally {
-                       try {
-                               inStream.close();
-                       } catch (IOException e) {
-                               // do nothing because the stream has already been closed
-                       }
+       public void showManufacturing(View view) {
+               showPDF(mComponentRootPath + SKODA_COMP_MANUFACTURING);
+       }
+
+       /**
+        * Called when the user touches the button Manufacturing pictured
+        */
+       public void showManufactImages(View view) {
+               showPDF(mComponentRootPath + SKODA_COMP_MANUFACT_IMAGES);
+       }
+
+       /**
+        * Called when the user touches the button Manufacture guide
+        */
+       public void showManufactGuide(View view) {
+               showPDF(mComponentRootPath + SKODA_COMP_MANUFACT_GUIDE);
+       }
+
+       /**
+        * Launch an activity to show the PDF file.
+        * @param filePath Path to the PDF file to be shown
+        */
+       private void showPDF(String filePath) {
+               Uri uri = Uri.parse(filePath);
+               Intent pdfIntent = new Intent(this, MuPDFActivity.class);
+               pdfIntent.setAction(Intent.ACTION_VIEW);
+               pdfIntent.setData(uri);
+               startActivity(pdfIntent);
+       }
+
+       /**
+        * Class for asynchronous loading of the PDF page to a bitmap.
+        */
+       private class LoadPageTask extends AsyncTask<Void, Void, Void> {
+
+               @Override
+               protected Void doInBackground(Void[] objects) {
+                       mPdfView.loadPage();
+                       return null;
+               }
+
+               @Override
+               protected void onPreExecute() {
+                       super.onPreExecute();
+                       Log.d(TAG, "Starting loading of the PDF page asynchronously.");
+                       mProgressContainer.setVisibility(View.VISIBLE);
+               }
+
+               @Override
+               protected void onPostExecute(Void aVoid) {
+                       super.onPostExecute(aVoid);
+                       mProgressContainer.setVisibility(View.INVISIBLE);
+                       mPreviewImg.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+                       mPreviewImg.setImageBitmap(mPdfView.getPageBitmap());
+                       mPreviewImg.invalidate();
+                       Log.d(TAG, "PDF page loaded.");
                }
-               return bi;
        }
 }