|
@ -1,3 +1,3 @@
|
|||
github: [tibbi]
|
||||
patreon: tiborkaputa
|
||||
custom: ["https://www.paypal.me/SimpleMobileTools", "https://www.simplemobiletools.com/donate"]
|
||||
custom: ["https://www.paypal.com/paypalme/simplemobiletools", "https://www.simplemobiletools.com/donate"]
|
||||
|
|
23
CHANGELOG.md
|
@ -1,6 +1,29 @@
|
|||
Changelog
|
||||
==========
|
||||
|
||||
Version 5.3.0 *(2020-11-05)*
|
||||
----------------------------
|
||||
|
||||
* Allow pausing the recording on Android 7+
|
||||
* Added some translation, UX and stability improvements
|
||||
|
||||
Version 5.2.1 *(2020-09-28)*
|
||||
----------------------------
|
||||
|
||||
* Allow picking between m4a and mp3 file extensions
|
||||
|
||||
Version 5.2.0 *(2020-09-19)*
|
||||
----------------------------
|
||||
|
||||
* Store recordings with proper m4a extension
|
||||
* Added some translation, stability and UX improvements
|
||||
|
||||
Version 5.1.3 *(2020-05-20)*
|
||||
----------------------------
|
||||
|
||||
* Allow sharing recordings
|
||||
* Added some UI and translation improvements
|
||||
|
||||
Version 5.1.2 *(2020-05-05)*
|
||||
----------------------------
|
||||
|
||||
|
|
|
@ -9,15 +9,14 @@ if (keystorePropertiesFile.exists()) {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion "29.0.3"
|
||||
compileSdkVersion 30
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.simplemobiletools.voicerecorder"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode 5
|
||||
versionName "5.1.2"
|
||||
targetSdkVersion 30
|
||||
versionCode 9
|
||||
versionName "5.3.0"
|
||||
setProperty("archivesBaseName", "voice-recorder")
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
|
@ -57,7 +56,10 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.simplemobiletools:commons:5.27.6'
|
||||
implementation 'com.simplemobiletools:commons:5.31.24'
|
||||
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||
implementation 'com.github.Armen101:AudioRecordView:1.0.2'
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
}
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
android:name=".activities.SplashActivity"
|
||||
android:theme="@style/SplashTheme" />
|
||||
|
||||
<activity android:name=".activities.MainActivity" />
|
||||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:launchMode="singleTask" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.SettingsActivity"
|
||||
|
@ -65,6 +67,7 @@
|
|||
<intent-filter>
|
||||
<action android:name="com.simplemobiletools.voicerecorder.action.GET_RECORDER_INFO" />
|
||||
<action android:name="com.simplemobiletools.voicerecorder.action.STOP_AMPLITUDE_UPDATE" />
|
||||
<action android:name="com.simplemobiletools.voicerecorder.action.TOGGLE_PAUSE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ class MainActivity : SimpleActivity() {
|
|||
view_pager.adapter = ViewPagerAdapter(this)
|
||||
view_pager.onPageChangeListener {
|
||||
main_tabs_holder.getTabAt(it)?.select()
|
||||
(view_pager.adapter as ViewPagerAdapter).finishActMode()
|
||||
}
|
||||
view_pager.currentItem = config.lastUsedViewPagerPage
|
||||
|
||||
|
@ -125,7 +126,8 @@ class MainActivity : SimpleActivity() {
|
|||
val faqItems = arrayListOf(
|
||||
FAQItem(R.string.faq_1_title, R.string.faq_1_text),
|
||||
FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons),
|
||||
FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons)
|
||||
FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons),
|
||||
FAQItem(R.string.faq_9_title_commons, R.string.faq_9_text_commons)
|
||||
)
|
||||
|
||||
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true)
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
package com.simplemobiletools.voicerecorder.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import com.simplemobiletools.commons.dialogs.ChangeDateTimeFormatDialog
|
||||
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.isQPlus
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import com.simplemobiletools.voicerecorder.R
|
||||
import com.simplemobiletools.voicerecorder.extensions.config
|
||||
import com.simplemobiletools.voicerecorder.helpers.EXTENSION_M4A
|
||||
import com.simplemobiletools.voicerecorder.helpers.EXTENSION_MP3
|
||||
import kotlinx.android.synthetic.main.activity_settings.*
|
||||
import java.util.*
|
||||
|
||||
|
@ -26,9 +31,15 @@ class SettingsActivity : SimpleActivity() {
|
|||
setupChangeDateTimeFormat()
|
||||
setupHideNotification()
|
||||
setupSaveRecordingsFolder()
|
||||
setupExtension()
|
||||
updateTextColors(settings_scrollview)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
updateMenuItemColors(menu)
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
private fun setupPurchaseThankYou() {
|
||||
settings_purchase_thank_you_holder.beVisibleIf(!isThankYouInstalled())
|
||||
settings_purchase_thank_you_holder.setOnClickListener {
|
||||
|
@ -81,4 +92,18 @@ class SettingsActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupExtension() {
|
||||
settings_extension.text = config.getExtensionText()
|
||||
settings_extension_holder.setOnClickListener {
|
||||
val items = arrayListOf(
|
||||
RadioItem(EXTENSION_M4A, getString(R.string.m4a)),
|
||||
RadioItem(EXTENSION_MP3, getString(R.string.mp3)))
|
||||
|
||||
RadioGroupDialog(this@SettingsActivity, items, config.extension) {
|
||||
config.extension = it as Int
|
||||
settings_extension.text = config.getExtensionText()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,11 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|||
import com.simplemobiletools.commons.helpers.isQPlus
|
||||
import com.simplemobiletools.commons.views.FastScroller
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.voicerecorder.BuildConfig
|
||||
import com.simplemobiletools.voicerecorder.R
|
||||
import com.simplemobiletools.voicerecorder.activities.SimpleActivity
|
||||
import com.simplemobiletools.voicerecorder.dialogs.RenameRecordingDialog
|
||||
import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri
|
||||
import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener
|
||||
import com.simplemobiletools.voicerecorder.models.Recording
|
||||
import kotlinx.android.synthetic.main.item_recording.view.*
|
||||
|
@ -47,7 +49,7 @@ class RecordingsAdapter(activity: SimpleActivity, var recordings: ArrayList<Reco
|
|||
|
||||
when (id) {
|
||||
R.id.cab_rename -> renameRecording()
|
||||
R.id.cab_select_all -> selectAll()
|
||||
R.id.cab_share -> shareRecordings()
|
||||
R.id.cab_delete -> askConfirmDelete()
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +97,17 @@ class RecordingsAdapter(activity: SimpleActivity, var recordings: ArrayList<Reco
|
|||
}
|
||||
}
|
||||
|
||||
private fun shareRecordings() {
|
||||
val selectedItems = getSelectedItems()
|
||||
val paths = if (isQPlus()) {
|
||||
selectedItems.map { getAudioFileContentUri(it.id.toLong()).toString() }
|
||||
} else {
|
||||
selectedItems.map { it.path }
|
||||
}
|
||||
|
||||
activity.sharePathsIntent(paths, BuildConfig.APPLICATION_ID)
|
||||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
val itemsCnt = selectedKeys.size
|
||||
val firstItem = getSelectedItems().first()
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.viewpager.widget.PagerAdapter
|
|||
import com.simplemobiletools.voicerecorder.R
|
||||
import com.simplemobiletools.voicerecorder.activities.SimpleActivity
|
||||
import com.simplemobiletools.voicerecorder.fragments.MyViewPagerFragment
|
||||
import com.simplemobiletools.voicerecorder.fragments.PlayerFragment
|
||||
|
||||
class ViewPagerAdapter(private val activity: SimpleActivity) : PagerAdapter() {
|
||||
private val mFragments = SparseArray<MyViewPagerFragment>()
|
||||
|
@ -40,4 +41,6 @@ class ViewPagerAdapter(private val activity: SimpleActivity) : PagerAdapter() {
|
|||
mFragments[i].onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
fun finishActMode() = (mFragments[1] as? PlayerFragment)?.finishActMode()
|
||||
}
|
||||
|
|
|
@ -63,7 +63,11 @@ class RenameRecordingDialog(val activity: BaseSimpleActivity, val recording: Rec
|
|||
put(Media.DISPLAY_NAME, newDisplayName)
|
||||
}
|
||||
|
||||
activity.contentResolver.update(getAudioFileContentUri(recording.id.toLong()), values, null, null)
|
||||
try {
|
||||
activity.contentResolver.update(getAudioFileContentUri(recording.id.toLong()), values, null, null)
|
||||
} catch (e: Exception) {
|
||||
activity.showErrorToast(e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLegacyFilename(recording: Recording, newTitle: String) {
|
||||
|
|
|
@ -2,9 +2,9 @@ package com.simplemobiletools.voicerecorder.fragments
|
|||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
||||
abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : RelativeLayout(context, attributeSet) {
|
||||
abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : ConstraintLayout(context, attributeSet) {
|
||||
abstract fun onResume()
|
||||
|
||||
abstract fun onDestroy()
|
||||
|
|
|
@ -42,7 +42,7 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
|
||||
override fun onResume() {
|
||||
setupColors()
|
||||
if (!prevSavePath.isEmpty() && context!!.config.saveRecordingsFolder != prevSavePath) {
|
||||
if (prevSavePath.isNotEmpty() && context!!.config.saveRecordingsFolder != prevSavePath) {
|
||||
setupAdapter()
|
||||
} else {
|
||||
getRecordingsAdapter()?.updateTextColor(context.config.textColor)
|
||||
|
@ -227,7 +227,7 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
return try {
|
||||
val retriever = MediaMetadataRetriever()
|
||||
retriever.setDataSource(context, getAudioFileContentUri(id))
|
||||
val time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
|
||||
val time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)!!
|
||||
Math.round(time.toLong() / 1000.toDouble())
|
||||
} catch (e: Exception) {
|
||||
0L
|
||||
|
@ -269,13 +269,23 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
player!!.apply {
|
||||
reset()
|
||||
|
||||
if (isQPlus()) {
|
||||
setDataSource(context, getAudioFileContentUri(recording.id.toLong()))
|
||||
} else {
|
||||
setDataSource(recording.path)
|
||||
try {
|
||||
if (isQPlus()) {
|
||||
setDataSource(context, getAudioFileContentUri(recording.id.toLong()))
|
||||
} else {
|
||||
setDataSource(recording.path)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
context?.showErrorToast(e)
|
||||
return
|
||||
}
|
||||
|
||||
prepareAsync()
|
||||
try {
|
||||
prepareAsync()
|
||||
} catch (e: Exception) {
|
||||
context.showErrorToast(e)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
play_pause_btn.setImageDrawable(getToggleButtonIcon(true))
|
||||
|
@ -386,6 +396,8 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
play_pause_btn.setImageDrawable(getToggleButtonIcon(false))
|
||||
}
|
||||
|
||||
fun finishActMode() = getRecordingsAdapter()?.finishActMode()
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun recordingCompleted(event: Events.RecordingCompleted) {
|
||||
refreshRecordings()
|
||||
|
|
|
@ -3,20 +3,25 @@ package com.simplemobiletools.voicerecorder.fragments
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.AttributeSet
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.isNougatPlus
|
||||
import com.simplemobiletools.voicerecorder.R
|
||||
import com.simplemobiletools.voicerecorder.extensions.config
|
||||
import com.simplemobiletools.voicerecorder.helpers.GET_RECORDER_INFO
|
||||
import com.simplemobiletools.voicerecorder.helpers.*
|
||||
import com.simplemobiletools.voicerecorder.models.Events
|
||||
import com.simplemobiletools.voicerecorder.services.RecorderService
|
||||
import kotlinx.android.synthetic.main.fragment_recorder.view.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import java.util.*
|
||||
|
||||
class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
|
||||
private var isRecording = false
|
||||
private var status = RECORDING_STOPPED
|
||||
private var pauseBlinkTimer = Timer()
|
||||
private var bus: EventBus? = null
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -25,6 +30,7 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
|
|||
|
||||
override fun onDestroy() {
|
||||
bus?.unregister(this)
|
||||
pauseBlinkTimer.cancel()
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
|
@ -39,6 +45,13 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
|
|||
toggleRecording()
|
||||
}
|
||||
|
||||
toggle_pause_button.setOnClickListener {
|
||||
Intent(context, RecorderService::class.java).apply {
|
||||
action = TOGGLE_PAUSE
|
||||
context.startService(this)
|
||||
}
|
||||
}
|
||||
|
||||
Intent(context, RecorderService::class.java).apply {
|
||||
action = GET_RECORDER_INFO
|
||||
context.startService(this)
|
||||
|
@ -52,6 +65,11 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
|
|||
background.applyColorFilter(adjustedPrimaryColor)
|
||||
}
|
||||
|
||||
toggle_pause_button.apply {
|
||||
setImageDrawable(resources.getColoredDrawableWithColor(R.drawable.ic_pause_vector, context.getFABIconColor()))
|
||||
background.applyColorFilter(adjustedPrimaryColor)
|
||||
}
|
||||
|
||||
recorder_visualizer.chunkColor = adjustedPrimaryColor
|
||||
recording_duration.setTextColor(context.config.textColor)
|
||||
}
|
||||
|
@ -61,17 +79,23 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
|
|||
}
|
||||
|
||||
private fun getToggleButtonIcon(): Drawable {
|
||||
val drawable = if (isRecording) R.drawable.ic_stop_vector else R.drawable.ic_microphone_vector
|
||||
val drawable = if (status == RECORDING_RUNNING || status == RECORDING_PAUSED) R.drawable.ic_stop_vector else R.drawable.ic_microphone_vector
|
||||
return resources.getColoredDrawableWithColor(drawable, context.getFABIconColor())
|
||||
}
|
||||
|
||||
private fun toggleRecording() {
|
||||
isRecording = !isRecording
|
||||
status = if (status == RECORDING_RUNNING || status == RECORDING_PAUSED) {
|
||||
RECORDING_STOPPED
|
||||
} else {
|
||||
RECORDING_RUNNING
|
||||
}
|
||||
|
||||
toggle_recording_button.setImageDrawable(getToggleButtonIcon())
|
||||
|
||||
if (isRecording) {
|
||||
if (status == RECORDING_RUNNING) {
|
||||
startRecording()
|
||||
} else {
|
||||
toggle_pause_button.beGone()
|
||||
stopRecording()
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +104,7 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
|
|||
Intent(context, RecorderService::class.java).apply {
|
||||
context.startService(this)
|
||||
}
|
||||
recorder_visualizer.recreate()
|
||||
}
|
||||
|
||||
private fun stopRecording() {
|
||||
|
@ -88,6 +113,17 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
|
|||
}
|
||||
}
|
||||
|
||||
private fun getPauseBlinkTask() = object : TimerTask() {
|
||||
override fun run() {
|
||||
if (status == RECORDING_PAUSED) {
|
||||
// update just the alpha so that it will always be clickable
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
toggle_pause_button.alpha = if (toggle_pause_button.alpha == 0f) 1f else 0f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun gotDurationEvent(event: Events.RecordingDuration) {
|
||||
updateRecordingDuration(event.duration)
|
||||
|
@ -95,16 +131,26 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
|
|||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun gotStatusEvent(event: Events.RecordingStatus) {
|
||||
isRecording = event.isRecording
|
||||
status = event.status
|
||||
toggle_recording_button.setImageDrawable(getToggleButtonIcon())
|
||||
if (isRecording) {
|
||||
recorder_visualizer.recreate()
|
||||
toggle_pause_button.beVisibleIf(status != RECORDING_STOPPED && isNougatPlus())
|
||||
if (status == RECORDING_PAUSED) {
|
||||
pauseBlinkTimer = Timer()
|
||||
pauseBlinkTimer.scheduleAtFixedRate(getPauseBlinkTask(), 500, 500)
|
||||
} else {
|
||||
pauseBlinkTimer.cancel()
|
||||
}
|
||||
|
||||
if (status == RECORDING_RUNNING) {
|
||||
toggle_pause_button.alpha = 1f
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun gotAmplitudeEvent(event: Events.RecordingAmplitude) {
|
||||
val amplitude = event.amplitude
|
||||
recorder_visualizer.update(amplitude)
|
||||
if (status == RECORDING_RUNNING) {
|
||||
recorder_visualizer.update(amplitude)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,4 +16,13 @@ class Config(context: Context) : BaseConfig(context) {
|
|||
var saveRecordingsFolder: String
|
||||
get() = prefs.getString(SAVE_RECORDINGS, "$internalStoragePath/${context.getString(R.string.app_name)}")!!
|
||||
set(saveRecordingsFolder) = prefs.edit().putString(SAVE_RECORDINGS, saveRecordingsFolder).apply()
|
||||
|
||||
var extension: Int
|
||||
get() = prefs.getInt(EXTENSION, EXTENSION_M4A)
|
||||
set(extension) = prefs.edit().putInt(EXTENSION, extension).apply()
|
||||
|
||||
fun getExtensionText() = context.getString(when (extension) {
|
||||
EXTENSION_M4A -> R.string.m4a
|
||||
else -> R.string.mp3
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,10 +12,19 @@ const val RECORDER_RUNNING_NOTIF_ID = 10000
|
|||
private const val PATH = "com.simplemobiletools.voicerecorder.action."
|
||||
const val GET_RECORDER_INFO = PATH + "GET_RECORDER_INFO"
|
||||
const val STOP_AMPLITUDE_UPDATE = PATH + "STOP_AMPLITUDE_UPDATE"
|
||||
const val TOGGLE_PAUSE = PATH + "TOGGLE_PAUSE"
|
||||
|
||||
const val EXTENSION_M4A = 0
|
||||
const val EXTENSION_MP3 = 1
|
||||
|
||||
const val RECORDING_RUNNING = 0
|
||||
const val RECORDING_STOPPED = 1
|
||||
const val RECORDING_PAUSED = 2
|
||||
|
||||
// shared preferences
|
||||
const val HIDE_NOTIFICATION = "hide_notification"
|
||||
const val SAVE_RECORDINGS = "save_recordings"
|
||||
const val EXTENSION = "extension"
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
fun getAudioFileContentUri(id: Long): Uri {
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.simplemobiletools.voicerecorder.models
|
|||
|
||||
class Events {
|
||||
class RecordingDuration internal constructor(val duration: Int)
|
||||
class RecordingStatus internal constructor(val isRecording: Boolean)
|
||||
class RecordingStatus internal constructor(val status: Int)
|
||||
class RecordingAmplitude internal constructor(val amplitude: Int)
|
||||
class RecordingCompleted internal constructor()
|
||||
}
|
||||
|
|
|
@ -21,9 +21,7 @@ import com.simplemobiletools.commons.helpers.isQPlus
|
|||
import com.simplemobiletools.voicerecorder.R
|
||||
import com.simplemobiletools.voicerecorder.activities.SplashActivity
|
||||
import com.simplemobiletools.voicerecorder.extensions.config
|
||||
import com.simplemobiletools.voicerecorder.helpers.GET_RECORDER_INFO
|
||||
import com.simplemobiletools.voicerecorder.helpers.RECORDER_RUNNING_NOTIF_ID
|
||||
import com.simplemobiletools.voicerecorder.helpers.STOP_AMPLITUDE_UPDATE
|
||||
import com.simplemobiletools.voicerecorder.helpers.*
|
||||
import com.simplemobiletools.voicerecorder.models.Events
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.io.File
|
||||
|
@ -34,7 +32,7 @@ class RecorderService : Service() {
|
|||
|
||||
private var currFilePath = ""
|
||||
private var duration = 0
|
||||
private var isRecording = false
|
||||
private var status = RECORDING_STOPPED
|
||||
private var durationTimer = Timer()
|
||||
private var amplitudeTimer = Timer()
|
||||
private var recorder: MediaRecorder? = null
|
||||
|
@ -47,6 +45,7 @@ class RecorderService : Service() {
|
|||
when (intent.action) {
|
||||
GET_RECORDER_INFO -> broadcastRecorderInfo()
|
||||
STOP_AMPLITUDE_UPDATE -> amplitudeTimer.cancel()
|
||||
TOGGLE_PAUSE -> togglePause()
|
||||
else -> startRecording()
|
||||
}
|
||||
|
||||
|
@ -58,7 +57,7 @@ class RecorderService : Service() {
|
|||
stopRecording()
|
||||
}
|
||||
|
||||
// mp4 output format with aac encoding should produce good enough mp3 files according to https://stackoverflow.com/a/33054794/1967672
|
||||
// mp4 output format with aac encoding should produce good enough m4a files according to https://stackoverflow.com/a/33054794/1967672
|
||||
private fun startRecording() {
|
||||
val baseFolder = if (isQPlus()) {
|
||||
cacheDir
|
||||
|
@ -71,7 +70,7 @@ class RecorderService : Service() {
|
|||
defaultFolder.absolutePath
|
||||
}
|
||||
|
||||
currFilePath = "$baseFolder/${getCurrentFormattedDateTime()}.mp3"
|
||||
currFilePath = "$baseFolder/${getCurrentFormattedDateTime()}.${config.getExtensionText()}"
|
||||
recorder = MediaRecorder().apply {
|
||||
setAudioSource(MediaRecorder.AudioSource.CAMCORDER)
|
||||
setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
|
||||
|
@ -93,7 +92,7 @@ class RecorderService : Service() {
|
|||
prepare()
|
||||
start()
|
||||
duration = 0
|
||||
isRecording = true
|
||||
status = RECORDING_RUNNING
|
||||
broadcastRecorderInfo()
|
||||
startForeground(RECORDER_RUNNING_NOTIF_ID, showNotification())
|
||||
|
||||
|
@ -111,7 +110,7 @@ class RecorderService : Service() {
|
|||
private fun stopRecording() {
|
||||
durationTimer.cancel()
|
||||
amplitudeTimer.cancel()
|
||||
isRecording = false
|
||||
status = RECORDING_STOPPED
|
||||
|
||||
recorder?.apply {
|
||||
try {
|
||||
|
@ -136,10 +135,7 @@ class RecorderService : Service() {
|
|||
private fun broadcastRecorderInfo() {
|
||||
broadcastDuration()
|
||||
broadcastStatus()
|
||||
|
||||
if (isRecording) {
|
||||
startAmplitudeUpdates()
|
||||
}
|
||||
startAmplitudeUpdates()
|
||||
}
|
||||
|
||||
private fun startAmplitudeUpdates() {
|
||||
|
@ -148,6 +144,23 @@ class RecorderService : Service() {
|
|||
amplitudeTimer.scheduleAtFixedRate(getAmplitudeUpdateTask(), 0, AMPLITUDE_UPDATE_MS)
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun togglePause() {
|
||||
try {
|
||||
if (status == RECORDING_RUNNING) {
|
||||
recorder?.pause()
|
||||
status = RECORDING_PAUSED
|
||||
} else if (status == RECORDING_PAUSED) {
|
||||
recorder?.resume()
|
||||
status = RECORDING_RUNNING
|
||||
}
|
||||
broadcastStatus()
|
||||
startForeground(RECORDER_RUNNING_NOTIF_ID, showNotification())
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
private fun addFileInNewMediaStore() {
|
||||
val audioCollection = Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
||||
|
@ -187,15 +200,20 @@ class RecorderService : Service() {
|
|||
|
||||
private fun getDurationUpdateTask() = object : TimerTask() {
|
||||
override fun run() {
|
||||
duration++
|
||||
broadcastDuration()
|
||||
if (status == RECORDING_RUNNING) {
|
||||
duration++
|
||||
broadcastDuration()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAmplitudeUpdateTask() = object : TimerTask() {
|
||||
override fun run() {
|
||||
if (recorder != null) {
|
||||
EventBus.getDefault().post(Events.RecordingAmplitude(recorder!!.maxAmplitude))
|
||||
try {
|
||||
EventBus.getDefault().post(Events.RecordingAmplitude(recorder!!.maxAmplitude))
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,8 +235,11 @@ class RecorderService : Service() {
|
|||
var priority = Notification.PRIORITY_DEFAULT
|
||||
var icon = R.drawable.ic_microphone_vector
|
||||
var title = label
|
||||
var text = getString(R.string.recording)
|
||||
var visibility = NotificationCompat.VISIBILITY_PUBLIC
|
||||
var text = getString(R.string.recording)
|
||||
if (status == RECORDING_PAUSED) {
|
||||
text += " (${getString(R.string.paused)})"
|
||||
}
|
||||
|
||||
if (hideNotification) {
|
||||
priority = Notification.PRIORITY_MIN
|
||||
|
@ -253,6 +274,6 @@ class RecorderService : Service() {
|
|||
}
|
||||
|
||||
private fun broadcastStatus() {
|
||||
EventBus.getDefault().post(Events.RecordingStatus(isRecording))
|
||||
EventBus.getDefault().post(Events.RecordingStatus(status))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,5 +153,37 @@
|
|||
android:maxLines="3" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_extension_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:paddingLeft="@dimen/normal_margin"
|
||||
android:paddingTop="@dimen/bigger_margin"
|
||||
android:paddingRight="@dimen/normal_margin"
|
||||
android:paddingBottom="@dimen/bigger_margin">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_extension_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@+id/settings_extension"
|
||||
android:paddingLeft="@dimen/medium_margin"
|
||||
android:paddingRight="@dimen/medium_margin"
|
||||
android:text="@string/extension" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_extension"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginEnd="@dimen/small_margin"
|
||||
android:background="@null"
|
||||
android:clickable="false" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
android:id="@+id/recordings_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:alpha="0.8"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="@dimen/small_margin"
|
||||
|
@ -23,20 +22,21 @@
|
|||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/recordings_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/player_controls_wrapper"
|
||||
android:layout_height="0dp"
|
||||
android:clipToPadding="false"
|
||||
android:scrollbars="none"
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager" />
|
||||
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"
|
||||
app:layout_constraintBottom_toTopOf="@+id/player_controls_wrapper"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.simplemobiletools.commons.views.FastScroller
|
||||
android:id="@+id/recordings_fastscroller"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignTop="@+id/recordings_list"
|
||||
android:layout_alignBottom="@+id/recordings_list"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:paddingStart="@dimen/normal_margin">
|
||||
android:layout_height="0dp"
|
||||
android:paddingStart="@dimen/normal_margin"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/recordings_list"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/recordings_list">
|
||||
|
||||
<include layout="@layout/fastscroller_handle_vertical" />
|
||||
|
||||
|
@ -46,7 +46,8 @@
|
|||
android:id="@+id/player_controls_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<View
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
<com.visualizer.amplitude.AudioRecordView
|
||||
android:id="@+id/recorder_visualizer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/recording_duration"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="@dimen/big_margin"
|
||||
android:background="@drawable/frame_background"
|
||||
app:chunkAlignTo="center"
|
||||
|
@ -19,28 +18,46 @@
|
|||
app:chunkRoundedCorners="true"
|
||||
app:chunkSoftTransition="true"
|
||||
app:chunkSpace="1dp"
|
||||
app:chunkWidth="3dp" />
|
||||
app:chunkWidth="3dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/recording_duration"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/recording_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/toggle_recording_button"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/bigger_margin"
|
||||
android:textSize="@dimen/extra_big_text_size"
|
||||
app:layout_constraintBottom_toTopOf="@+id/toggle_recording_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:text="00:00" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/toggle_recording_button"
|
||||
android:layout_width="@dimen/toggle_recording_button_size"
|
||||
android:layout_height="@dimen/toggle_recording_button_size"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/big_margin"
|
||||
android:background="@drawable/circle_background"
|
||||
android:elevation="@dimen/medium_margin"
|
||||
android:padding="@dimen/normal_margin"
|
||||
android:src="@drawable/ic_microphone_vector" />
|
||||
android:src="@drawable/ic_microphone_vector"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/toggle_pause_button"
|
||||
android:layout_width="@dimen/fab_size"
|
||||
android:layout_height="@dimen/fab_size"
|
||||
android:layout_marginBottom="@dimen/big_margin"
|
||||
android:background="@drawable/circle_background"
|
||||
android:elevation="@dimen/medium_margin"
|
||||
android:padding="@dimen/activity_margin"
|
||||
android:src="@drawable/ic_pause_vector"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/toggle_recording_button" />
|
||||
|
||||
</com.simplemobiletools.voicerecorder.fragments.RecorderFragment>
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
android:title="@string/rename"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/cab_select_all"
|
||||
android:icon="@drawable/ic_select_all_vector"
|
||||
android:title="@string/select_all"
|
||||
android:id="@+id/cab_share"
|
||||
android:icon="@drawable/ic_share_vector"
|
||||
android:title="@string/share"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/cab_delete"
|
||||
|
|
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 8.1 KiB |
|
@ -0,0 +1,54 @@
|
|||
<resources>
|
||||
<string name="app_name">Schlichtes Diktiergerät</string>
|
||||
<string name="app_launcher_name">Diktiergerät</string>
|
||||
<string name="recording_saved_successfully">Aufnahme erfolgreich gespeichert als \n\"%s\"</string>
|
||||
<string name="recording">Aufnehmen</string>
|
||||
<string name="no_recordings_found">Es wurden keine von dieser App\nerstellten Aufnahmen gefunden</string>
|
||||
<string name="no_recordings_in_folder_found">Es wurden keine Aufnahmen\nim ausgewählten Ordner gefunden</string>
|
||||
<string name="paused">Pausieren</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Bist du sicher, dass du %s löschen möchtest?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
<plurals name="delete_recordings">
|
||||
<item quantity="one">%d Aufnahme</item>
|
||||
<item quantity="other">%d Aufnahmen</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="try_hiding_notification">Versuche die Aufnahmebenachrichtigung auszublenden</string>
|
||||
<string name="save_recordings_in">Speichere Aufnahme in</string>
|
||||
|
||||
<!-- FAQ -->
|
||||
<string name="faq_1_title">Kann ich das Benachrichtigungssymbol während der Aufnahme ausblenden?</string>
|
||||
<string name="faq_1_text">Naja, das kommt darauf an. Während der Nutzung des Geräts ist es nicht mehr möglich, die Benachrichtigungen von Apps wie dieser vollständig auszublenden.
|
||||
Wenn du die Option in den Einstellungen aktivierst, wird die App ihr Bestes tun, es auszublenden. Du kannst es jedoch auf dem Sperrbildschirm ausblenden, indem du die Anzeige vertraulicher Benachrichtigungen in den Geräteeinstellungen verbietest.</string>
|
||||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
|
||||
<string name="app_title">Schlichtes Diktiergerät - Tonaufnahmen einfach</string>
|
||||
<!-- Short description has to have less than 80 chars -->
|
||||
<string name="app_short_description">Ein simpler Weg, Diskussionen oder Töne ohne Werbung und Internet aufzuzeichnen</string>
|
||||
<string name="app_long_description">
|
||||
Wolltest du dich schon immer mal erinnern, was die andere Person gesagt hat? Oder an die Aufgabe, die dir beim letzten Meeting gegeben wurde? Mit diesem simplen Diktiergerät kannst du jederzeit, schnell und problemlos Aufnahmen tätigen.
|
||||
|
||||
Die App erfüllt ihren Zweck, enthält keine ausgefallenen Funktionen, die du eh nie benutzen würdest. Nur du und das Diktiergerät. Es zeigt die aktuelle Lautstärke anhand eines schön gestalteten Pegelausschlags an. Du wirst damit viel Spaß haben. Zudem bietet sie eine intuitive und übersichtliche Benutzeroberfläche, da kann nicht viel schief gehen.
|
||||
|
||||
Es bietet zudem einen hilfreichen Player, mit dem die Aufnahmen direkt angehört, nach Bedarf umbenannt oder gelöscht werden können.
|
||||
|
||||
Die App enthält keine Werbung und verlangt keine unnötigen Berechtigungen. Sie ist vollständig OpenSource und bietet anpassbare Farben.
|
||||
|
||||
<b>Schau dir hier die vollständige Serie der Schlichten Apps an:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
||||
</string>
|
||||
|
||||
<!--
|
||||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
|
@ -0,0 +1,54 @@
|
|||
<resources>
|
||||
<string name="app_name">Απλή Εγγραφή Φωνής</string>
|
||||
<string name="app_launcher_name">Εγγραφή Φωνής</string>
|
||||
<string name="recording_saved_successfully">Η εγγραφή αποθηκεύτηκε με επιτυχία ως\n\"%s\"</string>
|
||||
<string name="recording">Εγγραφή</string>
|
||||
<string name="no_recordings_found">Δεν βρέθηκαν εγγραφές που δημιουργήθηκαν\n από αυτήν την εφαρμογή</string>
|
||||
<string name="no_recordings_in_folder_found">Δεν βρέθηκαν εγγραφές\nστον επιλεγμένο φάκελο</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Είστε βέβαιοι ότι θέλετε να διαγράψετε τις %s;</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
<plurals name="delete_recordings">
|
||||
<item quantity="one">%d εγγραφή</item>
|
||||
<item quantity="other">%d εγγραφές</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="try_hiding_notification">Δοκιμάστε να αποκρύψετε την ειδοποίηση εγγραφής</string>
|
||||
<string name="save_recordings_in">Αποθήκευση εγγραφών σε</string>
|
||||
|
||||
<!-- FAQ -->
|
||||
<string name="faq_1_title">Μπορώ να αποκρύψω το εικονίδιο ειδοποίησης κατά την εγγραφή;</string>
|
||||
<string name="faq_1_text">Εξαρτάται. Ενώ χρησιμοποιείτε τη συσκευή σας, δεν είναι πλέον δυνατή η πλήρης απόκρυψη των ειδοποιήσεων εφαρμογών όπως αυτή.
|
||||
Εάν ελέγξετε το κατάλληλο στοιχείο ρύθμισης, η εφαρμογή θα κάνει ό,τι μπορεί για να το αποκρύψει. Ωστόσο, μπορείτε να την αποκρύψετε στην οθόνη κλειδώματος, αν απενεργοποιήσετε την εμφάνιση ευαίσθητων ειδοποιήσεων στις ρυθμίσεις της συσκευής σας.</string>
|
||||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
|
||||
<string name="app_title">Απλή Εγγραφή Φωνής - Ηχογραφήστε εύκολα οτιδήποτε</string>
|
||||
<!-- Short description has to have less than 80 chars -->
|
||||
<string name="app_short_description">Έύκολη καταγραφή οτιδήποτε ήχου χωρίς διαφημίσεις ή πρόσβαση στο διαδίκτυο</string>
|
||||
<string name="app_long_description">
|
||||
Ευχήθηκες ποτέ να θυμάσαι τι είπε ο άλλος; Ή την εργασία που σου έδωσαν σε μια συνάντηση; Δεν θα εύχεστε άλλο. Με αυτή την απλή καταγραφή μπορείτε να ηχογραφήσετε οποιονδήποτε ήχο πολύ γρήγορα.
|
||||
|
||||
Η εφαρμογή πηγαίνει κατευθείαν στο θέμα, δεν περιέχει φανταχτερά χαρακτηριστικά που δεν θα χρησιμοποιήσετε. Μόνο εσύ και ο καταγραφέας φωνής. Δείχνει την τρέχουσα ηχητική ένταση σε μια ωραία απεικόνιση. Παρέχει ένα πραγματικά διαισθητικό και καθαρό περιβάλλον εργασίας χρήστη, δεν μπορούν να πάνε πολλά στραβά εκεί.
|
||||
|
||||
Προσφέρει επίσης έναν χρήσιμο player, ώστε να μπορείτε να ακούσετε τις εγγραφές σας γρήγορα, ίσως να τις μετονομάσετε ή να τις διαγράψετε.
|
||||
|
||||
Δεν περιέχει διαφημίσεις ή περιττά δικαιώματα. Είναι πλήρως ανοιχτού κώδικα, παρέχει προσαρμόσιμα χρώματα.
|
||||
|
||||
<b>Δείτε την πλήρη σειρά των Απλών εργαλείων εδώ:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
||||
</string>
|
||||
|
||||
<!--
|
||||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
|
@ -0,0 +1,54 @@
|
|||
<resources>
|
||||
<string name="app_name">Grabadora de voz Simple</string>
|
||||
<string name="app_launcher_name">Grabadora de voz</string>
|
||||
<string name="recording_saved_successfully">Grabación guardada exitosamente como\n\"%s\"</string>
|
||||
<string name="recording">Grabando</string>
|
||||
<string name="no_recordings_found">No se han encontrado grabaciones\ncreadas por esta app</string>
|
||||
<string name="no_recordings_in_folder_found">No se han encontrado grabaciones\nen la carpeta seleccionada</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">¿Estás seguro que quieres eliminar %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
<plurals name="delete_recordings">
|
||||
<item quantity="one">%d grabación</item>
|
||||
<item quantity="other">%d grabaciones</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="try_hiding_notification">Tratar de ocultar la notificación de grabación</string>
|
||||
<string name="save_recordings_in">Guardar grabaciones en</string>
|
||||
|
||||
<!-- FAQ -->
|
||||
<string name="faq_1_title">¿Puedo ocultar el ícono de notificación durante la grabación?</string>
|
||||
<string name="faq_1_text">Bueno, depende. Ya no es posible ocultar completamente las notificacioes de aplicaciones como esta mientras usas tu dispositivo.
|
||||
Si activas el ajuste correspondiente, la aplicación hará todo lo posible para ocultarla. También puedes ocultarla en la pantalla de bloqueo, si desactivas el mostrar contenido sensible en los ajustes de tu dispositivo.</string>
|
||||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
|
||||
<string name="app_title">Grabadora de voz Simple - Graba audio facilmente</string>
|
||||
<!-- Short description has to have less than 80 chars -->
|
||||
<string name="app_short_description">Una forma fácil de grabar cualquier sonido sin anuncios o acceso a internet</string>
|
||||
<string name="app_long_description">
|
||||
¿Alguna vez deseaste recordar lo que otra persona dijo? ¿O la tarea que te asignaron en una reunión? No desees más. Con esta grabadora simple puedes grabar cualquier audio realmente rápido.
|
||||
|
||||
La aplicación va directo al punto, no contiene características lujosas que no vas a usar. Solo tú y la grabadora de voz. Muestra el volumen del sonido actual de una forma con la que puedes tener un montón de diversión. Provee una interfaz de usuario realmente intuitiva y limpia, no hay mucho que pueda ir mal aquí.
|
||||
|
||||
También ofrece un útil reproductor, así que puedes escuchar tus grabaciones rapidamente, y quizá renombrarlas o eliminarlas.
|
||||
|
||||
No contiene anuncios o permisos innecesarios. Es completamente de código abierto, provee colores personalizables.
|
||||
|
||||
<b>Mira la suite completa de herramientas Simples aquí:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
||||
</string>
|
||||
|
||||
<!--
|
||||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
|
@ -0,0 +1,52 @@
|
|||
<resources>
|
||||
<string name="app_name">Simple Voice Recorder</string>
|
||||
<string name="app_launcher_name">Gravador de voz</string>
|
||||
<string name="recording_saved_successfully">Gravación gardada como\n\"%s\"</string>
|
||||
<string name="recording">Gravación</string>
|
||||
<string name="no_recordings_found">Non foron atopadas gravacións\ncreadas por este aplicativo</string>
|
||||
<string name="no_recordings_in_folder_found">Non foron atopados gravacións\nno cartafol seleccionado</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Ten a certeza de que desexa eliminar %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
<plurals name="delete_recordings">
|
||||
<item quantity="one">%d gravación</item>
|
||||
<item quantity="other">%d gravacións</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="try_hiding_notification">Intentar ocultar a notificación da gravación</string>
|
||||
<string name="save_recordings_in">Gardar gravacións en</string>
|
||||
|
||||
<!-- FAQ -->
|
||||
<string name="faq_1_title">Podo agochar a icona da notificación mentres estou gravando?</string>
|
||||
<string name="faq_1_text">Ben, depende. Mentres uses o teu dispositivo, non será posible agochar enteiramente as notificacións como as deste aplicativo. Se revisas os axustes deste elemento, o aplicativo intentará agochalo. Si que o podes agochar da pantalla de bloqueo, se o desactivas o amosador das notificacións sensibles nos axustes do teu dispositivo.
|
||||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
|
||||
<string name="app_title">Simple Voice Recorder - Record any audio easily</string>
|
||||
<!-- Short description has to have less than 80 chars -->
|
||||
<string name="app_short_description">An easy way of recording any discussion or audio sounds without ads</string>
|
||||
<string name="app_long_description">
|
||||
Algunha vez desexou gravar o que dixo a outra persoa? Ou a tarefa que lle deron nunha reunión? Non desexes máis. Con esta sinxela gravadora podes gravar calquera audio moi rápido.
|
||||
|
||||
O aplicativo non contén funcións de fantasía que non usarás. Mostra o volume de son cunha boa visualización. Ofrece unha interface de usuario moi intuitiva e clara.
|
||||
|
||||
Tamén ofrece un reprodutor útil para que poidas escoitar as túas gravacións rapidamente e tamén renomealas ou eliminalas.
|
||||
|
||||
Non contén anuncios nin permisos innecesarios. É totalmente de código aberto e ofrece cores personalizables.
|
||||
|
||||
<b>Consulta o conxunto completo de aplicativos Simple Tools aquí:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
||||
</string>
|
||||
|
||||
<!--
|
||||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
|
@ -5,6 +5,7 @@
|
|||
<string name="recording">Įrašoma</string>
|
||||
<string name="no_recordings_found">Nerasta įrašų įrašytų su šia programėle\nbuvo rasta</string>
|
||||
<string name="no_recordings_in_folder_found">Nerasta įrašų\pasirinktame aplanke</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Ar tikrai norite ištrinti %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<resources>
|
||||
<string name="app_name">Eenvoudige Voicerecorder</string>
|
||||
<string name="app_launcher_name">Voicerecorder</string>
|
||||
<string name="recording_saved_successfully">Opname opgeslagen als\n\"%s\"</string>
|
||||
<string name="recording">Opnemen</string>
|
||||
<string name="no_recordings_found">Geen opnames door deze app gevonden</string>
|
||||
<string name="no_recordings_in_folder_found">Geen opnames gevonden in de gekozen map</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">De volgende opname verwijderen? %s</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
<plurals name="delete_recordings">
|
||||
<item quantity="one">%d opname</item>
|
||||
<item quantity="other">%d opnames</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="try_hiding_notification">Tijdens de opname proberen de notificatie te verbergen</string>
|
||||
<string name="save_recordings_in">Opnames opslaan in</string>
|
||||
|
||||
<!-- FAQ -->
|
||||
<string name="faq_1_title">Kan ik de notificatie tijdens het opnemen verbergen?</string>
|
||||
<string name="faq_1_text">Dat ligt eraan. Tijdens het gebruik is het niet langer mogelijk in Android om notificaties van dit soort apps volledig te verbergen.
|
||||
De app bevat wel een instelling waarmee er toch zal worden geprobeerd om dit te bewerkstelligen. In de schermvergrendeling kan de notificatie w<>l worden verborgen door het tonen van gevoelige notificaties in de apparaatinstellingen uit te schakelen.</string>
|
||||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
|
||||
<string name="app_title">Eenvoudige Voicerecorder - Snel geluid opnemen</string>
|
||||
<!-- Short description has to have less than 80 chars -->
|
||||
<string name="app_short_description">Een makkelijke manier om discussies of geluiden op te nemen, zonder advertenties</string>
|
||||
<string name="app_long_description">
|
||||
Ooit gedacht "had ik dat gesprek maar opgenomen"? Welke briljante opmerking iemand maakte? Welke taken in een vergadering werden uitgedeeld? Met deze simpele voicerecorder zijn heel gemakkelijk opnames te maken.
|
||||
|
||||
De app is komt direct ter zake en bevat geen onnodige franjes. Het toont Het toont het huidige geluidsvolume in een mooie visualisatie, biedt een intu<74>tieve en cleane interface, zodat er niets mis kan gaan.
|
||||
|
||||
Het biedt ook een handige speler, zodat de opnames snel kunnen worden beluisterd, hernoemd of verwijderd.
|
||||
|
||||
Bevat geen advertenties of onnodige machtigingen. Volledig open-source. Kleuren van de app kunnen worden aangepast.
|
||||
|
||||
<b>Probeer ook eens de andere apps van Simple Tools:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
||||
</string>
|
||||
|
||||
<!--
|
||||
Haven't found some strings? There's more at
|
||||
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
|
||||
-->
|
||||
</resources>
|
|
@ -5,6 +5,7 @@
|
|||
<string name="recording">Nagrywanie</string>
|
||||
<string name="no_recordings_found">Nie znaleziono nagrań zapisanych\nprzez tę aplikację</string>
|
||||
<string name="no_recordings_in_folder_found">Nie znaleziono nagrań\nw wybranym folderze</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Czy jesteś pewien, że chcesz usunąć %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<string name="recording">Gravação</string>
|
||||
<string name="no_recordings_found">Não foram encontradas gravações\ncriadas por esta aplicação</string>
|
||||
<string name="no_recordings_in_folder_found">Não foram encontradas gravações\nna pasta selecionada</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Tem a certeza de que deseja apagar %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<string name="recording">Запись</string>
|
||||
<string name="no_recordings_found">Записи, созданные этим приложением,\nне найдены</string>
|
||||
<string name="no_recordings_in_folder_found">В выбранной папке не найдено\nни одной записи</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Вы уверены, что хотите удалить %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<string name="recording">Nahráva sa</string>
|
||||
<string name="no_recordings_found">Nenašli sa žiadne nahrávky\nvytvorené touto aplikáciou</string>
|
||||
<string name="no_recordings_in_folder_found">Vo zvolenom priečinku sa nenašli\nžiadne nahrávky</string>
|
||||
<string name="paused">Pauznuté</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Ste si istý, že chcete odstrániť %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<resources>
|
||||
|
||||
<string name="package_name">com.simplemobiletools.voicerecorder</string>
|
||||
<string name="m4a">m4a</string>
|
||||
<string name="mp3">mp3</string>
|
||||
|
||||
</resources>
|
|
@ -5,6 +5,7 @@
|
|||
<string name="recording">Recording</string>
|
||||
<string name="no_recordings_found">No recordings created by this app\nhave been found</string>
|
||||
<string name="no_recordings_in_folder_found">No recordings have been found\nin the selected folder</string>
|
||||
<string name="paused">Paused</string>
|
||||
|
||||
<!-- Confirmation dialog -->
|
||||
<string name="delete_recordings_confirmation">Are you sure you want to delete %s?</string> <!-- Are you sure you want to delete 5 recordings? -->
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.72'
|
||||
ext.kotlin_version = '1.4.10'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
Ευχήθηκες ποτέ να θυμάσαι τι είπε ο άλλος; Ή την εργασία που σου έδωσαν σε μια συνάντηση; Δεν θα εύχεστε άλλο. Με αυτή την απλή καταγραφή μπορείτε να ηχογραφήσετε οποιονδήποτε ήχο πολύ γρήγορα.
|
||||
|
||||
Η εφαρμογή πηγαίνει κατευθείαν στο θέμα, δεν περιέχει φανταχτερά χαρακτηριστικά που δεν θα χρησιμοποιήσετε. Μόνο εσύ και ο καταγραφέας φωνής. Δείχνει την τρέχουσα ηχητική ένταση σε μια ωραία απεικόνιση. Παρέχει ένα πραγματικά διαισθητικό και καθαρό περιβάλλον εργασίας χρήστη, δεν μπορούν να πάνε πολλά στραβά εκεί.
|
||||
|
||||
Προσφέρει επίσης έναν χρήσιμο παίκτη, ώστε να μπορείτε να ακούσετε τις εγγραφές σας γρήγορα, ίσως να τις μετονομάσετε ή να τις διαγράψετε.
|
||||
|
||||
Δεν περιέχει διαφημίσεις ή περιττά δικαιώματα. Είναι πλήρως ανοιχτού κώδικα, παρέχει προσαρμόσιμα χρώματα.
|
||||
|
||||
<b>Δείτε την πλήρη σειρά των Απλών εργαλείων εδώ:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
|
@ -0,0 +1 @@
|
|||
Έύκολη καταγραφή οτιδήποτε ήχου χωρίς διαφημίσεις ή πρόσβαση στο διαδίκτυο
|
|
@ -0,0 +1 @@
|
|||
Απλή Εγγραφή Φωνής - Ηχογραφήστε εύκολα οτιδήποτε
|
|
@ -0,0 +1,2 @@
|
|||
* Allow sharing recordings
|
||||
* Added some UI and translation improvements
|
|
@ -0,0 +1,2 @@
|
|||
* Store recordings with proper m4a extension
|
||||
* Added some translation, stability and UX improvements
|
|
@ -0,0 +1 @@
|
|||
* Allow picking between m4a and mp3 file extensions
|
|
@ -0,0 +1,2 @@
|
|||
* Allow pausing the recording on Android 7+
|
||||
* Added some translation, UX and stability improvements
|
|
@ -0,0 +1,16 @@
|
|||
¿Alguna vez deseaste recordar lo que otra persona dijo? ¿O la tarea que te asignaron en una reunión? No desees más. Con esta grabadora simple puedes grabar cualquier audio realmente rápido.
|
||||
|
||||
La aplicación va directo al punto, no contiene características lujosas que no vas a usar. Solo tú y la grabadora de voz. Muestra el volumen del sonido actual de una forma con la que puedes tener un montón de diversión. Provee una interfaz de usuario realmente intuitiva y limpia, no hay mucho que pueda ir mal aquí.
|
||||
|
||||
También ofrece un útil reproductor, así que puedes escuchar tus grabaciones rapidamente, y quizá renombrarlas o eliminarlas.
|
||||
|
||||
No contiene anuncios o permisos innecesarios. Es completamente de código abierto, provee colores personalizables.
|
||||
|
||||
<b>Mira la suite completa de herramientas Simples aquí:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
|
@ -0,0 +1 @@
|
|||
Una forma fácil de grabar cualquier sonido sin anuncios o acceso a internet
|
|
@ -0,0 +1 @@
|
|||
Grabadora de voz Simple - Graba audio facilmente
|
|
@ -0,0 +1,16 @@
|
|||
Ooit gedacht "had ik dat gesprek maar opgenomen"? Welke briljante opmerking iemand maakte? Welke taken in een vergadering werden uitgedeeld? Met deze simpele voicerecorder zijn heel gemakkelijk opnames te maken.
|
||||
|
||||
De app is komt direct ter zake en bevat geen onnodige franjes. Het toont Het toont het huidige geluidsvolume in een mooie visualisatie, biedt een intuïtieve en cleane interface, zodat er niets mis kan gaan.
|
||||
|
||||
Het biedt ook een handige speler, zodat de opnames snel kunnen worden beluisterd, hernoemd of verwijderd.
|
||||
|
||||
Bevat geen advertenties of onnodige machtigingen. Volledig open-source. Kleuren van de app kunnen worden aangepast.
|
||||
|
||||
<b>Probeer ook eens de andere apps van Simple Tools:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
|
@ -0,0 +1 @@
|
|||
Een makkelijke manier om discussies of geluiden op te nemen, zonder advertenties
|
|
@ -0,0 +1 @@
|
|||
Eenvoudige Voicerecorder - Snel geluid opnemen
|
|
@ -0,0 +1,16 @@
|
|||
Вы когда-нибудь хотели вспомнить, что сказал другой человек? Или задание, которое вам дали на совещании? Больше не нужно хотеть. С помощью этого простого диктофона вы сможете записать любой звук очень быстро.
|
||||
|
||||
Приложение сразу переходит к делу, оно не содержит никаких причудливых функций, которые вы не будете использовать. Только вы и диктофон. Оно показывает текущую громкость звука в виде приятной визуализации, от которой вы получите массу удовольствия. Приложение имеет действительно интуитивно понятный и чистый пользовательский интерфейс, не так много может пойти не так.
|
||||
|
||||
Также имеется проигрыватель, чтобы вы могли быстро прослушать свои записи, с возможностью переименовывать или удалить их.
|
||||
|
||||
Не содержит рекламы или ненужных разрешений, полностью с открытым исходным кодом. Есть возможность настраивать цвета интерфейса.
|
||||
|
||||
<b>Ознакомьтесь с полным набором инструментов серии Simple здесь:</b>
|
||||
https://www.simplemobiletools.com
|
||||
|
||||
<b>Facebook:</b>
|
||||
https://www.facebook.com/simplemobiletools
|
||||
|
||||
<b>Reddit:</b>
|
||||
https://www.reddit.com/r/SimpleMobileTools
|
|
@ -0,0 +1 @@
|
|||
Лёгкий способ записи любой дискуссии или звука без рекламы и доступа в интернет
|
|
@ -0,0 +1 @@
|
|||
Simple Voice Recorder - простая запись звука
|
|
@ -1,6 +1,6 @@
|
|||
#Sat Mar 28 17:10:51 CET 2020
|
||||
#Thu Nov 05 16:04:25 CET 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
|
|