Volume on SD cards warning
This commit is contained in:
parent
29b12898a4
commit
f44a702647
@ -20,6 +20,7 @@ import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
|
|||||||
import sushi.hardcore.droidfs.fingerprint_stuff.FingerprintPasswordHashSaver
|
import sushi.hardcore.droidfs.fingerprint_stuff.FingerprintPasswordHashSaver
|
||||||
import sushi.hardcore.droidfs.util.*
|
import sushi.hardcore.droidfs.util.*
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ChangePasswordActivity : BaseActivity() {
|
class ChangePasswordActivity : BaseActivity() {
|
||||||
@ -80,9 +81,25 @@ class ChangePasswordActivity : BaseActivity() {
|
|||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
if (requestCode == PICK_DIRECTORY_REQUEST_CODE) {
|
if (requestCode == PICK_DIRECTORY_REQUEST_CODE) {
|
||||||
if (data != null) {
|
if (data?.data != null) {
|
||||||
|
if (PathUtils.isTreeUriOnPrimaryStorage(data.data)){
|
||||||
val path = PathUtils.getFullPathFromTreeUri(data.data, this)
|
val path = PathUtils.getFullPathFromTreeUri(data.data, this)
|
||||||
|
if (path != null){
|
||||||
edit_volume_path.setText(path)
|
edit_volume_path.setText(path)
|
||||||
|
} else {
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.error)
|
||||||
|
.setMessage(R.string.path_from_uri_null_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.warning)
|
||||||
|
.setMessage(R.string.change_pwd_on_sdcard_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,38 +109,53 @@ class ChangePasswordActivity : BaseActivity() {
|
|||||||
rootCipherDir = edit_volume_path.text.toString()
|
rootCipherDir = edit_volume_path.text.toString()
|
||||||
if (rootCipherDir.isEmpty()) {
|
if (rootCipherDir.isEmpty()) {
|
||||||
Toast.makeText(this, R.string.enter_volume_path, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.enter_volume_path, Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
if (!File(rootCipherDir).canWrite()){
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.warning)
|
||||||
|
.setMessage(R.string.change_pwd_cant_write_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
} else {
|
} else {
|
||||||
changePassword(null)
|
changePassword(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun changePassword(givenHash: ByteArray?){
|
private fun changePassword(givenHash: ByteArray?){
|
||||||
object : LoadingTask(this, R.string.loading_msg_change_password){
|
|
||||||
override fun doTask(activity: AppCompatActivity) {
|
|
||||||
val newPassword = edit_new_password.text.toString().toCharArray()
|
val newPassword = edit_new_password.text.toString().toCharArray()
|
||||||
val newPasswordConfirm = edit_new_password_confirm.text.toString().toCharArray()
|
val newPasswordConfirm = edit_new_password_confirm.text.toString().toCharArray()
|
||||||
if (!newPassword.contentEquals(newPasswordConfirm)) {
|
if (!newPassword.contentEquals(newPasswordConfirm)) {
|
||||||
stopTaskWithToast(R.string.passwords_mismatch)
|
Toast.makeText(this, R.string.passwords_mismatch, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
|
object : LoadingTask(this, R.string.loading_msg_change_password) {
|
||||||
|
override fun doTask(activity: AppCompatActivity) {
|
||||||
val oldPassword = edit_old_password.text.toString().toCharArray()
|
val oldPassword = edit_old_password.text.toString().toCharArray()
|
||||||
var returnedHash: ByteArray? = null
|
var returnedHash: ByteArray? = null
|
||||||
if (usf_fingerprint && checkbox_save_password.isChecked){
|
if (usf_fingerprint && checkbox_save_password.isChecked) {
|
||||||
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
||||||
}
|
}
|
||||||
var changePasswordImmediately = true
|
var changePasswordImmediately = true
|
||||||
if (givenHash == null){
|
if (givenHash == null) {
|
||||||
val cipherText = sharedPrefs.getString(rootCipherDir, null)
|
val cipherText = sharedPrefs.getString(rootCipherDir, null)
|
||||||
if (cipherText != null){ //password hash saved
|
if (cipherText != null) { //password hash saved
|
||||||
stopTask {
|
stopTask {
|
||||||
fingerprintPasswordHashSaver.decrypt(cipherText, rootCipherDir, ::changePassword)
|
fingerprintPasswordHashSaver.decrypt(cipherText, rootCipherDir, ::changePassword)
|
||||||
}
|
}
|
||||||
changePasswordImmediately = false
|
changePasswordImmediately = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changePasswordImmediately){
|
if (changePasswordImmediately) {
|
||||||
if (GocryptfsVolume.changePassword(rootCipherDir, oldPassword, givenHash, newPassword, returnedHash)) {
|
if (GocryptfsVolume.changePassword(
|
||||||
|
rootCipherDir,
|
||||||
|
oldPassword,
|
||||||
|
givenHash,
|
||||||
|
newPassword,
|
||||||
|
returnedHash
|
||||||
|
)
|
||||||
|
) {
|
||||||
val editor = sharedPrefs.edit()
|
val editor = sharedPrefs.edit()
|
||||||
if (sharedPrefs.getString(rootCipherDir, null) != null){
|
if (sharedPrefs.getString(rootCipherDir, null) != null) {
|
||||||
editor.remove(rootCipherDir)
|
editor.remove(rootCipherDir)
|
||||||
editor.apply()
|
editor.apply()
|
||||||
}
|
}
|
||||||
@ -133,17 +165,20 @@ class ChangePasswordActivity : BaseActivity() {
|
|||||||
val newSavedVolumesPaths = oldSavedVolumesPaths.toMutableList()
|
val newSavedVolumesPaths = oldSavedVolumesPaths.toMutableList()
|
||||||
if (!oldSavedVolumesPaths.contains(rootCipherDir)) {
|
if (!oldSavedVolumesPaths.contains(rootCipherDir)) {
|
||||||
newSavedVolumesPaths.add(rootCipherDir)
|
newSavedVolumesPaths.add(rootCipherDir)
|
||||||
editor.putStringSet(ConstValues.saved_volumes_key, newSavedVolumesPaths.toSet())
|
editor.putStringSet(
|
||||||
|
ConstValues.saved_volumes_key,
|
||||||
|
newSavedVolumesPaths.toSet()
|
||||||
|
)
|
||||||
editor.apply()
|
editor.apply()
|
||||||
}
|
}
|
||||||
if (checkbox_save_password.isChecked && returnedHash != null){
|
if (checkbox_save_password.isChecked && returnedHash != null) {
|
||||||
fingerprintPasswordHashSaver.encryptAndSave(returnedHash, rootCipherDir){ _ ->
|
fingerprintPasswordHashSaver.encryptAndSave(returnedHash, rootCipherDir) { _ ->
|
||||||
stopTask { onPasswordChanged() }
|
stopTask { onPasswordChanged() }
|
||||||
}
|
}
|
||||||
continueImmediately = false
|
continueImmediately = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (continueImmediately){
|
if (continueImmediately) {
|
||||||
stopTask { onPasswordChanged() }
|
stopTask { onPasswordChanged() }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -158,11 +193,13 @@ class ChangePasswordActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
Arrays.fill(oldPassword, 0.toChar())
|
Arrays.fill(oldPassword, 0.toChar())
|
||||||
}
|
}
|
||||||
|
override fun doFinally(activity: AppCompatActivity) {
|
||||||
Arrays.fill(newPassword, 0.toChar())
|
Arrays.fill(newPassword, 0.toChar())
|
||||||
Arrays.fill(newPasswordConfirm, 0.toChar())
|
Arrays.fill(newPasswordConfirm, 0.toChar())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun onPasswordChanged(){
|
private fun onPasswordChanged(){
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
|
@ -5,12 +5,9 @@ import android.content.Intent
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import kotlinx.android.synthetic.main.activity_create.*
|
import kotlinx.android.synthetic.main.activity_create.*
|
||||||
import kotlinx.android.synthetic.main.activity_create.checkbox_remember_path
|
|
||||||
import kotlinx.android.synthetic.main.activity_create.checkbox_save_password
|
|
||||||
import kotlinx.android.synthetic.main.activity_create.edit_password
|
|
||||||
import kotlinx.android.synthetic.main.activity_create.edit_volume_path
|
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
import kotlinx.android.synthetic.main.toolbar.*
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
||||||
import sushi.hardcore.droidfs.fingerprint_stuff.FingerprintPasswordHashSaver
|
import sushi.hardcore.droidfs.fingerprint_stuff.FingerprintPasswordHashSaver
|
||||||
@ -19,6 +16,7 @@ import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class CreateActivity : BaseActivity() {
|
class CreateActivity : BaseActivity() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val PICK_DIRECTORY_REQUEST_CODE = 1
|
private const val PICK_DIRECTORY_REQUEST_CODE = 1
|
||||||
@ -53,36 +51,71 @@ class CreateActivity : BaseActivity() {
|
|||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
if (requestCode == PICK_DIRECTORY_REQUEST_CODE) {
|
if (requestCode == PICK_DIRECTORY_REQUEST_CODE) {
|
||||||
if (data != null) {
|
if (data?.data != null) {
|
||||||
|
if (PathUtils.isTreeUriOnPrimaryStorage(data.data)){
|
||||||
val path = PathUtils.getFullPathFromTreeUri(data.data, this)
|
val path = PathUtils.getFullPathFromTreeUri(data.data, this)
|
||||||
|
if (path != null){
|
||||||
edit_volume_path.setText(path)
|
edit_volume_path.setText(path)
|
||||||
|
} else {
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.error)
|
||||||
|
.setMessage(R.string.path_from_uri_null_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.warning)
|
||||||
|
.setMessage(R.string.create_on_sdcard_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onClickCreate(view: View?) {
|
fun onClickCreate(view: View?) {
|
||||||
object: LoadingTask(this, R.string.loading_msg_create){
|
rootCipherDir = edit_volume_path.text.toString()
|
||||||
override fun doTask(activity: AppCompatActivity) {
|
if (rootCipherDir.isEmpty()) {
|
||||||
|
Toast.makeText(this, R.string.enter_volume_path, Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
val password = edit_password.text.toString().toCharArray()
|
val password = edit_password.text.toString().toCharArray()
|
||||||
val passwordConfirm = edit_password_confirm.text.toString().toCharArray()
|
val passwordConfirm = edit_password_confirm.text.toString().toCharArray()
|
||||||
if (!password.contentEquals(passwordConfirm)) {
|
if (!password.contentEquals(passwordConfirm)) {
|
||||||
stopTaskWithToast(R.string.passwords_mismatch)
|
Toast.makeText(this, R.string.passwords_mismatch, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
rootCipherDir = edit_volume_path.text.toString()
|
object: LoadingTask(this, R.string.loading_msg_create){
|
||||||
|
override fun doTask(activity: AppCompatActivity) {
|
||||||
val volumePathFile = File(rootCipherDir)
|
val volumePathFile = File(rootCipherDir)
|
||||||
var goodDirectory = false
|
var goodDirectory = false
|
||||||
if (!volumePathFile.isDirectory) {
|
if (!volumePathFile.isDirectory) {
|
||||||
if (volumePathFile.mkdirs()) {
|
if (volumePathFile.mkdirs()) {
|
||||||
goodDirectory = true
|
goodDirectory = true
|
||||||
} else {
|
} else {
|
||||||
stopTaskWithToast(R.string.error_mkdir)
|
stopTask {
|
||||||
|
ColoredAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.warning)
|
||||||
|
.setMessage(R.string.create_cant_write_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val dirContent = volumePathFile.list()
|
val dirContent = volumePathFile.list()
|
||||||
if (dirContent != null){
|
if (dirContent != null){
|
||||||
if (dirContent.isEmpty()) {
|
if (dirContent.isEmpty()) {
|
||||||
|
if (volumePathFile.canWrite()){
|
||||||
goodDirectory = true
|
goodDirectory = true
|
||||||
|
} else {
|
||||||
|
stopTask {
|
||||||
|
ColoredAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.warning)
|
||||||
|
.setMessage(R.string.create_cant_write_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
stopTaskWithToast(R.string.dir_not_empty)
|
stopTaskWithToast(R.string.dir_not_empty)
|
||||||
}
|
}
|
||||||
@ -136,11 +169,14 @@ class CreateActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
override fun doFinally(activity: AppCompatActivity) {
|
||||||
Arrays.fill(password, 0.toChar())
|
Arrays.fill(password, 0.toChar())
|
||||||
Arrays.fill(passwordConfirm, 0.toChar())
|
Arrays.fill(passwordConfirm, 0.toChar())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun startExplorer(){
|
private fun startExplorer(){
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
|
@ -7,8 +7,16 @@ import android.os.Bundle
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.AdapterView.OnItemClickListener
|
import android.widget.AdapterView.OnItemClickListener
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import kotlinx.android.synthetic.main.activity_change_password.*
|
||||||
|
import kotlinx.android.synthetic.main.activity_create.*
|
||||||
import kotlinx.android.synthetic.main.activity_open.*
|
import kotlinx.android.synthetic.main.activity_open.*
|
||||||
|
import kotlinx.android.synthetic.main.activity_open.checkbox_remember_path
|
||||||
|
import kotlinx.android.synthetic.main.activity_open.checkbox_save_password
|
||||||
|
import kotlinx.android.synthetic.main.activity_open.edit_password
|
||||||
|
import kotlinx.android.synthetic.main.activity_open.edit_volume_path
|
||||||
|
import kotlinx.android.synthetic.main.activity_open.saved_path_listview
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
import kotlinx.android.synthetic.main.toolbar.*
|
||||||
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
|
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
||||||
@ -82,21 +90,51 @@ class OpenActivity : BaseActivity() {
|
|||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
if (requestCode == PICK_DIRECTORY_REQUEST_CODE) {
|
if (requestCode == PICK_DIRECTORY_REQUEST_CODE) {
|
||||||
if (data != null) {
|
if (data?.data != null) {
|
||||||
|
if (PathUtils.isTreeUriOnPrimaryStorage(data.data)){
|
||||||
val path = PathUtils.getFullPathFromTreeUri(data.data, this)
|
val path = PathUtils.getFullPathFromTreeUri(data.data, this)
|
||||||
|
if (path != null){
|
||||||
edit_volume_path.setText(path)
|
edit_volume_path.setText(path)
|
||||||
|
} else {
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.error)
|
||||||
|
.setMessage(R.string.path_from_uri_null_error_msg)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.warning)
|
||||||
|
.setMessage(R.string.open_on_sdcard_warning)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onClickOpen(view: View?) {
|
fun onClickOpen(view: View?) {
|
||||||
|
rootCipherDir = edit_volume_path.text.toString()
|
||||||
|
if (rootCipherDir.isEmpty()) {
|
||||||
|
Toast.makeText(this, R.string.enter_volume_path, Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
if (!File(rootCipherDir).canWrite()){
|
||||||
|
ColoredAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.warning)
|
||||||
|
.setMessage(R.string.open_cant_write_warning)
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton(R.string.ok) { _, _ -> openVolume() }
|
||||||
|
.show()
|
||||||
|
} else {
|
||||||
|
openVolume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openVolume(){
|
||||||
object : LoadingTask(this, R.string.loading_msg_open){
|
object : LoadingTask(this, R.string.loading_msg_open){
|
||||||
override fun doTask(activity: AppCompatActivity) {
|
override fun doTask(activity: AppCompatActivity) {
|
||||||
rootCipherDir = edit_volume_path.text.toString() //fresh get in case of manual rewrite
|
|
||||||
if (rootCipherDir.isEmpty()) {
|
|
||||||
stopTaskWithToast(R.string.enter_volume_path)
|
|
||||||
} else {
|
|
||||||
val password = edit_password.text.toString().toCharArray()
|
val password = edit_password.text.toString().toCharArray()
|
||||||
var returnedHash: ByteArray? = null
|
var returnedHash: ByteArray? = null
|
||||||
if (usf_fingerprint && checkbox_save_password.isChecked){
|
if (usf_fingerprint && checkbox_save_password.isChecked){
|
||||||
@ -130,7 +168,6 @@ class OpenActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun openUsingPasswordHash(passwordHash: ByteArray){
|
private fun openUsingPasswordHash(passwordHash: ByteArray){
|
||||||
object : LoadingTask(this, R.string.loading_msg_open){
|
object : LoadingTask(this, R.string.loading_msg_open){
|
||||||
|
@ -194,7 +194,9 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
total_size_text.text = getString(R.string.total_size, PathUtils.formatSize(totalSize))
|
total_size_text.text = getString(R.string.total_size, PathUtils.formatSize(totalSize))
|
||||||
|
runOnUiThread {
|
||||||
explorerAdapter.notifyDataSetChanged()
|
explorerAdapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,9 @@ import android.net.Uri;
|
|||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.provider.DocumentsContract;
|
import android.provider.DocumentsContract;
|
||||||
import android.provider.OpenableColumns;
|
import android.provider.OpenableColumns;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -81,24 +83,35 @@ public class PathUtils {
|
|||||||
return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups))+" "+units[digitGroups];
|
return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups))+" "+units[digitGroups];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Boolean isTreeUriOnPrimaryStorage(Uri treeUri){
|
||||||
|
String volumeId = getVolumeIdFromTreeUri(treeUri);
|
||||||
|
if (volumeId != null) {
|
||||||
|
return volumeId.equals(PRIMARY_VOLUME_NAME) || volumeId.equals("home") || volumeId.equals("downloads");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final String PRIMARY_VOLUME_NAME = "primary";
|
private static final String PRIMARY_VOLUME_NAME = "primary";
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getFullPathFromTreeUri(@Nullable final Uri treeUri, Context con) {
|
public static String getFullPathFromTreeUri(@Nullable Uri treeUri, Context context) {
|
||||||
if (treeUri == null) return null;
|
if (treeUri == null) return null;
|
||||||
String volumePath = getVolumePath(getVolumeIdFromTreeUri(treeUri),con);
|
if ("content".equalsIgnoreCase(treeUri.getScheme())) {
|
||||||
if (volumePath == null) return File.separator;
|
String volumePath = getVolumePath(getVolumeIdFromTreeUri(treeUri),context);
|
||||||
|
if (volumePath == null) return null;
|
||||||
if (volumePath.endsWith(File.separator))
|
if (volumePath.endsWith(File.separator))
|
||||||
volumePath = volumePath.substring(0, volumePath.length() - 1);
|
volumePath = volumePath.substring(0, volumePath.length() - 1);
|
||||||
String documentPath = getDocumentPathFromTreeUri(treeUri);
|
String documentPath = getDocumentPathFromTreeUri(treeUri);
|
||||||
if (documentPath.endsWith(File.separator))
|
if (documentPath.endsWith(File.separator))
|
||||||
documentPath = documentPath.substring(0, documentPath.length() - 1);
|
documentPath = documentPath.substring(0, documentPath.length() - 1);
|
||||||
if (documentPath.length() > 0) {
|
if (documentPath.length() > 0) {
|
||||||
if (documentPath.startsWith(File.separator))
|
return path_join(volumePath, documentPath);
|
||||||
return volumePath + documentPath;
|
|
||||||
else
|
|
||||||
return volumePath + File.separator + documentPath;
|
|
||||||
}
|
}
|
||||||
else return volumePath;
|
else return volumePath;
|
||||||
|
} else if ("file".equalsIgnoreCase(treeUri.getScheme())) {
|
||||||
|
return treeUri.getPath();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getVolumePath(final String volumeId, Context context) {
|
private static String getVolumePath(final String volumeId, Context context) {
|
||||||
@ -117,7 +130,6 @@ public class PathUtils {
|
|||||||
Object storageVolumeElement = Array.get(result, i);
|
Object storageVolumeElement = Array.get(result, i);
|
||||||
String uuid = (String) getUuid.invoke(storageVolumeElement);
|
String uuid = (String) getUuid.invoke(storageVolumeElement);
|
||||||
Boolean primary = (Boolean) isPrimary.invoke(storageVolumeElement);
|
Boolean primary = (Boolean) isPrimary.invoke(storageVolumeElement);
|
||||||
|
|
||||||
if (primary && PRIMARY_VOLUME_NAME.equals(volumeId))
|
if (primary && PRIMARY_VOLUME_NAME.equals(volumeId))
|
||||||
return (String) getPath.invoke(storageVolumeElement);
|
return (String) getPath.invoke(storageVolumeElement);
|
||||||
if (uuid != null && uuid.equals(volumeId))
|
if (uuid != null && uuid.equals(volumeId))
|
||||||
|
@ -143,7 +143,7 @@
|
|||||||
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
||||||
android:layout_marginBottom="@dimen/action_activity_button_margin_bottom"
|
android:layout_marginBottom="@dimen/action_activity_button_margin_bottom"
|
||||||
android:onClick="onClickChangePassword"
|
android:onClick="onClickChangePassword"
|
||||||
android:text="@string/change_volume_password"
|
android:text="@string/change_password"
|
||||||
style="@style/button"/>
|
style="@style/button"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -114,7 +114,7 @@
|
|||||||
android:layout_height="@dimen/action_activity_button_height"
|
android:layout_height="@dimen/action_activity_button_height"
|
||||||
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
||||||
android:onClick="onClickCreate"
|
android:onClick="onClickCreate"
|
||||||
android:text="@string/create_volume"
|
android:text="@string/create"
|
||||||
style="@style/button"/>
|
style="@style/button"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
||||||
android:layout_marginBottom="@dimen/action_activity_button_margin_bottom"
|
android:layout_marginBottom="@dimen/action_activity_button_margin_bottom"
|
||||||
android:onClick="onClickOpen"
|
android:onClick="onClickOpen"
|
||||||
android:text="@string/open_volume"
|
android:text="@string/open"
|
||||||
style="@style/button"/>
|
style="@style/button"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">DroidFS</string>
|
<string name="app_name">DroidFS</string>
|
||||||
<string name="open_volume">OPEN A VOLUME</string>
|
<string name="open_volume">Open a volume</string>
|
||||||
<string name="create_volume">CREATE A VOLUME</string>
|
<string name="create_volume">Create a volume</string>
|
||||||
<string name="change_volume_password">CHANGE VOLUME PASSWORD</string>
|
<string name="change_volume_password">Change a volume\'s password</string>
|
||||||
|
<string name="open">Open</string>
|
||||||
|
<string name="create">Create</string>
|
||||||
|
<string name="change_password">Change password</string>
|
||||||
<string name="password">Password:</string>
|
<string name="password">Password:</string>
|
||||||
<string name="password_confirm">Password (confirmation):</string>
|
<string name="password_confirm">Password (confirmation):</string>
|
||||||
<string name="volume_path">Volume Path:</string>
|
<string name="volume_path">Volume Path:</string>
|
||||||
@ -163,4 +166,11 @@
|
|||||||
<string name="choose_filter">Choose filter</string>
|
<string name="choose_filter">Choose filter</string>
|
||||||
<string name="filters_warning">Filters can only be applied to reduced quality images. If you want to take high definition photos, do not apply any filters.</string>
|
<string name="filters_warning">Filters can only be applied to reduced quality images. If you want to take high definition photos, do not apply any filters.</string>
|
||||||
<string name="timer_empty_error_msg">Please enter a numeric value</string>
|
<string name="timer_empty_error_msg">Please enter a numeric value</string>
|
||||||
|
<string name="path_from_uri_null_error_msg">Failed to retrieve the selected path.</string>
|
||||||
|
<string name="create_cant_write_error_msg">DroidFS doesn\'t have write access to this path. Please try another location.</string>
|
||||||
|
<string name="create_on_sdcard_error_msg">DroidFS can\'t write on removable SD cards, please select a path on internal storage.</string>
|
||||||
|
<string name="open_on_sdcard_warning">DroidFS can\'t write on removable SD cards. You will only have read-only access to the volumes therein.</string>
|
||||||
|
<string name="open_cant_write_warning">DroidFS doesn\'t have write access to this path. You will only have read-only access to this volume.</string>
|
||||||
|
<string name="change_pwd_cant_write_error_msg">DroidFS doesn\'t have write access to this path. You can try to move the volume to a writable location.</string>
|
||||||
|
<string name="change_pwd_on_sdcard_error_msg">DroidFS can\'t write on removable SD cards, please move the volume to internal storage.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user