Migrate to viewBinding
This commit is contained in:
parent
1719c192a8
commit
71d9447467
@ -1,6 +1,5 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
@ -27,6 +26,10 @@ android {
|
|||||||
variant.resValue "string", "versionName", variant.versionName
|
variant.resValue "string", "versionName", variant.versionName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
viewBinding true
|
||||||
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
|
@ -26,9 +26,9 @@ import androidx.camera.core.*
|
|||||||
import androidx.camera.extensions.HdrImageCaptureExtender
|
import androidx.camera.extensions.HdrImageCaptureExtender
|
||||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import kotlinx.android.synthetic.main.activity_camera.*
|
|
||||||
import sushi.hardcore.droidfs.adapters.DialogSingleChoiceAdapter
|
import sushi.hardcore.droidfs.adapters.DialogSingleChoiceAdapter
|
||||||
import sushi.hardcore.droidfs.content_providers.RestrictedFileProvider
|
import sushi.hardcore.droidfs.content_providers.RestrictedFileProvider
|
||||||
|
import sushi.hardcore.droidfs.databinding.ActivityCameraBinding
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
@ -46,13 +46,14 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
private val dateFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)
|
private val dateFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)
|
||||||
private val random = Random()
|
private val random = Random()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var timerDuration = 0
|
private var timerDuration = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
if (value > 0){
|
if (value > 0){
|
||||||
image_timer.setImageResource(R.drawable.icon_timer_on)
|
binding.imageTimer.setImageResource(R.drawable.icon_timer_on)
|
||||||
} else {
|
} else {
|
||||||
image_timer.setImageResource(R.drawable.icon_timer_off)
|
binding.imageTimer.setImageResource(R.drawable.icon_timer_off)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private var usf_keep_open = false
|
private var usf_keep_open = false
|
||||||
@ -68,10 +69,13 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
private var resolutions: Array<Size>? = null
|
private var resolutions: Array<Size>? = null
|
||||||
private var currentResolutionIndex: Int = 0
|
private var currentResolutionIndex: Int = 0
|
||||||
private var isBackCamera = true
|
private var isBackCamera = true
|
||||||
|
private lateinit var binding: ActivityCameraBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
usf_keep_open = sharedPrefs.getBoolean("usf_keep_open", false)
|
usf_keep_open = sharedPrefs.getBoolean("usf_keep_open", false)
|
||||||
setContentView(R.layout.activity_camera)
|
binding = ActivityCameraBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
gocryptfsVolume = GocryptfsVolume(intent.getIntExtra("sessionID", -1))
|
gocryptfsVolume = GocryptfsVolume(intent.getIntExtra("sessionID", -1))
|
||||||
outputDirectory = intent.getStringExtra("path")!!
|
outputDirectory = intent.getStringExtra("path")!!
|
||||||
|
|
||||||
@ -87,7 +91,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
|
|
||||||
cameraExecutor = Executors.newSingleThreadExecutor()
|
cameraExecutor = Executors.newSingleThreadExecutor()
|
||||||
|
|
||||||
image_ratio.setOnClickListener {
|
binding.imageRatio.setOnClickListener {
|
||||||
resolutions?.let {
|
resolutions?.let {
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.choose_resolution)
|
.setTitle(R.string.choose_resolution)
|
||||||
@ -100,7 +104,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image_timer.setOnClickListener {
|
binding.imageTimer.setOnClickListener {
|
||||||
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
||||||
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
||||||
dialogEditText.inputType = InputType.TYPE_CLASS_NUMBER
|
dialogEditText.inputType = InputType.TYPE_CLASS_NUMBER
|
||||||
@ -125,12 +129,12 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
|
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
image_close.setOnClickListener {
|
binding.imageClose.setOnClickListener {
|
||||||
isFinishingIntentionally = true
|
isFinishingIntentionally = true
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
image_flash.setOnClickListener {
|
binding.imageFlash.setOnClickListener {
|
||||||
image_flash.setImageResource(when (imageCapture?.flashMode) {
|
binding.imageFlash.setImageResource(when (imageCapture?.flashMode) {
|
||||||
ImageCapture.FLASH_MODE_AUTO -> {
|
ImageCapture.FLASH_MODE_AUTO -> {
|
||||||
imageCapture?.flashMode = ImageCapture.FLASH_MODE_ON
|
imageCapture?.flashMode = ImageCapture.FLASH_MODE_ON
|
||||||
R.drawable.icon_flash_on
|
R.drawable.icon_flash_on
|
||||||
@ -145,18 +149,18 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
image_camera_switch.setOnClickListener {
|
binding.imageCameraSwitch.setOnClickListener {
|
||||||
isBackCamera = if (isBackCamera) {
|
isBackCamera = if (isBackCamera) {
|
||||||
image_camera_switch.setImageResource(R.drawable.icon_camera_front)
|
binding.imageCameraSwitch.setImageResource(R.drawable.icon_camera_front)
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
image_camera_switch.setImageResource(R.drawable.icon_camera_back)
|
binding.imageCameraSwitch.setImageResource(R.drawable.icon_camera_back)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
setupCamera()
|
setupCamera()
|
||||||
}
|
}
|
||||||
take_photo_button.onClick = ::onClickTakePhoto
|
binding.takePhotoButton.onClick = ::onClickTakePhoto
|
||||||
orientedIcons = listOf(image_ratio, image_timer, image_close, image_flash, image_camera_switch)
|
orientedIcons = listOf(binding.imageRatio, binding.imageTimer, binding.imageClose, binding.imageFlash, binding.imageCameraSwitch)
|
||||||
sensorOrientationListener = SensorOrientationListener(this)
|
sensorOrientationListener = SensorOrientationListener(this)
|
||||||
|
|
||||||
val scaleGestureDetector = ScaleGestureDetector(this, object : ScaleGestureDetector.SimpleOnScaleGestureListener(){
|
val scaleGestureDetector = ScaleGestureDetector(this, object : ScaleGestureDetector.SimpleOnScaleGestureListener(){
|
||||||
@ -166,12 +170,12 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
camera_preview.setOnTouchListener { view, event ->
|
binding.cameraPreview.setOnTouchListener { view, event ->
|
||||||
view.performClick()
|
view.performClick()
|
||||||
when (event.action) {
|
when (event.action) {
|
||||||
MotionEvent.ACTION_DOWN -> true
|
MotionEvent.ACTION_DOWN -> true
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
val factory = camera_preview.meteringPointFactory
|
val factory = binding.cameraPreview.meteringPointFactory
|
||||||
val point = factory.createPoint(event.x, event.y)
|
val point = factory.createPoint(event.x, event.y)
|
||||||
val action = FocusMeteringAction.Builder(point).build()
|
val action = FocusMeteringAction.Builder(point).build()
|
||||||
imageCapture?.camera?.cameraControl?.startFocusAndMetering(action)
|
imageCapture?.camera?.cameraControl?.startFocusAndMetering(action)
|
||||||
@ -209,7 +213,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
//resolution.width and resolution.height seem to be inverted
|
//resolution.width and resolution.height seem to be inverted
|
||||||
val width = resolution.height
|
val width = resolution.height
|
||||||
val height = resolution.width
|
val height = resolution.width
|
||||||
camera_preview.layoutParams = if (metrics.widthPixels < width){
|
binding.cameraPreview.layoutParams = if (metrics.widthPixels < width){
|
||||||
RelativeLayout.LayoutParams(
|
RelativeLayout.LayoutParams(
|
||||||
metrics.widthPixels,
|
metrics.widthPixels,
|
||||||
(height * (metrics.widthPixels.toFloat() / width)).toInt()
|
(height * (metrics.widthPixels.toFloat() / width)).toInt()
|
||||||
@ -217,7 +221,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
} else {
|
} else {
|
||||||
RelativeLayout.LayoutParams(width, height)
|
RelativeLayout.LayoutParams(width, height)
|
||||||
}
|
}
|
||||||
(camera_preview.layoutParams as RelativeLayout.LayoutParams).addRule(RelativeLayout.CENTER_IN_PARENT)
|
(binding.cameraPreview.layoutParams as RelativeLayout.LayoutParams).addRule(RelativeLayout.CENTER_IN_PARENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCamera(resolution: Size? = null){
|
private fun setupCamera(resolution: Size? = null){
|
||||||
@ -227,7 +231,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
val preview = Preview.Builder()
|
val preview = Preview.Builder()
|
||||||
.build()
|
.build()
|
||||||
.also {
|
.also {
|
||||||
it.setSurfaceProvider(camera_preview.surfaceProvider)
|
it.setSurfaceProvider(binding.cameraPreview.surfaceProvider)
|
||||||
}
|
}
|
||||||
val builder = ImageCapture.Builder()
|
val builder = ImageCapture.Builder()
|
||||||
.setFlashMode(ImageCapture.FLASH_MODE_AUTO)
|
.setFlashMode(ImageCapture.FLASH_MODE_AUTO)
|
||||||
@ -263,7 +267,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
val outputOptions = ImageCapture.OutputFileOptions.Builder(outputBuff).build()
|
val outputOptions = ImageCapture.OutputFileOptions.Builder(outputBuff).build()
|
||||||
imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
|
imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
|
||||||
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
|
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
|
||||||
take_photo_button.onPhotoTaken()
|
binding.takePhotoButton.onPhotoTaken()
|
||||||
if (gocryptfsVolume.importFile(ByteArrayInputStream(outputBuff.toByteArray()), PathUtils.pathJoin(outputDirectory, fileName))){
|
if (gocryptfsVolume.importFile(ByteArrayInputStream(outputBuff.toByteArray()), PathUtils.pathJoin(outputDirectory, fileName))){
|
||||||
Toast.makeText(applicationContext, getString(R.string.picture_save_success, fileName), Toast.LENGTH_SHORT).show()
|
Toast.makeText(applicationContext, getString(R.string.picture_save_success, fileName), Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
@ -279,7 +283,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
override fun onError(exception: ImageCaptureException) {
|
override fun onError(exception: ImageCaptureException) {
|
||||||
take_photo_button.onPhotoTaken()
|
binding.takePhotoButton.onPhotoTaken()
|
||||||
Toast.makeText(applicationContext, exception.message, Toast.LENGTH_SHORT).show()
|
Toast.makeText(applicationContext, exception.message, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -291,15 +295,15 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
fileName = baseName+(random.nextInt(fileNameRandomMax-fileNameRandomMin)+fileNameRandomMin)+".jpg"
|
fileName = baseName+(random.nextInt(fileNameRandomMax-fileNameRandomMin)+fileNameRandomMin)+".jpg"
|
||||||
} while (gocryptfsVolume.pathExists(fileName))
|
} while (gocryptfsVolume.pathExists(fileName))
|
||||||
if (timerDuration > 0){
|
if (timerDuration > 0){
|
||||||
text_timer.visibility = View.VISIBLE
|
binding.textTimer.visibility = View.VISIBLE
|
||||||
Thread{
|
Thread{
|
||||||
for (i in timerDuration downTo 1){
|
for (i in timerDuration downTo 1){
|
||||||
runOnUiThread { text_timer.text = i.toString() }
|
runOnUiThread { binding.textTimer.text = i.toString() }
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
}
|
}
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
takePhoto()
|
takePhoto()
|
||||||
text_timer.visibility = View.GONE
|
binding.textTimer.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,10 +8,8 @@ import android.text.TextWatcher
|
|||||||
import android.widget.AdapterView.OnItemClickListener
|
import android.widget.AdapterView.OnItemClickListener
|
||||||
import android.widget.Toast
|
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.checkboxes_section.*
|
|
||||||
import kotlinx.android.synthetic.main.volume_path_section.*
|
|
||||||
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
|
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
|
||||||
|
import sushi.hardcore.droidfs.databinding.ActivityChangePasswordBinding
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import sushi.hardcore.droidfs.util.WidgetUtil
|
import sushi.hardcore.droidfs.util.WidgetUtil
|
||||||
import sushi.hardcore.droidfs.util.Wiper
|
import sushi.hardcore.droidfs.util.Wiper
|
||||||
@ -21,28 +19,31 @@ import java.util.*
|
|||||||
|
|
||||||
class ChangePasswordActivity : VolumeActionActivity() {
|
class ChangePasswordActivity : VolumeActionActivity() {
|
||||||
private lateinit var savedVolumesAdapter: SavedVolumesAdapter
|
private lateinit var savedVolumesAdapter: SavedVolumesAdapter
|
||||||
|
private lateinit var binding: ActivityChangePasswordBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_change_password)
|
binding = ActivityChangePasswordBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
setupLayout()
|
setupLayout()
|
||||||
setupFingerprintStuff()
|
setupFingerprintStuff()
|
||||||
savedVolumesAdapter = SavedVolumesAdapter(this, volumeDatabase)
|
savedVolumesAdapter = SavedVolumesAdapter(this, volumeDatabase)
|
||||||
if (savedVolumesAdapter.count > 0){
|
if (savedVolumesAdapter.count > 0){
|
||||||
saved_path_listview.adapter = savedVolumesAdapter
|
binding.savedPathListview.adapter = savedVolumesAdapter
|
||||||
saved_path_listview.onItemClickListener = OnItemClickListener { _, _, position, _ ->
|
binding.savedPathListview.onItemClickListener = OnItemClickListener { _, _, position, _ ->
|
||||||
val volume = savedVolumesAdapter.getItem(position)
|
val volume = savedVolumesAdapter.getItem(position)
|
||||||
currentVolumeName = volume.name
|
currentVolumeName = volume.name
|
||||||
if (volume.isHidden){
|
if (volume.isHidden){
|
||||||
switch_hidden_volume.isChecked = true
|
switchHiddenVolume.isChecked = true
|
||||||
edit_volume_name.setText(currentVolumeName)
|
editVolumeName.setText(currentVolumeName)
|
||||||
} else {
|
} else {
|
||||||
switch_hidden_volume.isChecked = false
|
switchHiddenVolume.isChecked = false
|
||||||
edit_volume_path.setText(currentVolumeName)
|
editVolumePath.setText(currentVolumeName)
|
||||||
}
|
}
|
||||||
onClickSwitchHiddenVolume()
|
onClickSwitchHiddenVolume()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
WidgetUtil.hideWithPadding(saved_path_listview)
|
WidgetUtil.hideWithPadding(binding.savedPathListview)
|
||||||
}
|
}
|
||||||
val textWatcher = object: TextWatcher{
|
val textWatcher = object: TextWatcher{
|
||||||
override fun afterTextChanged(s: Editable?) {
|
override fun afterTextChanged(s: Editable?) {
|
||||||
@ -51,30 +52,34 @@ class ChangePasswordActivity : VolumeActionActivity() {
|
|||||||
}
|
}
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
if (volumeDatabase.isVolumeSaved(s.toString())){
|
if (volumeDatabase.isVolumeSaved(s.toString())){
|
||||||
checkbox_remember_path.isEnabled = false
|
checkboxRememberPath.isEnabled = false
|
||||||
checkbox_remember_path.isChecked = false
|
checkboxRememberPath.isChecked = false
|
||||||
|
binding.editOldPassword.apply {
|
||||||
if (volumeDatabase.isHashSaved(s.toString())){
|
if (volumeDatabase.isHashSaved(s.toString())){
|
||||||
edit_old_password.text = null
|
text = null
|
||||||
edit_old_password.hint = getString(R.string.hash_saved_hint)
|
hint = getString(R.string.hash_saved_hint)
|
||||||
edit_old_password.isEnabled = false
|
isEnabled = false
|
||||||
} else {
|
} else {
|
||||||
edit_old_password.hint = null
|
hint = null
|
||||||
edit_old_password.isEnabled = true
|
isEnabled = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkbox_remember_path.isEnabled = true
|
checkboxRememberPath.isEnabled = true
|
||||||
edit_old_password.hint = null
|
binding.editOldPassword.apply {
|
||||||
edit_old_password.isEnabled = true
|
hint = null
|
||||||
|
isEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edit_volume_path.addTextChangedListener(textWatcher)
|
}
|
||||||
edit_volume_name.addTextChangedListener(textWatcher)
|
editVolumePath.addTextChangedListener(textWatcher)
|
||||||
edit_new_password_confirm.setOnEditorActionListener { _, _, _ ->
|
editVolumeName.addTextChangedListener(textWatcher)
|
||||||
|
binding.editNewPasswordConfirm.setOnEditorActionListener { _, _, _ ->
|
||||||
checkVolumePathThenChangePassword()
|
checkVolumePathThenChangePassword()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
button_change_password.setOnClickListener {
|
binding.buttonChangePassword.setOnClickListener {
|
||||||
checkVolumePathThenChangePassword()
|
checkVolumePathThenChangePassword()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +88,7 @@ class ChangePasswordActivity : VolumeActionActivity() {
|
|||||||
if (PathUtils.isTreeUriOnPrimaryStorage(uri)){
|
if (PathUtils.isTreeUriOnPrimaryStorage(uri)){
|
||||||
val path = PathUtils.getFullPathFromTreeUri(uri, this)
|
val path = PathUtils.getFullPathFromTreeUri(uri, this)
|
||||||
if (path != null){
|
if (path != null){
|
||||||
edit_volume_path.setText(path)
|
editVolumePath.setText(path)
|
||||||
} else {
|
} else {
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.error)
|
.setTitle(R.string.error)
|
||||||
@ -122,16 +127,16 @@ class ChangePasswordActivity : VolumeActionActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun changePassword(givenHash: ByteArray? = null){
|
private fun changePassword(givenHash: ByteArray? = null){
|
||||||
val newPassword = edit_new_password.text.toString().toCharArray()
|
val newPassword = binding.editNewPassword.text.toString().toCharArray()
|
||||||
val newPasswordConfirm = edit_new_password_confirm.text.toString().toCharArray()
|
val newPasswordConfirm = binding.editNewPasswordConfirm.text.toString().toCharArray()
|
||||||
if (!newPassword.contentEquals(newPasswordConfirm)) {
|
if (!newPassword.contentEquals(newPasswordConfirm)) {
|
||||||
Toast.makeText(this, R.string.passwords_mismatch, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.passwords_mismatch, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
object : LoadingTask(this, R.string.loading_msg_change_password) {
|
object : LoadingTask(this, R.string.loading_msg_change_password) {
|
||||||
override fun doTask(activity: AppCompatActivity) {
|
override fun doTask(activity: AppCompatActivity) {
|
||||||
val oldPassword = edit_old_password.text.toString().toCharArray()
|
val oldPassword = binding.editOldPassword.text.toString().toCharArray()
|
||||||
var returnedHash: ByteArray? = null
|
var returnedHash: ByteArray? = null
|
||||||
if (checkbox_save_password.isChecked) {
|
if (checkboxSavePassword.isChecked) {
|
||||||
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
||||||
}
|
}
|
||||||
var changePasswordImmediately = true
|
var changePasswordImmediately = true
|
||||||
@ -162,14 +167,14 @@ class ChangePasswordActivity : VolumeActionActivity() {
|
|||||||
}
|
}
|
||||||
if (changePasswordImmediately) {
|
if (changePasswordImmediately) {
|
||||||
if (GocryptfsVolume.changePassword(currentVolumePath, oldPassword, givenHash, newPassword, returnedHash)) {
|
if (GocryptfsVolume.changePassword(currentVolumePath, oldPassword, givenHash, newPassword, returnedHash)) {
|
||||||
val volume = Volume(currentVolumeName, switch_hidden_volume.isChecked)
|
val volume = Volume(currentVolumeName, switchHiddenVolume.isChecked)
|
||||||
if (volumeDatabase.isHashSaved(currentVolumeName)) {
|
if (volumeDatabase.isHashSaved(currentVolumeName)) {
|
||||||
volumeDatabase.removeHash(volume)
|
volumeDatabase.removeHash(volume)
|
||||||
}
|
}
|
||||||
if (checkbox_remember_path.isChecked) {
|
if (checkboxRememberPath.isChecked) {
|
||||||
volumeDatabase.saveVolume(volume)
|
volumeDatabase.saveVolume(volume)
|
||||||
}
|
}
|
||||||
if (checkbox_save_password.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
if (checkboxSavePassword.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
||||||
stopTask {
|
stopTask {
|
||||||
savePasswordHash(returnedHash) {
|
savePasswordHash(returnedHash) {
|
||||||
onPasswordChanged()
|
onPasswordChanged()
|
||||||
@ -209,8 +214,8 @@ class ChangePasswordActivity : VolumeActionActivity() {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
Wiper.wipeEditText(edit_old_password)
|
Wiper.wipeEditText(binding.editOldPassword)
|
||||||
Wiper.wipeEditText(edit_new_password)
|
Wiper.wipeEditText(binding.editNewPassword)
|
||||||
Wiper.wipeEditText(edit_new_password_confirm)
|
Wiper.wipeEditText(binding.editNewPasswordConfirm)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,9 +6,7 @@ import android.os.Build
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import kotlinx.android.synthetic.main.activity_create.*
|
import sushi.hardcore.droidfs.databinding.ActivityCreateBinding
|
||||||
import kotlinx.android.synthetic.main.checkboxes_section.*
|
|
||||||
import kotlinx.android.synthetic.main.volume_path_section.*
|
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import sushi.hardcore.droidfs.util.Wiper
|
import sushi.hardcore.droidfs.util.Wiper
|
||||||
@ -19,23 +17,26 @@ import java.util.*
|
|||||||
class CreateActivity : VolumeActionActivity() {
|
class CreateActivity : VolumeActionActivity() {
|
||||||
private var sessionID = -1
|
private var sessionID = -1
|
||||||
private var isStartingExplorer = false
|
private var isStartingExplorer = false
|
||||||
|
private lateinit var binding: ActivityCreateBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_create)
|
binding = ActivityCreateBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
setupLayout()
|
setupLayout()
|
||||||
setupFingerprintStuff()
|
setupFingerprintStuff()
|
||||||
edit_password_confirm.setOnEditorActionListener { _, _, _ ->
|
binding.editPasswordConfirm.setOnEditorActionListener { _, _, _ ->
|
||||||
createVolume()
|
createVolume()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
button_create.setOnClickListener {
|
binding.buttonCreate.setOnClickListener {
|
||||||
createVolume()
|
createVolume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClickSwitchHiddenVolume() {
|
override fun onClickSwitchHiddenVolume() {
|
||||||
super.onClickSwitchHiddenVolume()
|
super.onClickSwitchHiddenVolume()
|
||||||
if (switch_hidden_volume.isChecked){
|
if (switchHiddenVolume.isChecked){
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.warning)
|
.setTitle(R.string.warning)
|
||||||
.setMessage(R.string.hidden_volume_warning)
|
.setMessage(R.string.hidden_volume_warning)
|
||||||
@ -48,7 +49,7 @@ class CreateActivity : VolumeActionActivity() {
|
|||||||
if (PathUtils.isTreeUriOnPrimaryStorage(uri)){
|
if (PathUtils.isTreeUriOnPrimaryStorage(uri)){
|
||||||
val path = PathUtils.getFullPathFromTreeUri(uri, this)
|
val path = PathUtils.getFullPathFromTreeUri(uri, this)
|
||||||
if (path != null){
|
if (path != null){
|
||||||
edit_volume_path.setText(path)
|
editVolumePath.setText(path)
|
||||||
} else {
|
} else {
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.error)
|
.setTitle(R.string.error)
|
||||||
@ -67,8 +68,8 @@ class CreateActivity : VolumeActionActivity() {
|
|||||||
|
|
||||||
fun createVolume() {
|
fun createVolume() {
|
||||||
loadVolumePath {
|
loadVolumePath {
|
||||||
val password = edit_password.text.toString().toCharArray()
|
val password = binding.editPassword.text.toString().toCharArray()
|
||||||
val passwordConfirm = edit_password_confirm.text.toString().toCharArray()
|
val passwordConfirm = binding.editPasswordConfirm.text.toString().toCharArray()
|
||||||
if (!password.contentEquals(passwordConfirm)) {
|
if (!password.contentEquals(passwordConfirm)) {
|
||||||
Toast.makeText(this, R.string.passwords_mismatch, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.passwords_mismatch, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
@ -113,18 +114,18 @@ class CreateActivity : VolumeActionActivity() {
|
|||||||
if (goodDirectory) {
|
if (goodDirectory) {
|
||||||
if (GocryptfsVolume.createVolume(currentVolumePath, password, false, GocryptfsVolume.ScryptDefaultLogN, ConstValues.creator)) {
|
if (GocryptfsVolume.createVolume(currentVolumePath, password, false, GocryptfsVolume.ScryptDefaultLogN, ConstValues.creator)) {
|
||||||
var returnedHash: ByteArray? = null
|
var returnedHash: ByteArray? = null
|
||||||
if (checkbox_save_password.isChecked){
|
if (checkboxSavePassword.isChecked){
|
||||||
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
||||||
}
|
}
|
||||||
sessionID = GocryptfsVolume.init(currentVolumePath, password, null, returnedHash)
|
sessionID = GocryptfsVolume.init(currentVolumePath, password, null, returnedHash)
|
||||||
if (sessionID != -1) {
|
if (sessionID != -1) {
|
||||||
if (checkbox_remember_path.isChecked) {
|
if (checkboxRememberPath.isChecked) {
|
||||||
if (volumeDatabase.isVolumeSaved(currentVolumeName)) { //cleaning old saved path
|
if (volumeDatabase.isVolumeSaved(currentVolumeName)) { //cleaning old saved path
|
||||||
volumeDatabase.removeVolume(Volume(currentVolumeName))
|
volumeDatabase.removeVolume(Volume(currentVolumeName))
|
||||||
}
|
}
|
||||||
volumeDatabase.saveVolume(Volume(currentVolumeName, switch_hidden_volume.isChecked))
|
volumeDatabase.saveVolume(Volume(currentVolumeName, switchHiddenVolume.isChecked))
|
||||||
}
|
}
|
||||||
if (checkbox_save_password.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
if (checkboxSavePassword.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
||||||
stopTask {
|
stopTask {
|
||||||
savePasswordHash(returnedHash) {
|
savePasswordHash(returnedHash) {
|
||||||
startExplorer()
|
startExplorer()
|
||||||
@ -183,7 +184,7 @@ class CreateActivity : VolumeActionActivity() {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
Wiper.wipeEditText(edit_password)
|
Wiper.wipeEditText(binding.editPassword)
|
||||||
Wiper.wipeEditText(edit_password_confirm)
|
Wiper.wipeEditText(binding.editPasswordConfirm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,16 @@ import android.content.Intent
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import sushi.hardcore.droidfs.databinding.ActivityMainBinding
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
|
|
||||||
class MainActivity : BaseActivity() {
|
class MainActivity : BaseActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
val binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setSupportActionBar(toolbar)
|
setContentView(binding.root)
|
||||||
|
setSupportActionBar(binding.toolbar.toolbar)
|
||||||
if (!isRecreating) {
|
if (!isRecreating) {
|
||||||
if (sharedPrefs.getBoolean("applicationFirstOpening", true)){
|
if (sharedPrefs.getBoolean("applicationFirstOpening", true)){
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
@ -29,13 +30,13 @@ class MainActivity : BaseActivity() {
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button_open.setOnClickListener {
|
binding.buttonOpen.setOnClickListener {
|
||||||
startActivity(OpenActivity::class.java)
|
startActivity(OpenActivity::class.java)
|
||||||
}
|
}
|
||||||
button_create.setOnClickListener {
|
binding.buttonCreate.setOnClickListener {
|
||||||
startActivity(CreateActivity::class.java)
|
startActivity(CreateActivity::class.java)
|
||||||
}
|
}
|
||||||
button_change_password.setOnClickListener {
|
binding.buttonChangePassword.setOnClickListener {
|
||||||
startActivity(ChangePasswordActivity::class.java)
|
startActivity(ChangePasswordActivity::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,9 @@ import android.text.TextWatcher
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.AdapterView.OnItemClickListener
|
import android.widget.AdapterView.OnItemClickListener
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import kotlinx.android.synthetic.main.activity_open.*
|
|
||||||
import kotlinx.android.synthetic.main.checkboxes_section.*
|
|
||||||
import kotlinx.android.synthetic.main.volume_path_section.*
|
|
||||||
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
|
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
|
||||||
import sushi.hardcore.droidfs.content_providers.RestrictedFileProvider
|
import sushi.hardcore.droidfs.content_providers.RestrictedFileProvider
|
||||||
|
import sushi.hardcore.droidfs.databinding.ActivityOpenBinding
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
import sushi.hardcore.droidfs.explorers.ExplorerActivity
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerActivityDrop
|
import sushi.hardcore.droidfs.explorers.ExplorerActivityDrop
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerActivityPick
|
import sushi.hardcore.droidfs.explorers.ExplorerActivityPick
|
||||||
@ -29,24 +27,26 @@ class OpenActivity : VolumeActionActivity() {
|
|||||||
private var sessionID = -1
|
private var sessionID = -1
|
||||||
private var isStartingActivity = false
|
private var isStartingActivity = false
|
||||||
private var isFinishingIntentionally = false
|
private var isFinishingIntentionally = false
|
||||||
|
private lateinit var binding: ActivityOpenBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_open)
|
binding = ActivityOpenBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
setupLayout()
|
setupLayout()
|
||||||
setupFingerprintStuff()
|
setupFingerprintStuff()
|
||||||
savedVolumesAdapter = SavedVolumesAdapter(this, volumeDatabase)
|
savedVolumesAdapter = SavedVolumesAdapter(this, volumeDatabase)
|
||||||
if (savedVolumesAdapter.count > 0){
|
if (savedVolumesAdapter.count > 0){
|
||||||
saved_path_listview.adapter = savedVolumesAdapter
|
binding.savedPathListview.adapter = savedVolumesAdapter
|
||||||
saved_path_listview.onItemClickListener = OnItemClickListener { _, _, position, _ ->
|
binding.savedPathListview.onItemClickListener = OnItemClickListener { _, _, position, _ ->
|
||||||
val volume = savedVolumesAdapter.getItem(position)
|
val volume = savedVolumesAdapter.getItem(position)
|
||||||
currentVolumeName = volume.name
|
currentVolumeName = volume.name
|
||||||
if (volume.isHidden){
|
if (volume.isHidden){
|
||||||
switch_hidden_volume.isChecked = true
|
switchHiddenVolume.isChecked = true
|
||||||
edit_volume_name.setText(currentVolumeName)
|
editVolumeName.setText(currentVolumeName)
|
||||||
} else {
|
} else {
|
||||||
switch_hidden_volume.isChecked = false
|
switchHiddenVolume.isChecked = false
|
||||||
edit_volume_path.setText(currentVolumeName)
|
editVolumePath.setText(currentVolumeName)
|
||||||
}
|
}
|
||||||
onClickSwitchHiddenVolume()
|
onClickSwitchHiddenVolume()
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
||||||
@ -63,7 +63,7 @@ class OpenActivity : VolumeActionActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
WidgetUtil.hideWithPadding(saved_path_listview)
|
WidgetUtil.hideWithPadding(binding.savedPathListview)
|
||||||
}
|
}
|
||||||
val textWatcher = object: TextWatcher {
|
val textWatcher = object: TextWatcher {
|
||||||
override fun afterTextChanged(s: Editable?) {
|
override fun afterTextChanged(s: Editable?) {
|
||||||
@ -72,27 +72,27 @@ class OpenActivity : VolumeActionActivity() {
|
|||||||
}
|
}
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
if (volumeDatabase.isVolumeSaved(s.toString())){
|
if (volumeDatabase.isVolumeSaved(s.toString())){
|
||||||
checkbox_remember_path.isEnabled = false
|
checkboxRememberPath.isEnabled = false
|
||||||
checkbox_remember_path.isChecked = false
|
checkboxRememberPath.isChecked = false
|
||||||
if (volumeDatabase.isHashSaved(s.toString())){
|
if (volumeDatabase.isHashSaved(s.toString())){
|
||||||
checkbox_save_password.isEnabled = false
|
checkboxSavePassword.isEnabled = false
|
||||||
checkbox_save_password.isChecked = false
|
checkboxSavePassword.isChecked = false
|
||||||
} else {
|
} else {
|
||||||
checkbox_save_password.isEnabled = true
|
checkboxSavePassword.isEnabled = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkbox_remember_path.isEnabled = true
|
checkboxRememberPath.isEnabled = true
|
||||||
checkbox_save_password.isEnabled = true
|
checkboxSavePassword.isEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edit_volume_path.addTextChangedListener(textWatcher)
|
editVolumePath.addTextChangedListener(textWatcher)
|
||||||
edit_volume_name.addTextChangedListener(textWatcher)
|
editVolumeName.addTextChangedListener(textWatcher)
|
||||||
edit_password.setOnEditorActionListener { _, _, _ ->
|
binding.editPassword.setOnEditorActionListener { _, _, _ ->
|
||||||
checkVolumePathThenOpen()
|
checkVolumePathThenOpen()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
button_open.setOnClickListener {
|
binding.buttonOpen.setOnClickListener {
|
||||||
checkVolumePathThenOpen()
|
checkVolumePathThenOpen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ class OpenActivity : VolumeActionActivity() {
|
|||||||
override fun onDirectoryPicked(uri: Uri) {
|
override fun onDirectoryPicked(uri: Uri) {
|
||||||
val path = PathUtils.getFullPathFromTreeUri(uri, this)
|
val path = PathUtils.getFullPathFromTreeUri(uri, this)
|
||||||
if (path != null){
|
if (path != null){
|
||||||
edit_volume_path.setText(path)
|
editVolumePath.setText(path)
|
||||||
} else {
|
} else {
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.error)
|
.setTitle(R.string.error)
|
||||||
@ -162,17 +162,17 @@ class OpenActivity : VolumeActionActivity() {
|
|||||||
private fun 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) {
|
||||||
val password = edit_password.text.toString().toCharArray()
|
val password = binding.editPassword.text.toString().toCharArray()
|
||||||
var returnedHash: ByteArray? = null
|
var returnedHash: ByteArray? = null
|
||||||
if (checkbox_save_password.isChecked){
|
if (checkboxSavePassword.isChecked){
|
||||||
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
||||||
}
|
}
|
||||||
sessionID = GocryptfsVolume.init(currentVolumePath, password, null, returnedHash)
|
sessionID = GocryptfsVolume.init(currentVolumePath, password, null, returnedHash)
|
||||||
if (sessionID != -1) {
|
if (sessionID != -1) {
|
||||||
if (checkbox_remember_path.isChecked) {
|
if (checkboxRememberPath.isChecked) {
|
||||||
volumeDatabase.saveVolume(Volume(currentVolumeName, switch_hidden_volume.isChecked))
|
volumeDatabase.saveVolume(Volume(currentVolumeName, switchHiddenVolume.isChecked))
|
||||||
}
|
}
|
||||||
if (checkbox_save_password.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
if (checkboxSavePassword.isChecked && returnedHash != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
|
||||||
stopTask {
|
stopTask {
|
||||||
savePasswordHash(returnedHash) { success ->
|
savePasswordHash(returnedHash) { success ->
|
||||||
if (success){
|
if (success){
|
||||||
@ -261,7 +261,7 @@ class OpenActivity : VolumeActionActivity() {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
Wiper.wipeEditText(edit_password)
|
Wiper.wipeEditText(binding.editPassword)
|
||||||
if (intent.action == "pick" && !isFinishingIntentionally){
|
if (intent.action == "pick" && !isFinishingIntentionally){
|
||||||
val sessionID = intent.getIntExtra("sessionID", -1)
|
val sessionID = intent.getIntExtra("sessionID", -1)
|
||||||
if (sessionID != -1){
|
if (sessionID != -1){
|
||||||
|
@ -6,7 +6,7 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.jaredrummler.android.colorpicker.ColorPreferenceCompat
|
import com.jaredrummler.android.colorpicker.ColorPreferenceCompat
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
import sushi.hardcore.droidfs.databinding.ActivitySettingsBinding
|
||||||
import sushi.hardcore.droidfs.widgets.SimpleActionPreference
|
import sushi.hardcore.droidfs.widgets.SimpleActionPreference
|
||||||
import sushi.hardcore.droidfs.widgets.ThemeColor
|
import sushi.hardcore.droidfs.widgets.ThemeColor
|
||||||
|
|
||||||
@ -14,8 +14,9 @@ class SettingsActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_settings)
|
val binding = ActivitySettingsBinding.inflate(layoutInflater)
|
||||||
setSupportActionBar(toolbar)
|
setContentView(binding.root)
|
||||||
|
setSupportActionBar(binding.toolbar.toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
val screen = intent.extras?.getString("screen") ?: "main"
|
val screen = intent.extras?.getString("screen") ?: "main"
|
||||||
val fragment = if (screen == "UnsafeFeaturesSettingsFragment") {
|
val fragment = if (screen == "UnsafeFeaturesSettingsFragment") {
|
||||||
|
@ -10,24 +10,31 @@ import android.os.Build
|
|||||||
import android.security.keystore.KeyGenParameterSpec
|
import android.security.keystore.KeyGenParameterSpec
|
||||||
import android.security.keystore.KeyPermanentlyInvalidatedException
|
import android.security.keystore.KeyPermanentlyInvalidatedException
|
||||||
import android.security.keystore.KeyProperties
|
import android.security.keystore.KeyProperties
|
||||||
import android.widget.LinearLayout
|
import android.widget.*
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.appcompat.widget.SwitchCompat
|
||||||
import androidx.biometric.BiometricManager
|
import androidx.biometric.BiometricManager
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import kotlinx.android.synthetic.main.checkboxes_section.*
|
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
|
||||||
import kotlinx.android.synthetic.main.volume_path_section.*
|
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import sushi.hardcore.droidfs.util.WidgetUtil
|
import sushi.hardcore.droidfs.util.WidgetUtil
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
|
import sushi.hardcore.droidfs.widgets.ColoredImageButton
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import javax.crypto.*
|
import javax.crypto.*
|
||||||
import javax.crypto.spec.GCMParameterSpec
|
import javax.crypto.spec.GCMParameterSpec
|
||||||
|
|
||||||
abstract class VolumeActionActivity : BaseActivity() {
|
abstract class VolumeActionActivity : BaseActivity() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val STORAGE_PERMISSIONS_REQUEST = 0
|
||||||
|
private const val ANDROID_KEY_STORE = "AndroidKeyStore"
|
||||||
|
private const val KEY_ALIAS = "Hash Key"
|
||||||
|
private const val KEY_SIZE = 256
|
||||||
|
private const val GCM_TAG_LEN = 128
|
||||||
|
}
|
||||||
|
|
||||||
protected lateinit var currentVolumeName: String
|
protected lateinit var currentVolumeName: String
|
||||||
protected lateinit var currentVolumePath: String
|
protected lateinit var currentVolumePath: String
|
||||||
protected lateinit var volumeDatabase: VolumeDatabase
|
protected lateinit var volumeDatabase: VolumeDatabase
|
||||||
@ -50,18 +57,18 @@ abstract class VolumeActionActivity : BaseActivity() {
|
|||||||
private lateinit var dataToProcess: ByteArray
|
private lateinit var dataToProcess: ByteArray
|
||||||
private lateinit var originalHiddenVolumeSectionLayoutParams: LinearLayout.LayoutParams
|
private lateinit var originalHiddenVolumeSectionLayoutParams: LinearLayout.LayoutParams
|
||||||
private lateinit var originalNormalVolumeSectionLayoutParams: LinearLayout.LayoutParams
|
private lateinit var originalNormalVolumeSectionLayoutParams: LinearLayout.LayoutParams
|
||||||
companion object {
|
protected lateinit var switchHiddenVolume: SwitchCompat
|
||||||
private const val STORAGE_PERMISSIONS_REQUEST = 0
|
protected lateinit var checkboxRememberPath: CheckBox
|
||||||
private const val ANDROID_KEY_STORE = "AndroidKeyStore"
|
protected lateinit var checkboxSavePassword: CheckBox
|
||||||
private const val KEY_ALIAS = "Hash Key"
|
protected lateinit var editVolumeName: EditText
|
||||||
private const val KEY_SIZE = 256
|
protected lateinit var editVolumePath: EditText
|
||||||
private const val GCM_TAG_LEN = 128
|
private lateinit var hiddenVolumeSection: LinearLayout
|
||||||
}
|
private lateinit var normalVolumeSection: LinearLayout
|
||||||
|
|
||||||
protected fun setupLayout() {
|
protected fun setupLayout() {
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(findViewById(R.id.toolbar))
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
button_pick_directory.setOnClickListener {
|
findViewById<ColoredImageButton>(R.id.button_pick_directory).setOnClickListener {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) +
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) +
|
||||||
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
@ -73,20 +80,27 @@ abstract class VolumeActionActivity : BaseActivity() {
|
|||||||
safePickDirectory()
|
safePickDirectory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_hidden_volume.setOnClickListener {
|
switchHiddenVolume = findViewById(R.id.switch_hidden_volume)
|
||||||
|
checkboxRememberPath = findViewById(R.id.checkbox_remember_path)
|
||||||
|
checkboxSavePassword = findViewById(R.id.checkbox_save_password)
|
||||||
|
editVolumeName = findViewById(R.id.edit_volume_name)
|
||||||
|
editVolumePath = findViewById(R.id.edit_volume_path)
|
||||||
|
hiddenVolumeSection = findViewById(R.id.hidden_volume_section)
|
||||||
|
normalVolumeSection = findViewById(R.id.normal_volume_section)
|
||||||
|
switchHiddenVolume.setOnClickListener {
|
||||||
onClickSwitchHiddenVolume()
|
onClickSwitchHiddenVolume()
|
||||||
}
|
}
|
||||||
checkbox_remember_path.setOnClickListener {
|
checkboxRememberPath.setOnClickListener {
|
||||||
if (!checkbox_remember_path.isChecked) {
|
if (!checkboxRememberPath.isChecked) {
|
||||||
checkbox_save_password.isChecked = false
|
checkboxSavePassword.isChecked = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkbox_save_password.setOnClickListener {
|
checkboxSavePassword.setOnClickListener {
|
||||||
if (checkbox_save_password.isChecked) {
|
if (checkboxSavePassword.isChecked) {
|
||||||
if (biometricCanAuthenticateCode == 0) {
|
if (biometricCanAuthenticateCode == 0) {
|
||||||
checkbox_remember_path.isChecked = checkbox_remember_path.isEnabled
|
checkboxRememberPath.isChecked = checkboxRememberPath.isEnabled
|
||||||
} else {
|
} else {
|
||||||
checkbox_save_password.isChecked = false
|
checkboxSavePassword.isChecked = false
|
||||||
printAuthenticateImpossibleError()
|
printAuthenticateImpossibleError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,12 +108,12 @@ abstract class VolumeActionActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected open fun onClickSwitchHiddenVolume() {
|
protected open fun onClickSwitchHiddenVolume() {
|
||||||
if (switch_hidden_volume.isChecked){
|
if (switchHiddenVolume.isChecked){
|
||||||
WidgetUtil.show(hidden_volume_section, originalHiddenVolumeSectionLayoutParams)
|
WidgetUtil.show(hiddenVolumeSection, originalHiddenVolumeSectionLayoutParams)
|
||||||
WidgetUtil.hide(normal_volume_section)
|
WidgetUtil.hide(normalVolumeSection)
|
||||||
} else {
|
} else {
|
||||||
WidgetUtil.show(normal_volume_section, originalNormalVolumeSectionLayoutParams)
|
WidgetUtil.show(normalVolumeSection, originalNormalVolumeSectionLayoutParams)
|
||||||
WidgetUtil.hide(hidden_volume_section)
|
WidgetUtil.hide(hiddenVolumeSection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,9 +152,9 @@ abstract class VolumeActionActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun setupFingerprintStuff(){
|
protected fun setupFingerprintStuff(){
|
||||||
originalHiddenVolumeSectionLayoutParams = hidden_volume_section.layoutParams as LinearLayout.LayoutParams
|
originalHiddenVolumeSectionLayoutParams = hiddenVolumeSection.layoutParams as LinearLayout.LayoutParams
|
||||||
originalNormalVolumeSectionLayoutParams = normal_volume_section.layoutParams as LinearLayout.LayoutParams
|
originalNormalVolumeSectionLayoutParams = normalVolumeSection.layoutParams as LinearLayout.LayoutParams
|
||||||
WidgetUtil.hide(hidden_volume_section)
|
WidgetUtil.hide(hiddenVolumeSection)
|
||||||
volumeDatabase = VolumeDatabase(this)
|
volumeDatabase = VolumeDatabase(this)
|
||||||
usf_fingerprint = sharedPrefs.getBoolean("usf_fingerprint", false)
|
usf_fingerprint = sharedPrefs.getBoolean("usf_fingerprint", false)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && usf_fingerprint) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && usf_fingerprint) {
|
||||||
@ -173,7 +187,7 @@ abstract class VolumeActionActivity : BaseActivity() {
|
|||||||
when (actionMode) {
|
when (actionMode) {
|
||||||
Cipher.ENCRYPT_MODE -> {
|
Cipher.ENCRYPT_MODE -> {
|
||||||
val cipherText = cipherObject.doFinal(dataToProcess)
|
val cipherText = cipherObject.doFinal(dataToProcess)
|
||||||
success = volumeDatabase.addHash(Volume(currentVolumeName, switch_hidden_volume.isChecked, cipherText, cipherObject.iv))
|
success = volumeDatabase.addHash(Volume(currentVolumeName, switchHiddenVolume.isChecked, cipherText, cipherObject.iv))
|
||||||
}
|
}
|
||||||
Cipher.DECRYPT_MODE -> {
|
Cipher.DECRYPT_MODE -> {
|
||||||
try {
|
try {
|
||||||
@ -212,7 +226,7 @@ abstract class VolumeActionActivity : BaseActivity() {
|
|||||||
biometricPrompt = BiometricPrompt(this, executor, callback)
|
biometricPrompt = BiometricPrompt(this, executor, callback)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
WidgetUtil.hideWithPadding(checkbox_save_password)
|
WidgetUtil.hideWithPadding(checkboxSavePassword)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,17 +348,17 @@ abstract class VolumeActionActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun loadVolumePath(callback: () -> Unit){
|
protected fun loadVolumePath(callback: () -> Unit){
|
||||||
currentVolumeName = if (switch_hidden_volume.isChecked){
|
currentVolumeName = if (switchHiddenVolume.isChecked){
|
||||||
edit_volume_name.text.toString()
|
editVolumeName.text.toString()
|
||||||
} else {
|
} else {
|
||||||
edit_volume_path.text.toString()
|
editVolumePath.text.toString()
|
||||||
}
|
}
|
||||||
if (currentVolumeName.isEmpty()) {
|
if (currentVolumeName.isEmpty()) {
|
||||||
Toast.makeText(this, if (switch_hidden_volume.isChecked) {R.string.enter_volume_name} else {R.string.enter_volume_path}, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, if (switchHiddenVolume.isChecked) {R.string.enter_volume_name} else {R.string.enter_volume_path}, Toast.LENGTH_SHORT).show()
|
||||||
} else if (switch_hidden_volume.isChecked && currentVolumeName.contains("/")){
|
} else if (switchHiddenVolume.isChecked && currentVolumeName.contains("/")){
|
||||||
Toast.makeText(this, R.string.error_slash_in_name, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.error_slash_in_name, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
currentVolumePath = if (switch_hidden_volume.isChecked) {
|
currentVolumePath = if (switchHiddenVolume.isChecked) {
|
||||||
PathUtils.pathJoin(filesDir.path, currentVolumeName)
|
PathUtils.pathJoin(filesDir.path, currentVolumeName)
|
||||||
} else {
|
} else {
|
||||||
currentVolumeName
|
currentVolumeName
|
||||||
|
@ -14,12 +14,12 @@ import android.view.WindowManager
|
|||||||
import android.widget.AdapterView.OnItemClickListener
|
import android.widget.AdapterView.OnItemClickListener
|
||||||
import android.widget.AdapterView.OnItemLongClickListener
|
import android.widget.AdapterView.OnItemLongClickListener
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
|
import android.widget.ListView
|
||||||
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import kotlinx.android.synthetic.main.activity_explorer_base.*
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import kotlinx.android.synthetic.main.explorer_info_bar.*
|
|
||||||
import kotlinx.android.synthetic.main.toolbar.*
|
|
||||||
import sushi.hardcore.droidfs.BaseActivity
|
import sushi.hardcore.droidfs.BaseActivity
|
||||||
import sushi.hardcore.droidfs.ConstValues
|
import sushi.hardcore.droidfs.ConstValues
|
||||||
import sushi.hardcore.droidfs.ConstValues.Companion.isAudio
|
import sushi.hardcore.droidfs.ConstValues.Companion.isAudio
|
||||||
@ -62,6 +62,14 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
protected var isStartingActivity = false
|
protected var isStartingActivity = false
|
||||||
private var usf_open = false
|
private var usf_open = false
|
||||||
protected var usf_keep_open = false
|
protected var usf_keep_open = false
|
||||||
|
private lateinit var toolbar: androidx.appcompat.widget.Toolbar
|
||||||
|
private lateinit var titleText: TextView
|
||||||
|
private lateinit var listExplorer: ListView
|
||||||
|
private lateinit var refresher: SwipeRefreshLayout
|
||||||
|
private lateinit var textDirEmpty: TextView
|
||||||
|
private lateinit var currentPathText: TextView
|
||||||
|
private lateinit var totalSizeText: TextView
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
usf_open = sharedPrefs.getBoolean("usf_open", false)
|
usf_open = sharedPrefs.getBoolean("usf_open", false)
|
||||||
@ -74,16 +82,25 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
foldersFirst = sharedPrefs.getBoolean("folders_first", true)
|
foldersFirst = sharedPrefs.getBoolean("folders_first", true)
|
||||||
currentSortOrderIndex = resources.getStringArray(R.array.sort_orders_values).indexOf(sharedPrefs.getString(ConstValues.sort_order_key, "name"))
|
currentSortOrderIndex = resources.getStringArray(R.array.sort_orders_values).indexOf(sharedPrefs.getString(ConstValues.sort_order_key, "name"))
|
||||||
init()
|
init()
|
||||||
|
toolbar = findViewById(R.id.toolbar)
|
||||||
|
titleText = findViewById(R.id.title_text)
|
||||||
|
listExplorer = findViewById(R.id.list_explorer)
|
||||||
|
refresher = findViewById(R.id.refresher)
|
||||||
|
textDirEmpty = findViewById(R.id.text_dir_empty)
|
||||||
|
currentPathText = findViewById(R.id.current_path_text)
|
||||||
|
totalSizeText = findViewById(R.id.total_size_text)
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
title = ""
|
title = ""
|
||||||
title_text.text = getString(R.string.volume, volumeName)
|
titleText.text = getString(R.string.volume, volumeName)
|
||||||
explorerAdapter = ExplorerElementAdapter(this)
|
explorerAdapter = ExplorerElementAdapter(this)
|
||||||
explorerViewModel= ViewModelProvider(this).get(ExplorerViewModel::class.java)
|
explorerViewModel= ViewModelProvider(this).get(ExplorerViewModel::class.java)
|
||||||
currentDirectoryPath = explorerViewModel.currentDirectoryPath
|
currentDirectoryPath = explorerViewModel.currentDirectoryPath
|
||||||
setCurrentPath(currentDirectoryPath)
|
setCurrentPath(currentDirectoryPath)
|
||||||
list_explorer.adapter = explorerAdapter
|
listExplorer.apply {
|
||||||
list_explorer.onItemClickListener = OnItemClickListener { _, _, position, _ -> onExplorerItemClick(position) }
|
adapter = explorerAdapter
|
||||||
list_explorer.onItemLongClickListener = OnItemLongClickListener { _, _, position, _ -> onExplorerItemLongClick(position); true }
|
onItemClickListener = OnItemClickListener { _, _, position, _ -> onExplorerItemClick(position) }
|
||||||
|
onItemLongClickListener = OnItemLongClickListener { _, _, position, _ -> onExplorerItemLongClick(position); true }
|
||||||
|
}
|
||||||
refresher.setOnRefreshListener {
|
refresher.setOnRefreshListener {
|
||||||
setCurrentPath(currentDirectoryPath)
|
setCurrentPath(currentDirectoryPath)
|
||||||
refresher.isRefreshing = false
|
refresher.isRefreshing = false
|
||||||
@ -198,14 +215,14 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
|
|
||||||
protected fun setCurrentPath(path: String) {
|
protected fun setCurrentPath(path: String) {
|
||||||
explorerElements = gocryptfsVolume.listDir(path)
|
explorerElements = gocryptfsVolume.listDir(path)
|
||||||
text_dir_empty.visibility = if (explorerElements.size == 0) View.VISIBLE else View.INVISIBLE
|
textDirEmpty.visibility = if (explorerElements.size == 0) View.VISIBLE else View.INVISIBLE
|
||||||
sortExplorerElements()
|
sortExplorerElements()
|
||||||
if (path.isNotEmpty()) { //not root
|
if (path.isNotEmpty()) { //not root
|
||||||
explorerElements.add(0, ExplorerElement("..", (-1).toShort(), -1, -1, currentDirectoryPath))
|
explorerElements.add(0, ExplorerElement("..", (-1).toShort(), -1, -1, currentDirectoryPath))
|
||||||
}
|
}
|
||||||
explorerAdapter.setExplorerElements(explorerElements)
|
explorerAdapter.setExplorerElements(explorerElements)
|
||||||
currentDirectoryPath = path
|
currentDirectoryPath = path
|
||||||
current_path_text.text = getString(R.string.location, currentDirectoryPath)
|
currentPathText.text = getString(R.string.location, currentDirectoryPath)
|
||||||
Thread{
|
Thread{
|
||||||
var totalSize: Long = 0
|
var totalSize: Long = 0
|
||||||
for (element in explorerElements){
|
for (element in explorerElements){
|
||||||
@ -223,7 +240,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
total_size_text.text = getString(R.string.total_size, PathUtils.formatSize(totalSize))
|
totalSizeText.text = getString(R.string.total_size, PathUtils.formatSize(totalSize))
|
||||||
explorerAdapter.notifyDataSetChanged()
|
explorerAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
|
@ -8,13 +8,13 @@ import android.view.WindowManager
|
|||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import kotlinx.android.synthetic.main.activity_explorer.*
|
|
||||||
import sushi.hardcore.droidfs.CameraActivity
|
import sushi.hardcore.droidfs.CameraActivity
|
||||||
import sushi.hardcore.droidfs.GocryptfsVolume
|
import sushi.hardcore.droidfs.GocryptfsVolume
|
||||||
import sushi.hardcore.droidfs.OpenActivity
|
import sushi.hardcore.droidfs.OpenActivity
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
import sushi.hardcore.droidfs.adapters.IconTextDialogAdapter
|
import sushi.hardcore.droidfs.adapters.IconTextDialogAdapter
|
||||||
import sushi.hardcore.droidfs.content_providers.ExternalProvider
|
import sushi.hardcore.droidfs.content_providers.ExternalProvider
|
||||||
|
import sushi.hardcore.droidfs.databinding.ActivityExplorerBinding
|
||||||
import sushi.hardcore.droidfs.file_operations.OperationFile
|
import sushi.hardcore.droidfs.file_operations.OperationFile
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
@ -24,10 +24,12 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
companion object {
|
companion object {
|
||||||
private enum class ItemsActions {NONE, COPY, MOVE}
|
private enum class ItemsActions {NONE, COPY, MOVE}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var usf_decrypt = false
|
private var usf_decrypt = false
|
||||||
private var usf_share = false
|
private var usf_share = false
|
||||||
private var currentItemAction = ItemsActions.NONE
|
private var currentItemAction = ItemsActions.NONE
|
||||||
private val itemsToProcess = ArrayList<OperationFile>()
|
private val itemsToProcess = ArrayList<OperationFile>()
|
||||||
|
private lateinit var binding: ActivityExplorerBinding
|
||||||
private val pickFromOtherVolumes = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
private val pickFromOtherVolumes = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
if (result.resultCode == Activity.RESULT_OK) {
|
if (result.resultCode == Activity.RESULT_OK) {
|
||||||
result.data?.let { resultIntent ->
|
result.data?.let { resultIntent ->
|
||||||
@ -145,8 +147,9 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
setContentView(R.layout.activity_explorer)
|
binding = ActivityExplorerBinding.inflate(layoutInflater)
|
||||||
fab.setOnClickListener {
|
setContentView(binding.root)
|
||||||
|
binding.fab.setOnClickListener {
|
||||||
if (currentItemAction != ItemsActions.NONE){
|
if (currentItemAction != ItemsActions.NONE){
|
||||||
openDialogCreateFolder()
|
openDialogCreateFolder()
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,14 +4,17 @@ import android.content.Intent
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import kotlinx.android.synthetic.main.activity_explorer_drop.*
|
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
|
import sushi.hardcore.droidfs.databinding.ActivityExplorerDropBinding
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
|
|
||||||
class ExplorerActivityDrop : BaseExplorerActivity() {
|
class ExplorerActivityDrop : BaseExplorerActivity() {
|
||||||
|
private lateinit var binding: ActivityExplorerDropBinding
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
setContentView(R.layout.activity_explorer_drop)
|
binding = ActivityExplorerDropBinding.inflate(layoutInflater)
|
||||||
fab.setOnClickListener {
|
setContentView(binding.root)
|
||||||
|
binding.fab.setOnClickListener {
|
||||||
openDialogCreateFolder()
|
openDialogCreateFolder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package sushi.hardcore.droidfs.file_viewers
|
package sushi.hardcore.droidfs.file_viewers
|
||||||
|
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer
|
import com.google.android.exoplayer2.SimpleExoPlayer
|
||||||
import kotlinx.android.synthetic.main.activity_audio_player.*
|
import sushi.hardcore.droidfs.databinding.ActivityAudioPlayerBinding
|
||||||
import sushi.hardcore.droidfs.R
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class AudioPlayer: MediaPlayer(){
|
class AudioPlayer: MediaPlayer(){
|
||||||
|
private lateinit var binding: ActivityAudioPlayerBinding
|
||||||
|
|
||||||
override fun viewFile() {
|
override fun viewFile() {
|
||||||
setContentView(R.layout.activity_audio_player)
|
binding = ActivityAudioPlayerBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
super.viewFile()
|
super.viewFile()
|
||||||
refreshFileName()
|
refreshFileName()
|
||||||
}
|
}
|
||||||
@ -17,7 +19,7 @@ class AudioPlayer: MediaPlayer(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun bindPlayer(player: SimpleExoPlayer) {
|
override fun bindPlayer(player: SimpleExoPlayer) {
|
||||||
audio_controller.player = player
|
binding.audioController.player = player
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlaylistIndexChanged() {
|
override fun onPlaylistIndexChanged() {
|
||||||
@ -27,7 +29,7 @@ class AudioPlayer: MediaPlayer(){
|
|||||||
private fun refreshFileName() {
|
private fun refreshFileName() {
|
||||||
val filename = File(filePath).name
|
val filename = File(filePath).name
|
||||||
val pos = filename.lastIndexOf('.')
|
val pos = filename.lastIndexOf('.')
|
||||||
music_title.text = if (pos != -1){
|
binding.musicTitle.text = if (pos != -1){
|
||||||
filename.substring(0,pos)
|
filename.substring(0,pos)
|
||||||
} else {
|
} else {
|
||||||
filename
|
filename
|
||||||
|
@ -13,9 +13,9 @@ import com.bumptech.glide.Glide
|
|||||||
import com.bumptech.glide.RequestBuilder
|
import com.bumptech.glide.RequestBuilder
|
||||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||||
import kotlinx.android.synthetic.main.activity_image_viewer.*
|
|
||||||
import sushi.hardcore.droidfs.ConstValues
|
import sushi.hardcore.droidfs.ConstValues
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
|
import sushi.hardcore.droidfs.databinding.ActivityImageViewerBinding
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
import sushi.hardcore.droidfs.widgets.ZoomableImageView
|
import sushi.hardcore.droidfs.widgets.ZoomableImageView
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
@ -29,6 +29,7 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
private const val hideDelay: Long = 3000
|
private const val hideDelay: Long = 3000
|
||||||
private const val MIN_SWIPE_DISTANCE = 150
|
private const val MIN_SWIPE_DISTANCE = 150
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var fileName: String
|
private lateinit var fileName: String
|
||||||
private lateinit var glideImage: RequestBuilder<Drawable>
|
private lateinit var glideImage: RequestBuilder<Drawable>
|
||||||
private var x1 = 0F
|
private var x1 = 0F
|
||||||
@ -38,28 +39,30 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
private var rotatedBitmap: Bitmap? = null
|
private var rotatedBitmap: Bitmap? = null
|
||||||
private val handler = Handler()
|
private val handler = Handler()
|
||||||
private val hideUI = Runnable {
|
private val hideUI = Runnable {
|
||||||
action_buttons.visibility = View.GONE
|
binding.actionButtons.visibility = View.GONE
|
||||||
action_bar.visibility = View.GONE
|
binding.actionBar.visibility = View.GONE
|
||||||
}
|
}
|
||||||
private val slideshowNext = Runnable {
|
private val slideshowNext = Runnable {
|
||||||
if (slideshowActive){
|
if (slideshowActive){
|
||||||
image_viewer.resetZoomFactor()
|
binding.imageViewer.resetZoomFactor()
|
||||||
swipeImage(-1F, true)
|
swipeImage(-1F, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private lateinit var binding: ActivityImageViewerBinding
|
||||||
|
|
||||||
override fun getFileType(): String {
|
override fun getFileType(): String {
|
||||||
return "image"
|
return "image"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun viewFile() {
|
override fun viewFile() {
|
||||||
setContentView(R.layout.activity_image_viewer)
|
binding = ActivityImageViewerBinding.inflate(layoutInflater)
|
||||||
image_viewer.setOnInteractionListener(object : ZoomableImageView.OnInteractionListener {
|
setContentView(binding.root)
|
||||||
|
binding.imageViewer.setOnInteractionListener(object : ZoomableImageView.OnInteractionListener {
|
||||||
override fun onSingleTap(event: MotionEvent?) {
|
override fun onSingleTap(event: MotionEvent?) {
|
||||||
handler.removeCallbacks(hideUI)
|
handler.removeCallbacks(hideUI)
|
||||||
if (action_buttons.visibility == View.GONE) {
|
if (binding.actionButtons.visibility == View.GONE) {
|
||||||
action_buttons.visibility = View.VISIBLE
|
binding.actionButtons.visibility = View.VISIBLE
|
||||||
action_bar.visibility = View.VISIBLE
|
binding.actionBar.visibility = View.VISIBLE
|
||||||
handler.postDelayed(hideUI, hideDelay)
|
handler.postDelayed(hideUI, hideDelay)
|
||||||
} else {
|
} else {
|
||||||
hideUI.run()
|
hideUI.run()
|
||||||
@ -67,7 +70,7 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onTouch(event: MotionEvent?) {
|
override fun onTouch(event: MotionEvent?) {
|
||||||
if (!image_viewer.isZoomed) {
|
if (!binding.imageViewer.isZoomed) {
|
||||||
when (event?.action) {
|
when (event?.action) {
|
||||||
MotionEvent.ACTION_DOWN -> {
|
MotionEvent.ACTION_DOWN -> {
|
||||||
x1 = event.x
|
x1 = event.x
|
||||||
@ -83,7 +86,7 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
image_delete.setOnClickListener {
|
binding.imageDelete.setOnClickListener {
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
.keepFullScreen()
|
.keepFullScreen()
|
||||||
.setTitle(R.string.warning)
|
.setTitle(R.string.warning)
|
||||||
@ -110,7 +113,7 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
.setMessage(getString(R.string.single_delete_confirm, fileName))
|
.setMessage(getString(R.string.single_delete_confirm, fileName))
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
image_button_slideshow.setOnClickListener {
|
binding.imageButtonSlideshow.setOnClickListener {
|
||||||
if (!slideshowActive){
|
if (!slideshowActive){
|
||||||
slideshowActive = true
|
slideshowActive = true
|
||||||
handler.postDelayed(slideshowNext, ConstValues.slideshow_delay)
|
handler.postDelayed(slideshowNext, ConstValues.slideshow_delay)
|
||||||
@ -121,23 +124,23 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
stopSlideshow()
|
stopSlideshow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image_previous.setOnClickListener {
|
binding.imagePrevious.setOnClickListener {
|
||||||
askSaveRotation {
|
askSaveRotation {
|
||||||
image_viewer.resetZoomFactor()
|
binding.imageViewer.resetZoomFactor()
|
||||||
swipeImage(1F)
|
swipeImage(1F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image_next.setOnClickListener {
|
binding.imageNext.setOnClickListener {
|
||||||
askSaveRotation {
|
askSaveRotation {
|
||||||
image_viewer.resetZoomFactor()
|
binding.imageViewer.resetZoomFactor()
|
||||||
swipeImage(-1F)
|
swipeImage(-1F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image_rotate_right.setOnClickListener {
|
binding.imageRotateRight.setOnClickListener {
|
||||||
rotationAngle += 90
|
rotationAngle += 90
|
||||||
rotateImage()
|
rotateImage()
|
||||||
}
|
}
|
||||||
image_rotate_left.setOnClickListener {
|
binding.imageRotateLeft.setOnClickListener {
|
||||||
rotationAngle -= 90
|
rotationAngle -= 90
|
||||||
rotateImage()
|
rotateImage()
|
||||||
}
|
}
|
||||||
@ -148,9 +151,9 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
private fun loadImage(){
|
private fun loadImage(){
|
||||||
loadWholeFile(filePath)?.let {
|
loadWholeFile(filePath)?.let {
|
||||||
glideImage = Glide.with(this).load(it)
|
glideImage = Glide.with(this).load(it)
|
||||||
glideImage.into(image_viewer)
|
glideImage.into(binding.imageViewer)
|
||||||
fileName = File(filePath).name
|
fileName = File(filePath).name
|
||||||
text_filename.text = fileName
|
binding.textFilename.text = fileName
|
||||||
rotationAngle = 0F
|
rotationAngle = 0F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,8 +204,8 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun rotateImage(){
|
private fun rotateImage(){
|
||||||
image_viewer.restoreZoomNormal()
|
binding.imageViewer.restoreZoomNormal()
|
||||||
glideImage.transform(RotateTransformation(this)).into(image_viewer)
|
glideImage.transform(RotateTransformation(this)).into(binding.imageViewer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun askSaveRotation(callback: () -> Unit){
|
private fun askSaveRotation(callback: () -> Unit){
|
||||||
@ -250,6 +253,6 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
image_viewer.restoreZoomNormal()
|
binding.imageViewer.restoreZoomNormal()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,22 +2,23 @@ package sushi.hardcore.droidfs.file_viewers
|
|||||||
|
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer
|
import com.google.android.exoplayer2.SimpleExoPlayer
|
||||||
import kotlinx.android.synthetic.main.activity_video_player.*
|
import sushi.hardcore.droidfs.databinding.ActivityVideoPlayerBinding
|
||||||
import sushi.hardcore.droidfs.R
|
|
||||||
|
|
||||||
|
|
||||||
class VideoPlayer: MediaPlayer() {
|
class VideoPlayer: MediaPlayer() {
|
||||||
private var firstPlay = true
|
private var firstPlay = true
|
||||||
private val autoFit by lazy {
|
private val autoFit by lazy {
|
||||||
sharedPrefs.getBoolean("autoFit", false)
|
sharedPrefs.getBoolean("autoFit", false)
|
||||||
}
|
}
|
||||||
|
private lateinit var binding: ActivityVideoPlayerBinding
|
||||||
|
|
||||||
override fun viewFile() {
|
override fun viewFile() {
|
||||||
setContentView(R.layout.activity_video_player)
|
binding = ActivityVideoPlayerBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
super.viewFile()
|
super.viewFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bindPlayer(player: SimpleExoPlayer) {
|
override fun bindPlayer(player: SimpleExoPlayer) {
|
||||||
video_player.player = player
|
binding.videoPlayer.player = player
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFileType(): String {
|
override fun getFileType(): String {
|
||||||
@ -26,7 +27,7 @@ class VideoPlayer: MediaPlayer() {
|
|||||||
|
|
||||||
override fun onPlayerReady() {
|
override fun onPlayerReady() {
|
||||||
if (firstPlay && autoFit) {
|
if (firstPlay && autoFit) {
|
||||||
requestedOrientation = if (video_player.width < video_player.height) ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
requestedOrientation = if (binding.videoPlayer.width < binding.videoPlayer.height) ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT else ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
||||||
firstPlay = false
|
firstPlay = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context="sushi.hardcore.droidfs.MainActivity">
|
tools:context="sushi.hardcore.droidfs.MainActivity">
|
||||||
|
|
||||||
<include layout="@layout/toolbar"/>
|
<include android:id="@+id/toolbar" layout="@layout/toolbar"/>
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredImageView
|
<sushi.hardcore.droidfs.widgets.ColoredImageView
|
||||||
android:id="@+id/image_logo"
|
android:id="@+id/image_logo"
|
||||||
|
Loading…
Reference in New Issue
Block a user