I have a test class that extends ProviderTestCase2<>.
I would like to populate this test class database with data from some .db files.
Is there some particular method to push some .db file into the Mock Context of a ProviderTestCase2?
Otherwise which way is the easier to populate the database from the .db file?!
Thank you very much!!
How about copying in a pre-existing .db file from the SD Card or something similar? This is a quick piece of code that will accomplish this for you:
private void importDBFile(File importDB) {
String dataDir = Environment.getDataDirectory().getPath();
String packageName = getPackageName();
File importDir = new File(dataDir + "/data/" + packageName + "/databases/");
if (!importDir.exists()) {
Toast.makeText(this, "There was a problem importing the Database", Toast.LENGTH_SHORT).show();
return;
}
File importFile = new File(importDir.getPath() + "/" + importDB.getName());
try {
importFile.createNewFile();
copyDB(importDB, importFile);
Toast.makeText(this, "Import Successful", Toast.LENGTH_SHORT).show();
} catch (IOException ex) {
Toast.makeText(this, "There was a problem importing the Database", Toast.LENGTH_SHORT).show();
}
}
private void copyDB(File from, File to) throws IOException {
FileChannel inChannel = new FileInputStream(from).getChannel();
FileChannel outChannel = new FileOutputStream(to).getChannel();
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} finally {
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
Hopefully this will work for your scenario
Related
I'm working on an app where I'm downloading a PDF file, saving it to internal storage and then opening that file in other app using FileProvider.
Note: It may be a duplicate question, I've gone through most of the questions on StackOverflow, but still didn't find the solution.
The file is getting downloaded fine but when I'm opening it, it is empty.
The downlaoded file is 30 kb and it has 5 pages but all are empty.
Initially, I thought it is empty because the other app doesn't have permission to open the file, but I did another thing to check whether it is a permission issue. I've saved the file to external storage, still, it was empty. So, it means it is not a permission issue.
Please Note:
Along with pdf file, there is some .xls file as well and when I'm opening those in excel android app, it says cannot open the file. This indicates, that there is some issue while writing the byte stream.
Retrofit Interface.java
#GET(ApiConstants.END_POINT_DOWNLOAD_DOCUMENT)
#Streaming
Call<ResponseBody> downloadDocument(#Query("bucket") String bucket, #Query("filename") String fileName);
Code to Download the file: Here I'm checking if a file is already there, then return the file, otherwise download the file.
public LiveData<Resource<File>> openOrDownloadFile(String bucket, String fileName) {
MutableLiveData<Resource<File>> documentLiveData = new MutableLiveData<>();
documentLiveData.postValue(Resource.loading(null));
Context context = MyApp.getInstance();
final File file = new File(context.getFilesDir(), fileName);
if (file.exists()) {
documentLiveData.postValue(Resource.success(file));
} else {
Call<ResponseBody> call = apiService.downloadDocument(bucket, fileName);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
appExecutors.diskIO().execute(new Runnable() {
#Override
public void run() {
try {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
inputStream = response.body().byteStream();
outputStream = new FileOutputStream(file);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
}
documentLiveData.postValue(Resource.success(file));
outputStream.flush();
} catch (IOException e) {
documentLiveData.postValue(Resource.error("Error: Unable to save file/n"+e.getLocalizedMessage(), null));
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
Log.e(AppConstants.TAG, e.getMessage(), e);
documentLiveData.postValue(Resource.error("Error: Unable to save file/n"+e.getLocalizedMessage(), null));
}
}
});
} else {
documentLiveData.postValue(Resource.error("Unable to download file", null));
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
documentLiveData.postValue(Resource.error(t.getLocalizedMessage(), null));
}
});
}
return documentLiveData;
}
Fragment Code
private void onItemClickListener(Document document) {
mDocumentsViewModel.openORDownloadFile(document.getType(), document.getName()).observe(this, new Observer<Resource<File>>() {
#Override
public void onChanged(#Nullable Resource<File> fileResource) {
binding.setResource(fileResource);
if (fileResource.status == Status.SUCCESS) {
openFile(fileResource.data);
}
}
});
}
void openFile(File file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID, file);
intent.setDataAndType(uri, mDocumentsViewModel.getMimeType(file.getAbsolutePath()));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
PackageManager pm = getActivity().getPackageManager();
if (intent.resolveActivity(pm) != null) {
startActivity(intent);
} else {
Toast.makeText(getActivity(), "This file cannot be opened on this device. Please download some compatible app from play store", Toast.LENGTH_SHORT).show();
}
}
Following are the versions :
ext.retrofit_version = "2.4.0"
ext.okhttp_version = "3.8.0"
I'm struggling with this issue, it'll be a great help if you can point out the issue. Thank you.
Update: The problem was with the backend APIs. My code was correct. Once they've fixed the problem at there side, it started working at my side without any changes.
I am using the below code to create a folder in pictures folder and toasting the path.
but folder is not created i have mentioned write to external storage in android manifest.
java.io.File file = new java.io.File (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"College");
if(!file.exists())
{
if(file.mkdir())
{
String f =file.getAbsolutePath();
Toast.makeText(getApplicationContext(),f,Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getApplicationContext(),"File Not Created",Toast.LENGTH_LONG).show();
}
}
please help me with the problem
This did it for me:
import java.io.File;
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "/College");
try
{
if (!file.exists()) {
file.mkdir();
Toast.makeText(this, "Folder created at " + file.toString(), Toast.LENGTH_LONG).show();
}
} catch (Exception ex) {
ex.printStackTrace();
}
I used this code and it worked
File file;
String CAMERA_DIR = "/dcim/";
// Check that the SDCard is mounted
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
// Get the absolute path
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "College");
}
else {
file = new File( Environment.getExternalStorageDirectory() + CAMERA_DIR + "College");
}
// Create the storage directory if it does not exist
if (! file.exists()) {
if (! file.mkdirs()) {
Toast.makeText(getApplicationContext(),"File Not Created",Toast.LENGTH_LONG).show();
return;
}
}
String f =file.getAbsolutePath();
Toast.makeText(getApplicationContext(),f,Toast.LENGTH_LONG).show();
}
else {
throw new IOException();
}
}
i m trying to create directory in sd card through this card.but it is not worked.i put write external storage permission in manifest though it is not working.need urgent help.i had put this code in try catch.but it doesn't enter in catch block.here is my code..
try
{
File songDirectory = new File(Environment.getExternalStorageDirectory().toString()+"/iAC2013");
if(!songDirectory.exists())
{
songDirectory.mkdirs();
Toast.makeText(getApplicationContext(),"Directory created", Toast.LENGTH_LONG).show();
// ShowlistView();
}
else
{
//ShowlistView();
Toast.makeText(getApplicationContext(),"Directory AlreadyExists", Toast.LENGTH_LONG).show();
}
}
catch(Exception e)
{
Log.e("","Error While creating file is:::::"+e+"");
}
Try out the Below Code :
File sdDir = Environment.getExternalStorageDirectory();
File wwwjdicDir = new File(sdDir.getAbsolutePath() + "/your_folder_name");
if (!wwwjdicDir.exists()) {
wwwjdicDir.mkdir();
}
if (!wwwjdicDir.canWrite()) {
return;
}
try like
File dir = new File(DEFAULT_STORAGE_LOCATION);
// test dir for existence and writeability
if (!dir.exists()) {
try {
dir.mkdirs();
} catch (Exception e) {
return null;
}
} else {
if (!dir.canWrite()) {
return null;
// do your work here
}
}
If this is your code
File songDirectory = new `File(Environment.getExternalStorageDirectory().toString()+"/iAC2013");
you need to chagne it to this
File songDirectory = new File(Environment.getExternalStorageDirectory().toString()+"/iAC2013");
The only way to get and visualize the data table of my database inside external devices is by atribution of privilege of superuser privilege in external device? Don't exist another way that allow visualize the data tables as in emulator?
I make this question because this way of superuser privilege not inspire me security.
Thanks for your attention (PS: Sorry by mistakes, but english is not my mother language :) )
You can add functionality to export the database file from the internal read-only app storage to the SD-Card by simply letting your app copy the file.
Then use whatever ways you have to get it from there. Works on any device and no root required.
private void exportDb() {
File database = getDatabasePath("myDb.db");
File sdCard = new File(Environment.getExternalStorageDirectory(), "myDb.db");
if (copy(database, sdCard)) {
Toast.makeText(this, "Get db from " + sdCard.getPath(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Copying the db failed", Toast.LENGTH_LONG).show();
}
}
private static boolean copy(File src, File target) {
// try creating necessary directories
target.mkdirs();
boolean success = false;
FileOutputStream out = null;
FileInputStream in = null;
try {
out = new FileOutputStream(target);
in = new FileInputStream(src);
byte[] buffer = new byte[8 * 1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
success = true;
} catch (FileNotFoundException e) {
// maybe log
} catch (IOException e) {
// maybe log
} finally {
close(in);
close(out);
}
if (!success) {
// try to delete failed attempts
target.delete();
}
return success;
}
private static void close(final Closeable closeMe) {
if (closeMe != null)
try {
closeMe.close();
} catch (IOException ignored) {
// ignored
}
}
I'm currently doing some debugging and I was wondering is it possible to display the contents of the phones SQLite database via the SDK? I know it's possible to do this via queries phone side. But I was just curious could you do it via the SDK?
Export the database to the sdcard file, and each time you have to copy over to your computer, and open by some SQLite Manager tool, I use Firefox's plugin for this. There simple I don't have to reopen the database again and again, just hit the refresh button and the tables will get updated.
You can use Eclipse's File Manager to get a file from the device, from sdcard while it's in usb mode. You have this option only as you cannot get the device into Eclipse and mount the SD Card in the same time. You have to use Eclipse.
Here is the code to export the database to SDCard
/*
* Task to backup the database to the SDCard
*/
public static class ExportDatabaseFileTask extends AsyncTask<String, Void, Boolean> {
private Context ctx;
/**
*
*/
public ExportDatabaseFileTask(Context ctx) {
super();
this.ctx=ctx;
}
// automatically done on worker thread (separate from UI thread)
protected Boolean doInBackground(final String... args) {
File dbFile =
new File(Environment.getDataDirectory() + "/data/[com.your.pkg]/databases/[pkg]");
File exportDir = new File(Environment.getExternalStorageDirectory(), "");
if (!exportDir.exists()) {
exportDir.mkdirs();
}
File file = new File(exportDir, dbFile.getName());
try {
file.createNewFile();
this.copyFile(dbFile, file);
return true;
} catch (IOException e) {
Log.e("birthdroid", e.getMessage(), e);
return false;
}
}
// can use UI thread here
protected void onPostExecute(final Boolean success) {
if (success) {
Toast.makeText(ctx, "Export successful!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ctx, "Export failed", Toast.LENGTH_SHORT).show();
}
}
void copyFile(File src, File dst) throws IOException {
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} finally {
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
}
On a cursor you always can call:
DatabaseUtils.dumpCursorToString(cur);
to get a raw String representation of the cursor