在我的应用程序中,我希望能够打开与我的 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();
}
}
}