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