2

私のアプリでは、sqlite データベースへの接続を開き、id、名前、および pdf のバイト [] である blob を含む単一の行を取得できるようにしたいと考えています。どうすればこれを行うことができますか?

MainActivity.class がすべての作業を担当します。私の資産フォルダからPDFをバイト配列に変換し、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();

    }

};

}

更新- これが私のために働いたアクティビティです。これは、おそらく別のクラスで行う必要があるいくつかのことを示しています。このファイルは、アセット フォルダーから 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();
}

そして、db 操作を処理する Adapter クラス:

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 ファイルを作成するときに null ポインターにつながる呼び出しを行っていました。アセットからファイルをバイト配列としてデータベースにコピーして blob として保存する方法、およびデータベースからバイト配列を読み取り、新しいファイルを作成し、そのファイル名から Uri を作成した後、新しいアクティビティに渡します。

于 2013-09-20T19:21:46.293 に答える