2

在我的应用程序中,我希望能够打开与我的 sqlite 数据库的连接并检索包含 id、名称和 blob 的单行,该 blob 是 pdf 的字节 []。我该怎么做呢?

MainActivity.class 负责所有的工作。它将我的资产文件夹中的 pdf 转换为字节数组,我将其作为 blob 存储在我的 SQLite 数据库中。但是,当我打开文件时,里面没有数据。

谁能帮我解决我在这里做错了什么??!

我的主要活动:

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();

    }

};

}

更新- 这是最终为我工作的活动。这展示了一些可能应该在单独的类中完成的事情。此文件从 assets 文件夹中复制一个 pdf 并将其作为 blob 存储到 db 中,然后单击按钮从 db 中检索 blob 并为任何此类应用程序启动任何 ACTION_VIEW 意图。希望这对某人有所帮助,我花了一点时间才把它弄好!

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();
}

还有我处理数据库操作的适配器类:

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) > 0;
}

// Close the Database connection
public void close(){
    if(mDbHelper != null){
        mDbHelper.close();
    }
}

}
4

1 回答 1

0

看起来我上面的代码中有一个错误。在我用我正在调用的数据库中的字节数组编写新文件之前,flush()当从数据库中的 blob 创建 .pdf 文件时,它会导致一个空指针。如果您有兴趣了解如何将文件从资产复制到数据库作为字节数组并将其存储为 blob,以及如何从数据库中读取字节数组和在创建新文件并从该文件名创建 Uri 后将其传递给新活动。

于 2013-09-20T19:21:46.293 回答