How to Get Free and Total Size of Each Storagevolume

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 as
System.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



Leave a reply



Submit