I want to copy my local SQLite database out of data/data folder and see its content in some db browser for debug purposes.
Is there any way how to copy it out to root folder?
I used this function 2 months ago, but as I updated my Android Studio from 3.5 to 4.1, it is not working anymore. I cant even see content of databases folder using adb shell. It says Permission denied on both debug and release build version.
fun backupDatabase(){
try {
val sd: File = Environment.getExternalStorageDirectory()
if (sd.canWrite()) {
val currentDBPath = "/data/data/${app.packageName}/databases/$DB_NAME"
val backupDBPath = "backupDB.db"
val currentDB = File(currentDBPath)
val backupDB = File(sd, backupDBPath)
if (currentDB.exists()) {
val src: FileChannel = FileInputStream(currentDB).channel
val dst: FileChannel = FileOutputStream(backupDB).channel
dst.transferFrom(src, 0, src.size())
src.close()
dst.close()
}
}
} catch (e: java.lang.Exception) {
App.log("BackupEx: ${e.localizedMessage}")
}
}
Follow this directory pattern in your Device Explorer on Android Studio.
data -> data -> com.example.appname -> databases.
Then you copy three files:
One with your database name, the other with a "-shm" suffix and another with a "-wal" suffix.
Open all of these files in your SQLite browser.
Related
I am currently working with one of my app updates and I am looking for a way to save some files at the root of shared internal storage.
Don't confuse with the word shared here. I just meant here with the phone's internal/external storage which holds a large amount of data.
Now coming to the main point, I have an app that uses the FFmpeg library for android and it records the live streams and saves it into the phone's storage.
Now here's the problem I don't want to save this file in my app package folder.
e.g: /storage/emulated/0/Android/data/com.app.package/files/...
I want to save this video file in the root of the storage folder where I can create a special folder for my app just like WhatsApp then save all required data in it only.
e.g: /storage/emulated/0/MyApp/...
To be more concise I want my app just like WhatsApp which has a separate folder in internal storage for storing its app-related data.
Now, so far I tried these.
getExternalFilesDir(null)?.absolutePath -> /storage/emulated/0/Android/data/com.app.package/files
getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.absolutePath -> /storage/emulated/0/Android/data/com.app.package/files/Download
externalCacheDir?.absolutePath -> /storage/emulated/0/Android/data/com.app.package/cache
filesDir?.absolutePath -> /data/user/0/com.app.package/files
Environment.getRootDirectory().absolutePath -> /system
Environment.getExternalStorageDirectory().absolutePath -> /storage/emulated/0
Environment.getExternalStoragePublicDirectory("").absolutePath -> /storage/emulated/0
Now these to methods can work for me but they are deprecated getExternalStorageDirectory() & getExternalStoragePublicDirectory()
Just keep in mind my solution is related to the WhatsApp storage folder.
I searched a lot but not so much help as I don't want to go with just a copy-paste and hack solutions. I want to do it in a clean way.
I am trying to open a File Picker via intent for this I have set permission
....
....
and for intent.
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.type = "*/*"
intent.flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
startActivityForResult(Intent.createChooser(intent, "Select .... file"), RC)
Now here on Android 10, a file picker is not opening and this works perfectly if I add the requestLegacyExternalStorage flag in the manifest.
Or
if I set android:maxSdkVersion="29" also worked but here google wants to use Some SAF or Media Store API but I don't get it I just want to pick a file just a simple txt nothing else.
You can save video file to external storage using this:
#RequiresApi(api = Build.VERSION_CODES.Q)
#Throws(FileNotFoundException::class)
fun addToApiAbove29Gallery(
context: Context,
file: File?,
fileName: String?,
destinationPath: String?,
action: () -> Unit
) {
val valuesvideos: ContentValues
valuesvideos = ContentValues()
valuesvideos.put(
MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM
+ File.separator + context.resources.getString(R.string.app_name)
+ File.separator + File(destinationPath).name
)
valuesvideos.put(MediaStore.Video.Media.TITLE, "${fileName}.mp4")
valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, "${fileName}.mp4")
valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
valuesvideos.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000)
valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis())
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1)
val resolver = context.contentResolver
val collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val uriSavedVideo = resolver.insert(collection, valuesvideos)
val pfd = context.contentResolver.openFileDescriptor(uriSavedVideo!!, "w")
val executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
val handler = Handler(Looper.getMainLooper())
executor.execute {
if (pfd != null) {
try {
val out =
FileOutputStream(pfd.fileDescriptor)
val inputStream = FileInputStream(file)
val buf = ByteArray(8192)
var len: Int
while (inputStream.read(buf).also { len = it } > 0) {
out.write(buf, 0, len)
}
out.close()
inputStream.close()
pfd.close()
valuesvideos.clear()
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 0)
try {
setExifFromUri(
context,
uriSavedVideo,
File(destinationPath)
)
} catch (e: IOException) {
e.printStackTrace()
}
} catch (e: Exception) {
e.printStackTrace()
}
handler.post {
context.contentResolver.update(uriSavedVideo, valuesvideos, null, null)
action()
}
}
}
}
Note that this code is only for android 10 and above, because you can easily save the video file to ecternal storage below android 10.
Simple to do in every system but Android, but I have and app that needs to create a csv file in SHARED EXTERNAL Download folder. Shutdown/restart phone/app and the file persist. Then I need to delete the file (persistent URI somewhere?) before I recreate it with new data. (if exists() delete)
I see all kinds of doc pointing to SAF for this process, but can find no examples anywhere of how to perform this simple process of create/delete. If is can do this on API 28 and it work on 29+ that would be great.
Without SAF I've done this:
fun writeCSV() {
val CSV_HEADER = "Last,First\n"
val mockData = "Tester,Joe\n"
val contentValues = ContentValues()
contentValues.put(MediaStore.Downloads.DISPLAY_NAME, "aTest.csv")
contentValues.put(MediaStore.Downloads.MIME_TYPE, "text/csv")
contentValues.put(MediaStore.Downloads.IS_PENDING, true)
val uri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val fileUri = contentResolver.insert(uri, contentValues)
if (fileUri != null) {
try {
val outputStream = contentResolver.openOutputStream(fileUri)
outputStream!!.write(CSV_HEADER.toByteArray())
outputStream!!.write(mockData.toByteArray())
outputStream!!.close()
contentValues.put(MediaStore.Images.Media.IS_PENDING, false)
contentResolver.update(fileUri, contentValues, null, null)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
The problem is when fun is called again I need to delete this file and recreate it with new data because Android creates "aTest (1).csv" instead of overwriting it.
I am trying to save files from the asset folder to the android device's public directory e.g. "Downloads".
Normal file read-write doesn't seem to work.
How to do it?
I have tried this
How to copy files from 'assets' folder to sdcard?
but this didn't work.
fun copy() {
val bufferSize = 1024
val assetManager = context.assets
val assetFiles = assetManager.list("")
assetFiles.forEach {
val inputStream = assetManager.open(it)
val outputStream = FileOutputStream(File(this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), it))
try {
inputStream.copyTo(outputStream, bufferSize)
} finally {
inputStream.close()
outputStream.flush()
outputStream.close()
}
}
}
Make sure you have enabled runtime read/write permissions and after that simply you can use this code to save any file to a directory.
fun saveImageToExternalStorage(image:Bitmap) {
val fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/downloads"
try
{
val dir = File(fullPath)
if (!dir.exists())
{
dir.mkdirs()
}
val fOut:OutputStream = null
val file = File(fullPath, "image.png")
if (file.exists())
file.delete()
file.createNewFile()
fOut = FileOutputStream(file)
// 100 means no compression, the lower you go, the stronger the compression
image.compress(Bitmap.CompressFormat.PNG, 100, fOut)
fOut.flush()
fOut.close()
}
catch (e:Exception) {
Log.e("saveToExternalStorage()", e.message)
}
}
I'm working with SAF (Storage access framework) to write down video files onto SD-CARD.
I've successfully create files, read them and moving.
But i have found the issue with deleting files.
When i delete files using SAF. Files are gone, but space isn't recover.
For example: when 1 have 2GB left out of 10GB.
And i delete file (1GB total) space left is 2GB, not 3GB.
I've used: enter code here
val file: DocumentFile = DocumentFile.fromTreeUri(ctx, treeUri)
file?.delete()
Even:
DocumentsContract.deleteDocument(
activity.contentResolver,
uri
)
and even this:
val path = "/storage/${external?.name}/root.img"
val f = File(path)
if (f.exists()) {
val deleteCmd = "rm -r $path"
val runtime = Runtime.getRuntime()
try {
runtime.exec(deleteCmd)
} catch (e: IOException) {
e.printStackTrace()
}
}
app.applicationContext.deleteFile(f.name)
f.absoluteFile.delete()
f.exists()
I am trying to download an apk file from the web server and store it in the download folder. I am using fuel library
Fuel.download("https://mypath/app.apk").destination {
response, url -> val dir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()) File(dir, "abcd.apk")
}.progress {
readBytes, totalBytes -> val progress = readBytes.toFloat() / totalBytes.toFloat()
Log.d("log",progress.toString())
}.response {
req, res, result -> Log.d("log","download completed ")
Log.d("log",Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/abcd.apk")
}
I am getting bytesArray in response but the file is not saving to download folder. I have write_external_storage on my Manifest file. Please let me know what am I missing?
As you mentioned in comment that you are using targetSdkVersion as 23. Beginning with Android 6.0 (API level 23), if you set targetSdkVersion as 23 in your app you have to implement rumtime permission in your app.
To implement it please refer official documentation here Requesting Permissions at Run Time
fun storeImage(link: String) : String {
val policy: StrictMode.ThreadPolicy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy)
val cw = ContextWrapper(applicationContext)
val directory: File = cw.getDir("imageDir", Context.MODE_PRIVATE)
val pictureFile = File(directory, "backgroundImage.gif")
URL(link).openStream().use { input ->
FileOutputStream(pictureFile).use { output ->
input.copyTo(output)
Log.e("DD GIF", "storeImage: FILE SAVED" )
return "SAVED"
}
}
}
it is working for me.