Copying preloaded database, adding carriage returns - android

I have an app which comes with a preloaded database.
My temporary copy function is like so
private void copyDatabase() {
AssetManager assetManager = context.getResources().getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(DATABASE_NAME);
out = new FileOutputStream(DATABASE_FILE);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) > 0){
out.write(buffer, 0, read);
}
} catch (IOException e) {
Log.e("error", e.getMessage());
} finally {
if(in != null) {
try {
in.close();
}catch (IOException e) {
Log.e("error", e.getMessage());
}
}
if(out != null) {
try {
out.close();
}catch (IOException e) {
Log.e("error", e.getMessage());
}
}
}
}
However on Android 2.2 I keep getting an error "database disk image malformed". So I went ahead and copied it off the device, onto my computer. And sure enough, it wouldn't open. I did a hex compare on the two files and there are 10 instances where 1 byte is different. Hex 0D has been added 10 times in random spots in the malformed copy.
The copy routine works fine in 3.x+. I also have developed other apps with the same method and don't have an issue.
Any ideas?

Not sure what the issue was, but I created a new sqlite database, imported the data, and that seemed to work.

Related

how to and input files to apk that can be read from C++?

I use JNI to develop my app, and there are two .dat files used as input files in C++ layer. At present, I push these two files into mobile devices through adb before open related app. I think there is a better solution to prevent from pushing two files into mobile devices.
after trying several solutions, I have solved it by combining three solutions, and the code shown below. Before using the code, you need to create a folder called "assets" parallel to "res" folder. Through this way, you can attach the input file you may use to the apk, and when installing the apk first time, it will automatically store the files to specific path in the target device.
public class CameraPreviewActivity extends AppCompatActivity
implements CameraPermissionHelper.CameraPermissionCallback {
SharedPreferences prefs = null;
public static String TAG = "CameraPreviewActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = getSharedPreferences("com.yourcompany.yourapp", MODE_PRIVATE);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onResume() {
super.onResume();
if(prefs.getBoolean("firstrun", true)){
prefs.edit().putBoolean("firstrun", false).commit();
try {
final InputStream input = getResources().getAssets().open("face_model.dat");
try {
File UPLOAD_DIR = new File("/sdcard");
File file = new File(UPLOAD_DIR, "face_model.dat");
OutputStream output = new FileOutputStream(file);
try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace(); // handle exception, define IOException and others
}
} finally {
input.close();
}
}catch (IOException e){
e.printStackTrace();
}
try {
final InputStream input = getResources().getAssets().open("shape_pred.dat");
try {
File UPLOAD_DIR = new File("/sdcard");
File file = new File(UPLOAD_DIR, "shape_pred.dat");
OutputStream output = new FileOutputStream(file);
try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace(); // handle exception, define IOException and others
}
} finally {
input.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}

copy files from assets folder to sd card in android

my code works fine for copying a file from assets folder to sd card. but whenever i try to copy again, it just replaces the old file with the new one instead of renaming it. how do i fix this? thanks
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (files != null) for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(getExternalFilesDir(null), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
}
Overwriting files in case they exist is a normal behavior, Use fileObject.exists() method to check, If the file exists pick another filename, You can use System.currentTimeMillis() method to gain a unique suffix and add it to the file name.
NaN answer is one of the ways to achieve your goal, just changing one line will do the job:
File outFile = new File(getExternalFilesDir(null), filename + System.currentTimeMillis());
Another way is to increase file size ad eternum, but if you are making a tools suit this won't fit your needs.

Getting SQL file from physical phone in device monitor not working?

I have noticed in the android device monitor when I try to access the data folder so I can pull the sql file of my application that is running on my physical phone it does not work but when accessing the application through an emulator it does work. Obviously running the application on the emulator is much more time consuming and I need to present this sqlite data in a timed viva so I can't really be waiting for an emulator.
I was wondering why this is happening as I have allowed debugging and while it does not ask for any more checks on security the device monitor will not open the data folder, when clicked the arrowhead next to the folder disappears then reappears after a few seconds but I can still access every other folder with a drop-down arrow next to it.
If your device is not rooted, you cannot access your app's data file. Try to use following code snippet in any of your Activity to copy the file to sdcard.
public static void copyDataFile() {
File dataDir = getFilesDir().getParentFile();
File target = new File(dataDir, "/* relative path to your sql file */");
File out = new File(Environment.getExternalStorageDirectory(), "/* new file name */");
copyFile(target, out);
}
public static void copyFile(File in, File out) {
if (in.exists()) {
if (!out.exists()) {
try {
out.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileInputStream is = null;
FileOutputStream os = null;
try {
is = new FileInputStream(in);
os = new FileOutputStream(out);
byte[] buf = new byte[4096];
int l = 0;
while ((l = is.read(buf)) > 0) {
os.write(buf, 0, l);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

restore database file from dropbox to local memory

I have implemented a database backup on dropbox, i would like to restore the DB from dropbox to the internal memory (data\data\\database),
i think is forbidden to write directly, is possible to read by stream the file on dropbox, and open the local file, clear the data inside , and flush the stream into the file?
If yes, anyone have a code for example?
I hope to be clear.
this is my code...
private boolean downloadDropboxFile(String dbPath, File localFile) throws IOException{
BufferedInputStream br = null;
BufferedOutputStream bw = null;
try {
if (!localFile.exists()) {
localFile.createNewFile(); //otherwise dropbox client will fail silently
}
byte[] buffer = new byte[4096];
DropboxInputStream fd = mApi.getFileStream (dbPath, null);
br = new BufferedInputStream(fd, buffer.length);
bw = new BufferedOutputStream(new FileOutputStream(localFile));
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
} catch (DropboxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//in finally block:
if (bw != null) {
bw.close();
}
if (br != null) {
br.close();
}
}
return true;
}

Android: action_send put extra_stream from res/drawable folder causes crash

I am creating a game, and trying to allow the user to share their win via text/facebook/etc. I am using the code below to grab an image from my res/drawable folder. I am pretty sure I am doing it right, but my app keeps crashing after I choose the send method (ex. facebook). Any help would be greatly appreciated.
Intent ShareIntent = new Intent(android.content.Intent.ACTION_SEND);
ShareIntent.setType("image/jpeg");
Uri winnerPic = Uri.parse("android.resource://com.poop.pals/" + R.drawable.winnerpic);
ShareIntent.putExtra(Intent.EXTRA_STREAM, winnerPic);
startActivity(ShareIntent);
Android's resources are only accessible to your app via the resource apis, there is no regular file on the filesystem you can open in other ways.
What you can do is to copy the file from the InputStream you can get to a regular file in a place that is accessible to other apps.
// copy R.drawable.winnerpic to /sdcard/winnerpic.png
File file = new File (Environment.getExternalStorageDirectory(), "winnerpic.png");
FileOutputStream output = null;
InputStream input = null;
try {
output = new FileOutputStream(file);
input = context.getResources().openRawResource(R.drawable.winnerpic);
byte[] buffer = new byte[1024];
int copied;
while ((copied = input.read(buffer)) != -1) {
output.write(buffer, 0, copied);
}
} catch (FileNotFoundException e) {
Log.e("OMG", "can't copy", e);
} catch (IOException e) {
Log.e("OMG", "can't copy", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
// ignore
}
}
if (output != null) {
try {
output.close();
} catch (IOException e) {
// ignore
}
}
}

Categories

Resources