title: How do i open a pdf from a blob stored in sqlite database in android?
body: <p>In my app, i would like to be able to open a connection to my sqlite database and retrieve a single row containing an id, a name, and a blob which is a byte [] of a pdf. How do I go about doing this? </p>
  
  <p>MainActivity.class is responsible for all the work. It converts a pdf from my assets folder  into a byte array which I store as a blob in my SQLite Database. However when i go to open the file, there is no data in it. </p>
  
  <p>Can anyone help me with what I am doing wrong here??!</p>
  
  <p>My MainActivity: </p>
  
  <pre><code>public class MainActivity extends Activity {
  
  //-------------------------------------------------------------------
  // Member Variables
  //-------------------------------------------------------------------
  
  // UI components
  private Button mViewPDFButton           = null;
  private TextView mDirectionsTextView    = null;
  
  // File name of the PDF we want to store 
  private final String FILE_NAME      = "my-pdf-file.pdf";
  private InputStream inputStream;
  private byte [] pdfFileArray        = null;
  private PDFDbAdapter pdfAdapter     = null;
  private ByteArrayOutputStream buffer;
  
  // Directions
  private String text = "To view a PDF from internal storage, click the \'View PDF\' button on the bottom of the screen.";
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      // Initialize the UI
      mViewPDFButton      = (Button) findViewById(R.id.ViewPDFButton);
      mDirectionsTextView = (TextView) findViewById(R.id.directionsTextView);
  
      // Set the Text for the directions
      mDirectionsTextView.setText(text);
  
      // Call to Copy the File to the Internal Storage
      copyFileToDatabase(FILE_NAME);
  
      // Add a listener to the button
      mViewPDFButton.setOnClickListener(ViewPDFListener);
  
  
  
  
  
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
  }
  
  //-----------------------------------------------------------------------------------
  // Private Methods
  //-----------------------------------------------------------------------------------
  private void copyFileToDatabase(String fileName){
  
      // Get the Application Assets from the asset manager
      AssetManager assetManager = getBaseContext().getAssets();
  
      // Attempt to process the file input stream
      try{
          // use the asset manager to open the file
          inputStream = assetManager.open(fileName);
  
          // Initialize the adapter reference using the base context
          pdfAdapter = new PDFDbAdapter(getBaseContext());
          pdfAdapter.open();
  
          // Create the byte array from the input stream
          pdfFileArray = convertToByteArray(inputStream);
  
          // Store the byte array in the database
          pdfAdapter.createPDFFile(fileName, pdfFileArray);
  
      }catch(IOException ex){
  
          // Print the stack trace from the exception
          ex.printStackTrace();
      }
  
  }
  
  // Launch the new Intent with the file stored in the DB
  private void launchPDFIntent(){
  
      // Initialize the Cursor for the adapter
      Cursor cursor = pdfAdapter.fetchPDFFile(0);
  
      // Move the cursor to the first position
      cursor.moveToPosition(0);
  
      // create a String to hold the current File name
      String fileName;
  
      // Create a byte array to hold the array returned from the cursor
      byte [] blobArray = null;
  
      // Loop through using the cursor
      while(cursor.moveToNext()){
  
          // Get the id from the cursor
          int id = cursor.getInt(0);
  
          // get the file name from the cursor
          fileName = cursor.getString(1);
  
          // get the array from the cursor
          blobArray = cursor.getBlob(2);
      }
  
      // Create a new file from the returned byte array
      File pdfFile = convertBytesToFile(blobArray);
  
      Uri path = Uri.fromFile(pdfFile);
  
      // Parse the file into a uri to share with another application
  
      Intent newIntent = new Intent(Intent.ACTION_VIEW);
      newIntent.setDataAndType(path, "application/pdf");
      newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  
      try{
          startActivity(newIntent);
      }catch(ActivityNotFoundException ex){
          ex.printStackTrace();
      }
  
  }
  
  // Converts the array of bytes into a File
  private File convertBytesToFile(byte [] byteToConvert){
  
      File fileToReturn = new File( Environment.getExternalStorageDirectory() + "/PDF-doc.pdf");
  
      try{
  
          FileOutputStream fileOutputStream = new FileOutputStream(fileToReturn);
          fileOutputStream.write(byteToConvert);
          fileOutputStream.close();
  
      }catch(FileNotFoundException ex){
          ex.printStackTrace();
      }catch(Exception ex){
          ex.printStackTrace();
      }
  
      return fileToReturn;
  }
  
  
  // Converts the pdf file from assets to a byte array for storage in the database
  private byte[] convertToByteArray(InputStream input){
      int nRead = 0;
      byte [] convertedData = new byte[16384];
      buffer = new ByteArrayOutputStream();
  
      try{
  
          // Read the data into the array
          while((nRead = input.read(convertedData, 0, convertedData.length)) != -1){
              buffer.write(convertedData, 0, nRead);
          }
  
          // Flush the buffer
          buffer.flush();
  
  
      }catch(IOException ex){
          ex.printStackTrace();
          return null;
      }
  
  return buffer.toByteArray();
  }
  
  
  //-----------------------------------------------------------------------------------
  // Actions
  //-----------------------------------------------------------------------------------
  
  // Listener for the button to view the PDF
  private OnClickListener ViewPDFListener = new OnClickListener(){
  
      @Override
      public void onClick(View arg0) {
  
          launchPDFIntent();
  
      }
  
  };
  
  }
  </code></pre>
  
  <p><strong>UPDATE</strong> - Here is the Activity that ended up working for me. This demonstrates a few things that should probably be done in separate classes. This file copies a pdf from the assets folder and stores it into a db as a blob, then on a button click retrieves the blob from the db and launches any ACTION_VIEW intent for any application of this type. Hope this helps someone, it took me a little while to get it right!</p>
  
  <pre><code>public class MainActivity extends Activity {
  
  //-------------------------------------------------------------------
  // Member Variables
  //-------------------------------------------------------------------
  
  private static final String TAG = "PDFViewer";
  
  // UI components
  private Button mViewPDFButton           = null;
  private TextView mDirectionsTextView    = null;
  
  // File name of the PDF we want to store 
  private final String FILE_NAME      = "my-pdf-file.pdf";
  private InputStream inputStream;
  private byte [] pdfFileArray        = null;
  private PDFDbAdapter pdfAdapter     = null;
  private ByteArrayOutputStream buffer;
  private String fileName;
  
  // Directions
  private String text = "To view a PDF from internal storage, click the \'View PDF\' button on the bottom of the screen.";
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      // Initialize the UI
      mViewPDFButton      = (Button) findViewById(R.id.ViewPDFButton);
      mDirectionsTextView = (TextView) findViewById(R.id.directionsTextView);
  
      // Set the Text for the directions
      mDirectionsTextView.setText(text);
  
      // Call to Copy the File to the Internal Storage
      copyFileToDatabase(FILE_NAME);
  
      // Add a listener to the button
      mViewPDFButton.setOnClickListener(ViewPDFListener);
  
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
  }
  
  //-----------------------------------------------------------------------------------
  // Private Methods
  //-----------------------------------------------------------------------------------
  private void copyFileToDatabase(String fileName){
  
      // Get the Application Assets from the asset manager
      AssetManager assetManager = getBaseContext().getAssets();
  
      // Attempt to process the file input stream
      try{
          // use the asset manager to open the file
          inputStream = assetManager.open(fileName);
  
          // Initialize the adapter reference using the base context
          pdfAdapter = new PDFDbAdapter(getBaseContext());
          pdfAdapter.open();
  
          // Create the byte array from the input stream
          pdfFileArray = convertToByteArray(inputStream);
  
          // flush the buffer, since the operation is complete
          buffer.flush();
  
          // Store the byte array in the database
          pdfAdapter.createPDFFile(fileName, pdfFileArray);
  
      }catch(IOException ex){
  
          // Print the stack trace from the exception
          ex.printStackTrace();
      }
  
      pdfAdapter.close();
  
  }
  
  // Launch the new Intent with the file stored in the DB
  private void launchPDFIntent(){
  
      pdfAdapter = new PDFDbAdapter(getBaseContext());
      pdfAdapter.open();
  
      // Initialize the Cursor for the adapter
      Cursor cursor = pdfAdapter.fetchPDFFile(1);
  
      // Move the cursor to the first position
      cursor.moveToFirst();
  
      // Create a byte array to hold the array returned from the cursor
      byte [] blobArray = null;
  
      // Get the id from the cursor
      int id = cursor.getInt(0);
  
      // get the file name from the cursor
      fileName = cursor.getString(1);
  
      // get the array from the cursor
      blobArray = cursor.getBlob(2);
      Log.d("PDF_SIZE", "The array is: "+ blobArray.length);
  
  
      // Create a new file from the returned byte array
      File pdfFile = convertBytesToFile(blobArray);
  
      // The unique identifier for the file
      Uri path = Uri.fromFile(pdfFile);
  
      // Parse the file into a uri to share with another application
  
      Intent newIntent = new Intent(Intent.ACTION_VIEW);
      newIntent.setDataAndType(path, "application/pdf");
      newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  
      try{
          startActivity(newIntent);
      }catch(ActivityNotFoundException ex){
          ex.printStackTrace();
      }
  
      pdfAdapter.close();
  }
  </code></pre>
  
  <p>And my Adapter class which handles the db operations:</p>
  
  <pre><code>public class PDFDbAdapter {
  
  // -------------------------------------------------------------------
  // Constants
  // -------------------------------------------------------------------
  
  public static final String DATABASE_TABLE = "pdf_documents";
  public static final String KEY_ROW_ID = "_id";
  public static final String KEY_FILE_NAME = "file_name";
  public static final String KEY_FILE_BLOB = "file_blob";
  
  
  static final String CREATE_TABLE_PDFDOCS = ("CREATE TABLE " + DATABASE_TABLE + "(" 
                                                  + KEY_ROW_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                                                  + KEY_FILE_NAME + " VARCHAR(100),"
                                                  + KEY_FILE_BLOB + " BLOB);");
  
  // -------------------------------------------------------------------
  // Member Variables
  // -------------------------------------------------------------------
  private Context mContext;
  private DBCache mDbHelper;
  private SQLiteDatabase mDataBase;
  
  // -------------------------------------------------------------------
  // Constructor
  
  // Constructor, passes in the current context of the application
  public PDFDbAdapter(Context context){
      this.mContext = context;
  }
  
  // -------------------------------------------------------------------
  // Class Methods
  
  // Open the Database for reading
  public PDFDbAdapter open() throws SQLiteException{
      this.mDbHelper = new DBCache(mContext);
      this.mDataBase = mDbHelper.getWritableDatabase();
  
      return this;
  }
  
  // Create the new PDF File save in the database
  public long createPDFFile(String fileName, byte [] fileBlob){
      ContentValues values = new ContentValues();
      values.put(KEY_FILE_NAME, fileName);
      values.put(KEY_FILE_BLOB, fileBlob);
  
      return this.mDataBase.insert(DATABASE_TABLE, null, values);
  }
  
  // Read the current file in the database
  public Cursor fetchPDFFile(long rowId){
  
      Cursor currentCursor = mDataBase.query(true, DATABASE_TABLE, new String [] {KEY_ROW_ID, KEY_FILE_NAME, KEY_FILE_BLOB},
              KEY_ROW_ID +"="+rowId, null, null, null, null, null);
  
      if(currentCursor != null){
          currentCursor.moveToFirst();
      }
  
      return currentCursor;
  
  }
  
  // Read all available PDF's from the database
  public Cursor fetchAllPDFFiles(){
      return this.mDataBase.query( DATABASE_TABLE, new String [] {KEY_ROW_ID, KEY_FILE_NAME, 
              KEY_FILE_BLOB}, null, null, null ,null, null);
  
  }
  
  // Delete the current PDF file from the database
  public boolean deletePDFFile(long rowId){
      return this.mDataBase.delete(DATABASE_TABLE, KEY_ROW_ID +"=" + rowId, null) &gt; 0;
  }
  
  // Close the Database connection
  public void close(){
      if(mDbHelper != null){
          mDbHelper.close();
      }
  }
  
  }
  </code></pre>