I'm working with Android and I'm trying to use a database I already have. I'd like to put it on the SD card. I have the database file in my project's assets folder. How can I make it on the SD card or external storage of whatever device the app is installed on?
//Step1 : Checked accessiblity on sd card
public boolean doesSDCardAccessible(){
try {
return(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return false;
}
//Step2 : create directory on SD Card
//APP_DIR : your PackageName
public void createAndInitAppDir(){
try {
if(doesSDCardAccessible()){
AppDir = new File(Environment.getExternalStorageDirectory(),APP_DIR+"/");
if(!AppDir.exists()){
AppDir.mkdirs();
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
//Step 3 : Create Database on sdcard
//APP_DIR : your PackageName
//DATABASE_VERSION : give Database Vesrion
//DATABASE_NAME : your Databsename Name
public void initDB()
{
try {
//Using SQLiteHelper Class Created Database
sqliteHelper = new SQLiteHelper(Application.this,AppDir.getAbsolutePath()+"/"+DATABASE_NAME,
null, DATABASE_VERSION);
//OR use following
//Creating db here. or db will be created at runtime whenever writable db is opened.
db = SQLiteDatabase.openOrCreateDatabase(AppDir.getAbsolutePath()+"/"+DATABASE_NAME, null);*/
db= sqliteHelper.getWritableDatabase();
db.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
In reference to this answer, you can find the directory of the SD card in Android 4.0+ by trying both of the following (only one should work per device):
new File("/mnt/external_sd/");
or
new File("/mnt/extSdCard/");
On Android <4.0, you can use
Environment.getExternalStorageDirectory();
You can create your SQLite database there. Additionally, if you can't find it, you can iterate over all directories in /mnt/ (note: the sdcard will always be accessible via /mnt/).
Go throuh this link
OR try following
InputStream myInput;
try {
AssetManager assetManager = getAssets();
myInput = assetManager.open("mydatabase.db");
File directory = new File("/sdcard/some_folder");
if (!directory.exists()) {
directory.mkdirs();
}
OutputStream myOutput = new FileOutputStream(directory
.getPath() + "/DatabaseSample.backup");
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The database is like any other flat file. Just copy it to your SD card.
public boolean backup()
{
File sdcard = Environment.getExternalStorageDirectory();
File data = new File("/data/data/com.mydomain.myappname/databases/");
if (sdcard.canWrite())
{
File input = new File(data, DB_NAME);
File output = new File(sdcard, "android/data/com.mydomain.myappname/databases/");
if(!output.exists())
{
if(output.mkdirs())
{
output = new File(sdcard,
"android/data/com.mydomain.myappname/databases/backup.db");
output.createNewFile();
result = true;
}
else
{
output = new File(sdcard,
"android/data/com.mydomain.myappname/databases/backup.db");
result = true;
}
if(input.exists() && result)
{
FileInputStream source;
FileOutputStream destination;
try
{
source = new FileInputStream(input);
try
{
destination = new FileOutputStream(output);
byte[] buffer = new byte[1024];
int length;
while((length = source.read(buffer)) > 0)
{
destination.write(buffer, 0, length);
}
source.close();
destination.flush();
destination.close();
result = true;
}
catch(Exception e)
{
result = false;
destination = null;
}
}
catch(Exception e)
{
result = false;
source = null;
}
}
else
{
result = false;
}
}
else
{
result = false;
}
}
catch(Exception e)
{
result = false;
}
return result;
}
Related
I am making an app which stores its SQLite Database backup on GDrive. I succeeded in signing in and uploading the file in the drive but failed to restore it. Following is the code.
I use SQLiteDatabase to store the fileID so that when it is required while updating and restoring, it can be used. I am looking for a method which will make use of FileID to restore.
Error occurs at file.getDownloadUrl() and file.getContent().
class DriveClassHelper
{
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private static Drive mDriveService;
private String FileID = null;
private static String filePath = "/data/data/com.example.gdrivebackup/databases/Data.db";
DriveClassHelper(Drive mDriveService)
{
DriveClassHelper.mDriveService = mDriveService;
}
// ---------------------------------- TO BackUp on Drive -------------------------------------------
public Task<String> createFile()
{
return Tasks.call(mExecutor, () ->
{
File fileMetaData = new File();
fileMetaData.setName("Backup");
java.io.File file = new java.io.File(filePath);
String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("application/x-sqlite-3");
FileContent mediaContent = new FileContent(mimeType, file);
File myFile = null;
FileID = getFileIDFromDatabase();
try {
if (FileID != null) {
Log.i("CALLED : ", FileID);
//mDriveService.files().delete().execute();
myFile = mDriveService.files().update(FileID, fileMetaData, mediaContent).execute();
} else {
myFile = mDriveService.files().create(fileMetaData, mediaContent).execute();
MainActivity.demoSQLite.insertData(myFile.getId());
}
} catch (Exception e) {
e.printStackTrace();
}
if (myFile == null) {
throw new IOException("Null Result when requesting file creation");
}
Log.i("ID:", myFile.getId());
return myFile.getId();
}
);
}
// -------------------------------------------------------------------------------------------------
// ---------------------------------- TO get File ID -------------------------------------------
private static String getFileIDFromDatabase()
{
String FileIDFromMethod = null;
Cursor result = MainActivity.demoSQLite.getData();
if (result.getCount() == 0) {
Log.i("CURSOR :", "NO ENTRY");
return null;
} else {
while (result.moveToNext()) {
FileIDFromMethod = result.getString(0);
}
return FileIDFromMethod;
}
}
// -------------------------------------------------------------------------------------------------
// ---------------------------------- TO Restore -------------------------------------------
public static class Restore extends AsyncTask<Void, Void, String>
{
#Override
protected String doInBackground(Void... params) {
String fileId = null;
try
{
fileId = getFileIDFromDatabase();
if (fileId != null)
{
File file = mDriveService.files().get(fileId).execute();
downloadFile(file);
}
else
{
return null;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return fileId;
}
private void downloadFile(File file)
{
InputStream mInput = null;
FileOutputStream mOutput = null;
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) //Error occurs at file.getDownloadUrl()
{
try
{
HttpResponse resp = mDriveService.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
mInput = resp.getContent();
String outFileName = "file://" + Environment.getDataDirectory().getPath() + filePath;
// Log.e("com.example.myapp", "getDatabasePath="+ getDatabasePath(""));
//Log.e("com.example.myapp", "outFileName="+outFileName);
// String outFileName = "../databases/" + "Quickpay.db";
mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
}
catch (IOException e)
{
// An error occurred.
e.printStackTrace();
// return null;
}
finally
{
try
{
//Close the streams
if (mOutput != null)
{
mOutput.close();
}
if (mInput != null)
{
mInput.close();
}
}
catch (IOException e)
{
Log.e("com.example.myapp", "failed to close databases");
}
}
}
else
{
// The file doesn't have any content stored on Drive.
// return null;
Log.e("com.example.myapp", "No content on Drive");
}
}
}
}
The Gradle file is like
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0')
{
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.api-client:google-api-client-android:1.26.0')
{
exclude group: 'org.apache.httpcomponents'
}
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
As far as i know Download URL is only avalibale in Google drive api v2 and not in V3.
Short lived download URL for the file. This field is only populated for files with content stored in Google Drive; it is not populated for Google Docs or shortcut files.
It was not very stable in my opinion as not all file types would return a download url.
Using Google Drive v3 you should download the file using a stream.
String fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().get(fileId)
.executeMediaAndDownloadTo(outputStream);
This should work with the restore. Let me know if it doesnt and i will have a look its been a while since i have tried restore.
Trying to download file by url. For that using java.nio library. The code above work perfect for sdk 24 and above but getting IllegalArgumentException for android sdk 23 and below. I'm getting the error when trying transfer the data. Dear Friends can you please clarify which is the problem.
private void downloadFile(final String itemUrl) {
new Thread(new Runnable() {
#Override
public void run() {
ReadableByteChannel readableByteChannel = null;
FileOutputStream fOutStream = null;
String root =
getApplicationContext().getApplicationInfo().dataDir;
File myDir = new File(root + "/downloadedSongs");
if (!myDir.exists()) {
myDir.mkdirs();
}
File file = new File(myDir, itemTitle);
if (file.exists()) {
file.delete();
}
try {
URL url = new URL(itemUrl);
readableByteChannel =
Channels.newChannel(url.openStream());
fOutStream = new FileOutputStream(file);
fOutStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException e) {
orderAction = Enums.OrderAction.Delete;
} catch (IllegalArgumentException e) {
orderAction = Enums.OrderAction.Delete;
Crashlytics.logException(e);
} finally {
try {
if (fOutStream != null) {
fOutStream.close();
}
if (readableByteChannel != null) {
readableByteChannel.close();
}
} catch (IOException ioExObj) {
orderAction = Enums.OrderAction.Delete;
}
closeNotification(orderAction);
}
}
}).start();
}
Fatal Exception: java.lang.IllegalArgumentException: position=0 count=9223372036854775807 at java.nio.FileChannelImpl.transferFrom(FileChannelImpl.java:370) at am.itsoft.youtomp3.services.DnlService$1.run(DnlService.java:169) at java.lang.Thread.run(Thread.java:818)
The reason is in this argument: Long.MAX_VALUE
Right code:
FileChannel destChannel = fOutStream.getChannel();
long blockSize;
if (Build.VERSION.SDK_INT > 23) {
long blockSize = Long.MAX_VALUE;
} else {
long blockSize = 8*1024;
}
long position = 0;
long loaded;
while ((loaded = destChannel.transferFrom(readableByteChannel, position, blockSize)) > 0) {
position += loaded;
}
I am new for android, Im downloading image from URL and set in listView. Its working some mobile and not creating file/directory in some mobile.
Its throw error like:
java.io.FileNotFoundException: /storage/emulated/0/.tam/veg.png: open failed: ENOENT (No such file or directory)
I don't know why its throw error like this some mobile. I want to create directory all type of mobile. Please anyone help me.
Here my code:
public class ImageStorage {
public static String saveToSdCard(Bitmap bitmap, String filename) {
String stored = null;
File sdcard = Environment.getExternalStorageDirectory();
File folder = new File(sdcard.getAbsoluteFile(), ".tam");//the dot makes this directory hidden to the user
folder.mkdir();
File file = new File(folder.getAbsoluteFile(), filename) ;
if (file.exists())
return stored ;
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
stored = "success";
} catch (Exception e) {
e.printStackTrace();
}
return stored;
}
public static File getImage(String imagename) {
File mediaImage = null;
try {
String root = Environment.getExternalStorageDirectory().getAbsolutePath();
File myDir = new File(root);
if (!myDir.exists())
return null;
mediaImage = new File(myDir.getPath() + "/.tam/"+imagename);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mediaImage;
}
public static File checkifImageExists(String imagename) {
File file = ImageStorage.getImage("/" + imagename);
if (file.exists()) {
return file;
} else {
return null;
}
}
public static String getImageName(String value){
String getName[] = value.split("/");
return getName[4];
}
}
Below path not in all mobile:
/storage/emulated/0/
Thanks in advance!!
Maybe u should check if there's external storage in the mobile before u use this path
public String getDir(Context context) {
String checkPath = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
checkPath = Environment.getExternalStorageDirectory().getPath();
} else {
checkPath = context.getCacheDir().getPath();
}
return checkPath;
}
In reality its just making a copy of a text.txt file. I know how to use file chooser to choose the file but that is as far as my knowledge really goes.
I can do this:
public BasicFile()
{
JFileChooser choose = new JFileChooser(".");
int status = choose.showOpenDialog(null);
try
{
if (status != JFileChooser.APPROVE_OPTION) throw new IOException();
f = choose.getSelectedFile();
if (!f.exists()) throw new FileNotFoundException();
}
catch(FileNotFoundException e)
{
display(1, e.toString(), "File not found ....");
}
catch(IOException e)
{
display(1, e.toString(), "Approve option was not selected");
}
}
Path object is perfect for copying files,
Try this code to copy a file,
Path source = Paths.get("c:\\blabla.txt");
Path target = Paths.get("c:\\blabla2.txt");
try {
Files.copy(source, target);
} catch (IOException e1) {
e1.printStackTrace();
}
If you have to backup a whole folder, you can use this code
public class BackUpFolder {
public void copy(File sourceLocation, File targetLocation) throws IOException {
if (sourceLocation.isDirectory()) {
copyDirectory(sourceLocation, targetLocation);
} else {
copyFile(sourceLocation, targetLocation);
}
}
private void copyDirectory(File source, File target) throws IOException {
if (!target.exists()) {
target.mkdir();
}
for (String f : source.list()) {
copy(new File(source, f), new File(target, f));
}
}
private void copyFile(File source, File target) throws IOException {
try (
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(target)) {
byte[] buf = new byte[1024];
int length;
while ((length = in.read(buf)) > 0) {
out.write(buf, 0, length);
}
}
}
public static void main(String[] args) {
try {
BackUpFolder backUpFolder = new BackUpFolder();
String location = "./src/edu/abc/locationFiles/daofile"; //File path you are getting from file chooser
String target = "./src"; //target place you want to patse
File locFile = new File(location);
File tarFile = new File(target);
backUpFolder.copyDirectory(locFile, tarFile);
} catch (IOException ex) {
Logger.getLogger(BackUpFolder.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Start by taking a look at Basic I/O, which explains the basics of Input/OutputStreams and Readers and Writers, which are used to read/write bytes of data from a source to a destination.
If you're using Java 7 or over, you should also take a look at Copying a File or Directory which is part of newer Files and Paths API, which you can find more information about at File I/O (Featuring NIO.2)
I wish to create a zip program in Java, which zip files and folders let say structure like this -
folder-one/
folder-one/one.txt
folder-one/two.mp3
folder-one/three.jpg
folder-two/
folder-two/four.doc
folder-two/five.rtf
folder-two/folder-three/
folder-two/folder-three/six.txt
I used zip4j open source, I have collected all the files (with absolute path) in one list then given it to zip but it is zipping files only as in my.zip -
one.txt
two.mp3
three.jpg
four.doc
five.rtf
six.txt
How can I preserve same structure on zipping and unzipping as it was on local earlier. Please suggest if any other open source can help me to zip/unzip in same structure files and folders like other windows zip programs.
Code is below --
public class CreateZipWithOutputStreams {
ArrayList filesToAdd = new ArrayList();
public void CreateZipWithOutputStreams(String sAbsolutePath) {
ZipOutputStream outputStream = null;
InputStream inputStream = null;
try {
ArrayList arrLocal = exploredFolder(sAbsolutePath);
outputStream = new ZipOutputStream(new FileOutputStream(new File("c:\\ZipTest\\CreateZipFileWithOutputStreams.zip")));
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
parameters.setEncryptFiles(true);
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
parameters.setPassword("neelam");
for (int i = 0; i < arrLocal.size(); i++) {
File file = (File) arrLocal.get(i);
outputStream.putNextEntry(file, parameters);
if (file.isDirectory()) {
outputStream.closeEntry();
continue;
}
inputStream = new FileInputStream(file);
byte[] readBuff = new byte[4096];
int readLen = -1;
while ((readLen = inputStream.read(readBuff)) != -1) {
outputStream.write(readBuff, 0, readLen);
}
outputStream.closeEntry();
inputStream.close();
}
outputStream.finish();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public ArrayList exploredFolder(String sAbsolutePath) {
File[] sfiles;
File fsSelectedPath = new File(sAbsolutePath);
sfiles = fsSelectedPath.listFiles();
if (sfiles == null) {
return null;
}
for (int j = 0; j < sfiles.length; j++) {
File f = sfiles[j];
if (f.isDirectory() == true) {
exploredFolder(f.getAbsolutePath());
} else {
filesToAdd.add(f);
}
}
return filesToAdd;
}
public static void main(String[] args) {
new CreateZipWithOutputStreams().CreateZipWithOutputStreams("c:\\ZipTest");
}
}
Thanks!
Okay so first the code that is attached is supposed to work the way it is because the exploredFolder(String absolutePath) method is returning the "files to add" which in turn is being used by the CreateZipWithOutputStreams() method to create a single layered(flat) zip file.
What needs to be done is looping over the individual folders and keep adding them to the ZipOutputStream.
Please go through the link below and you will find the code snippet and detailed explaination.
Let me know if that helps!
http://www.java-forums.org/blogs/java-io/973-how-work-zip-files-java.html