How to check which StorageVolume we have access to, and which we don't?
Here is an alternate way to get what you want. It is a work-around like you have posted without using reflection or file paths.
On an emulator, I see the following items for which I have permitted access.
persistedUriPermissions array contents (value of URI only):
0 uri = content://com.android.externalstorage.documents/tree/primary%3A
1 uri = content://com.android.externalstorage.documents/tree/1D03-2E0E%3ADownload
2 uri = content://com.android.externalstorage.documents/tree/1D03-2E0E%3A
3 uri = content://com.android.externalstorage.documents/tree/primary%3ADCIM
4 uri = content://com.android.externalstorage.documents/tree/primary%3AAlarms
"%3A" is a colon (":"). So, it appears that the URI is constructed as follows for a volume where "<volume>" is the UUID of the volume.
uri = "content://com.android.externalstorage.documents/tree/<volume>:"
If the uri is a directory directly under a volume, then the structure is:
uri = "content://com.android.externalstorage.documents/tree/<volume>:<directory>"
For directories deeper in the structure, the format is:
uri = "content://com.android.externalstorage.documents/tree/<volume>:<directory>/<directory>/<directory>..."
So, it is just a matter of extracting volumes from URIs in these formats. The volume extracted can be used as a key for StorageManager.storageVolumes
. The following code does just this.
It seems to me that there should be an easier way to go about this. There must be a missing linkage in the API between storage volumes and URIs. I can't say that this technique covers all circumstances.
I also question the UUID that is returned by storageVolume.uuid
which seems to be a 32-bit value. I thought that UUIDs are 128 bits in length. Is this an alternative format for a UUID or somehow derived from the UUID? Interesting, and it is all about to drop! :(
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
var storageVolumes = storageManager.storageVolumes
val storageVolumePathsWeHaveAccessTo = HashSet<String>()
checkAccessButton.setOnClickListener {
checkAccessToStorageVolumes()
}
requestAccessButton.setOnClickListener {
storageVolumes = storageManager.storageVolumes
val primaryVolume = storageManager.primaryStorageVolume
val intent = primaryVolume.createOpenDocumentTreeIntent()
startActivityForResult(intent, 1)
}
}
private fun checkAccessToStorageVolumes() {
val storageVolumePathsWeHaveAccessTo = HashSet<String>()
val persistedUriPermissions = contentResolver.persistedUriPermissions
persistedUriPermissions.forEach {
storageVolumePathsWeHaveAccessTo.add(it.uri.toString())
}
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
for (storageVolume in storageVolumes) {
val uuid = if (storageVolume.isPrimary) {
// Primary storage doesn't get a UUID here.
"primary"
} else {
storageVolume.uuid
}
val volumeUri = uuid?.let { buildVolumeUriFromUuid(it) }
when {
uuid == null ->
Log.d("AppLog", "UUID is null for ${storageVolume.getDescription(this)}!")
storageVolumePathsWeHaveAccessTo.contains(volumeUri) ->
Log.d("AppLog", "Have access to $uuid")
else -> Log.d("AppLog", "Don't have access to $uuid")
}
}
}
private fun buildVolumeUriFromUuid(uuid: String): String {
return DocumentsContract.buildTreeDocumentUri(
"com.android.externalstorage.documents",
"$uuid:"
).toString()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Log.d("AppLog", "resultCode:$resultCode")
val uri = data?.data ?: return
val takeFlags =
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.takePersistableUriPermission(uri, takeFlags)
Log.d("AppLog", "granted uri: ${uri.path}")
}
}
How to find the amount of free storage (disk space) left on Android?
Try StatFs.getAvailableBlocks. You'll need to convert the block count to KB with getBlockSize.
Android get free size of internal/external memory
This is the way I did it :
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable;
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
bytesAvailable = stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
}
else {
bytesAvailable = (long)stat.getBlockSize() * (long)stat.getAvailableBlocks();
}
long megAvailable = bytesAvailable / (1024 * 1024);
Log.e("","Available MB : "+megAvailable);
Oracle: is it possible to calculate actual storage size used by the data in a table?
You probably want something based on the dbms_space.space_usage
procedure. This will tell you how many blocks are 0-25% full, 25-50% full, 50-75% full, and 75-100% full, and completely full. I use the midpoint estimate in the script below-- it may make more sense for you to use an optimistic or a pessimistic estimate if you are trying to determine how much free space you are going to create by removing a lot of data. You'd also need to run the same procedure for any indexes, materialized views, etc. that would be impacted by removing data from the table.
drop table foo;
/
create table foo (
col1 number
);
insert into foo
select level
from dual
connect by level <= 10000;
declare
l_unformatted_blocks integer;
l_unformatted_bytes integer;
l_fs1_blocks integer;
l_fs1_bytes integer;
l_fs2_blocks integer;
l_fs2_bytes integer;
l_fs3_blocks integer;
l_fs3_bytes integer;
l_fs4_blocks integer;
l_fs4_bytes integer;
l_full_blocks integer;
l_full_bytes integer;
l_partition_name varchar2(30) := null;
l_segment_size integer;
begin
select sum(bytes)
into l_segment_size
from user_segments
where segment_name = 'FOO';
dbms_space.space_usage( user, 'FOO', 'TABLE',
l_unformatted_blocks, l_unformatted_bytes,
l_fs1_blocks, l_fs1_bytes,
l_fs2_blocks, l_fs2_bytes,
l_fs3_blocks, l_fs3_bytes,
l_fs4_blocks, l_fs4_bytes,
l_full_blocks, l_full_bytes,
l_partition_name );
dbms_output.put_line( 'Segment size is ' || l_segment_size ||
' of which roughly ' ||
to_char(
l_full_bytes +
l_fs4_bytes * 0.125 +
l_fs3_bytes * 0.375 +
l_fs2_bytes * 0.625 +
l_fs1_bytes * 0.875
) ||
' bytes used ' ||
to_char(
8 * 1024 *
l_full_blocks +
l_fs4_blocks * 0.125 +
l_fs3_blocks * 0.375 +
l_fs2_blocks * 0.625 +
l_fs1_blocks * 0.875
) ||
' if we use blocks.'
);
end;
/
Best way to determine the amount of space available for storing app files with Xamarin forms?
1.) Do these lines of code above actually return the amount of bytes that can be stored in a specific directory? Or do they return the amount of bytes that can be stored on the whole device?
Obviously it is specific directory
,because in the code it needs specific folder path as parameter .
You can try to set directoryPath asSystem.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)
and
System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
to see the difference.
2.) For Android I am not too sure what the difference between the two ways of doing this are I am hoping for an explanation of the difference between the both of then and which is a better to use?
I can't tell the difference or which is better, because based on my test the result comes the same , and for details you can refer to here , it's maybe helpful .
Related Topics
How to Change the Background Color Around a Dialogfragment
Display Data After Every 10 Seconds in Android
Xiaomi Does Not Receive Notification When Application Is Not Running
Opening Webview Not in New Browser
Failed to Connect to Camera Service
Write_Secure_Settings Permission Error Even When Added in Manifest
Why Isn't My App on the List of Apps to Open Txt File
Setpluginsenabled Not Exist for Webview
How to Insert Image in a SQLite Database
How to Use Data-Binding with Fragment
How to Simulate Accelerometer in Android Emulator
Render Error in Android Studio 3.0 Layout Editor
Exif Orientation Tag Value Always 0 for Image Taken with Portrait Camera App Android
Get Temperature of Battery on Android
How to Add Shadow to the Fab Provided with the Android Support Design Library
Android: Backspace in Webview/Baseinputconnection
How to Shutdown an Android Mobile Programmatically
Execution Failed for Task App:Transformclasseswithdesugarfordebug Error on Android Studio 3.0 Beta 2