more rewriting to kotlin

This commit is contained in:
tibbi 2017-11-05 23:17:50 +01:00
parent 18b5c9de46
commit 94fef5494c
26 changed files with 322 additions and 652 deletions

View File

@ -1,5 +1,4 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'android-apt'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
@ -39,12 +38,8 @@ android {
dependencies { dependencies {
compile 'com.simplemobiletools:commons:2.35.6' compile 'com.simplemobiletools:commons:2.35.6'
compile 'com.jakewharton:butterknife:8.0.1'
compile 'com.squareup:otto:1.3.8' compile 'com.squareup:otto:1.3.8'
compile 'com.github.yukuku:ambilwarna:2.0.1'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
apt 'com.jakewharton:butterknife-compiler:8.0.1'
} }
buildscript { buildscript {

View File

@ -1,20 +1,3 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in $ANDROID_HOME/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Otto # Otto
-keepattributes *Annotation* -keepattributes *Annotation*
-keepclassmembers class ** { -keepclassmembers class ** {

View File

@ -30,7 +30,7 @@
<activity <activity
android:name=".activities.MainActivity" android:name=".activities.MainActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/BlackSplashScreen.Dark"/> android:theme="@style/AppTheme"/>
<activity <activity
android:name=".activities.WidgetConfigureActivity" android:name=".activities.WidgetConfigureActivity"

View File

@ -1,76 +1,84 @@
package com.simplemobiletools.flashlight.activities package com.simplemobiletools.flashlight.activities
import android.Manifest
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.ImageView import android.widget.ImageView
import android.widget.SeekBar import android.widget.SeekBar
import butterknife.ButterKnife import com.simplemobiletools.commons.extensions.*
import butterknife.OnClick
import com.simplemobiletools.commons.activities.AboutActivity
import com.simplemobiletools.commons.extensions.beInvisible
import com.simplemobiletools.commons.helpers.LICENSE_KOTLIN import com.simplemobiletools.commons.helpers.LICENSE_KOTLIN
import com.simplemobiletools.commons.helpers.LICENSE_OTTO import com.simplemobiletools.commons.helpers.LICENSE_OTTO
import com.simplemobiletools.commons.helpers.PERMISSION_CAMERA
import com.simplemobiletools.flashlight.BuildConfig import com.simplemobiletools.flashlight.BuildConfig
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.extensions.config import com.simplemobiletools.flashlight.extensions.config
import com.simplemobiletools.flashlight.helpers.BusProvider import com.simplemobiletools.flashlight.helpers.BusProvider
import com.simplemobiletools.flashlight.helpers.MyCameraImpl import com.simplemobiletools.flashlight.helpers.MyCameraImpl
import com.simplemobiletools.flashlight.helpers.Utils
import com.simplemobiletools.flashlight.models.Events import com.simplemobiletools.flashlight.models.Events
import com.squareup.otto.Bus import com.squareup.otto.Bus
import com.squareup.otto.Subscribe import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : SimpleActivity() { class MainActivity : SimpleActivity() {
companion object { private val MAX_STROBO_DELAY = 2000
private val CAMERA_PERMISSION = 1 private val MIN_STROBO_DELAY = 30
private val MAX_STROBO_DELAY = 2000
private val MIN_STROBO_DELAY = 30
private var mBus: Bus? = null
}
private var mBus: Bus? = null
private var mCameraImpl: MyCameraImpl? = null private var mCameraImpl: MyCameraImpl? = null
private var mJustGrantedPermission: Boolean = false
private val isCameraPermissionGranted: Boolean
get() = ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
ButterKnife.bind(this)
mBus = BusProvider.instance mBus = BusProvider.instance
changeIconColor(R.color.translucent_white, bright_display_btn) changeIconColor(R.color.translucent_white, bright_display_btn)
changeIconColor(R.color.translucent_white, stroboscope_btn) changeIconColor(R.color.translucent_white, stroboscope_btn)
stroboscope_bar.max = MAX_STROBO_DELAY - MIN_STROBO_DELAY
stroboscope_bar.progress = stroboscope_bar.max / 2
stroboscope_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { bright_display_btn.setOnClickListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, b: Boolean) { startActivity(Intent(applicationContext, BrightDisplayActivity::class.java))
val frequency = stroboscope_bar.max - progress + MIN_STROBO_DELAY }
if (mCameraImpl != null)
mCameraImpl!!.setStroboFrequency(frequency)
}
override fun onStartTrackingTouch(seekBar: SeekBar) { toggle_btn.setOnClickListener {
mCameraImpl!!.toggleFlashlight()
}
} setupStroboscope()
}
override fun onStopTrackingTouch(seekBar: SeekBar) { override fun onResume() {
super.onResume()
mCameraImpl!!.handleCameraSetup()
mCameraImpl!!.checkFlashlight()
} bright_display_btn.beVisibleIf(config.brightDisplay)
}) stroboscope_btn.beVisibleIf(config.stroboscope)
if (!config.stroboscope) {
mCameraImpl!!.stopStroboscope()
stroboscope_bar.beInvisible()
}
}
override fun onStart() {
super.onStart()
mBus!!.register(this)
if (mCameraImpl == null) {
setupCameraImpl()
}
}
override fun onStop() {
super.onStop()
mBus!!.unregister(this)
}
override fun onDestroy() {
super.onDestroy()
releaseCamera()
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
@ -80,16 +88,11 @@ class MainActivity : SimpleActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.settings -> { R.id.settings -> launchSettings()
startActivity(Intent(applicationContext, SettingsActivity::class.java)) R.id.about -> launchAbout()
return true
}
R.id.about -> {
startActivity(Intent(applicationContext, AboutActivity::class.java))
return true
}
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
return true
} }
private fun launchSettings() { private fun launchSettings() {
@ -105,88 +108,55 @@ class MainActivity : SimpleActivity() {
mCameraImpl!!.enableFlashlight() mCameraImpl!!.enableFlashlight()
} }
@OnClick(R.id.toggle_btn) private fun setupStroboscope() {
fun toggleFlashlight() { stroboscope_btn.setOnClickListener {
mCameraImpl!!.toggleFlashlight() toggleStroboscope()
} }
@OnClick(R.id.bright_display_btn) stroboscope_bar.max = MAX_STROBO_DELAY - MIN_STROBO_DELAY
fun launchBrightDisplay() { stroboscope_bar.progress = stroboscope_bar.max / 2
startActivity(Intent(applicationContext, BrightDisplayActivity::class.java)) stroboscope_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
} override fun onProgressChanged(seekBar: SeekBar, progress: Int, b: Boolean) {
val frequency = stroboscope_bar.max - progress + MIN_STROBO_DELAY
if (mCameraImpl != null)
mCameraImpl!!.stroboFrequency = frequency
}
@OnClick(R.id.stroboscope_btn) override fun onStartTrackingTouch(seekBar: SeekBar) {
fun tryToggleStroboscope() {
toggleStroboscope() }
override fun onStopTrackingTouch(seekBar: SeekBar) {
}
})
} }
private fun toggleStroboscope() { private fun toggleStroboscope() {
// use the old Camera API for stroboscope, the new Camera Manager is way too slow // use the old Camera API for stroboscope, the new Camera Manager is way too slow
if (isCameraPermissionGranted || Utils.isNougat) { if (isNougatPlus()) {
if (mCameraImpl!!.toggleStroboscope()) { cameraPermissionGranted()
stroboscope_bar.visibility = if (stroboscope_bar.visibility == View.VISIBLE) View.INVISIBLE else View.VISIBLE
changeIconColor(if (stroboscope_bar.visibility == View.VISIBLE) R.color.colorPrimary else R.color.translucent_white, stroboscope_btn)
}
} else { } else {
val permissions = arrayOf(Manifest.permission.CAMERA) handlePermission(PERMISSION_CAMERA) {
ActivityCompat.requestPermissions(this, permissions, CAMERA_PERMISSION) if (it) {
} cameraPermissionGranted()
} } else {
toast(R.string.camera_permission)
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { }
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_PERMISSION) {
mJustGrantedPermission = true
if (isCameraPermissionGranted) {
toggleStroboscope()
} else {
Utils.showToast(applicationContext, R.string.camera_permission)
} }
} }
} }
override fun onStart() { private fun cameraPermissionGranted() {
super.onStart() if (mCameraImpl!!.toggleStroboscope()) {
mBus!!.register(this) stroboscope_bar.beInvisibleIf(stroboscope_bar.visibility == View.VISIBLE)
changeIconColor(if (stroboscope_bar.visibility == View.VISIBLE) R.color.color_primary else R.color.translucent_white, stroboscope_btn)
if (mCameraImpl == null) {
setupCameraImpl()
} }
} }
override fun onResume() {
super.onResume()
if (mJustGrantedPermission) {
mJustGrantedPermission = false
return
}
mCameraImpl!!.handleCameraSetup()
mCameraImpl!!.checkFlashlight()
bright_display_btn!!.visibility = if (config.brightDisplay) View.VISIBLE else View.GONE
stroboscope_btn!!.visibility = if (config.stroboscope) View.VISIBLE else View.GONE
if (!config.stroboscope) {
mCameraImpl!!.stopStroboscope()
stroboscope_bar.visibility = View.INVISIBLE
}
}
override fun onStop() {
super.onStop()
mBus!!.unregister(this)
}
override fun onDestroy() {
super.onDestroy()
releaseCamera()
}
private fun releaseCamera() { private fun releaseCamera() {
if (mCameraImpl != null) { mCameraImpl?.releaseCamera()
mCameraImpl!!.releaseCamera() mCameraImpl = null
mCameraImpl = null
}
} }
@Subscribe @Subscribe
@ -198,15 +168,15 @@ class MainActivity : SimpleActivity() {
} }
} }
fun enableFlashlight() { private fun enableFlashlight() {
changeIconColor(R.color.colorPrimary, toggle_btn) changeIconColor(R.color.color_primary, toggle_btn)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
changeIconColor(R.color.translucent_white, stroboscope_btn) changeIconColor(R.color.translucent_white, stroboscope_btn)
stroboscope_bar.beInvisible() stroboscope_bar.beInvisible()
} }
fun disableFlashlight() { private fun disableFlashlight() {
changeIconColor(R.color.translucent_white, toggle_btn) changeIconColor(R.color.translucent_white, toggle_btn)
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
} }
@ -218,7 +188,7 @@ class MainActivity : SimpleActivity() {
@Subscribe @Subscribe
fun cameraUnavailable(event: Events.CameraUnavailable) { fun cameraUnavailable(event: Events.CameraUnavailable) {
Utils.showToast(this, R.string.camera_error) toast(R.string.camera_error)
disableFlashlight() disableFlashlight()
} }
} }

View File

@ -1,54 +1,45 @@
package com.simplemobiletools.flashlight.activities package com.simplemobiletools.flashlight.activities
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.TaskStackBuilder import com.simplemobiletools.commons.extensions.updateTextColors
import android.support.v7.widget.SwitchCompat
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.helpers.Config import com.simplemobiletools.flashlight.extensions.config
import kotlinx.android.synthetic.main.activity_settings.*
class SettingsActivity : SimpleActivity() { class SettingsActivity : SimpleActivity() {
@BindView(R.id.settings_bright_display) internal var mBrightDisplaySwitch: SwitchCompat? = null
@BindView(R.id.settings_stroboscope) internal var mStroboscopeSwitch: SwitchCompat? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings) setContentView(R.layout.activity_settings)
mConfig = Config.newInstance(applicationContext) }
ButterKnife.bind(this)
override fun onResume() {
super.onResume()
setupCustomizeColors()
setupBrightDisplay() setupBrightDisplay()
setupStroboscope() setupStroboscope()
updateTextColors(settings_holder)
}
private fun setupCustomizeColors() {
settings_customize_colors_holder.setOnClickListener {
startCustomizationActivity()
}
} }
private fun setupBrightDisplay() { private fun setupBrightDisplay() {
mBrightDisplaySwitch!!.isChecked = mConfig!!.brightDisplay settings_bright_display.isChecked = config.brightDisplay
settings_bright_display_holder.setOnClickListener {
settings_bright_display.toggle()
config.brightDisplay = settings_bright_display.isChecked
}
} }
private fun setupStroboscope() { private fun setupStroboscope() {
mStroboscopeSwitch!!.isChecked = mConfig!!.stroboscope settings_stroboscope.isChecked = config.stroboscope
} settings_stroboscope_holder.setOnClickListener {
settings_stroboscope.toggle()
@OnClick(R.id.settings_bright_display_holder) config.stroboscope = settings_stroboscope.isChecked
fun handleBrightDisplay() { }
mBrightDisplaySwitch!!.isChecked = !mBrightDisplaySwitch!!.isChecked
mConfig!!.brightDisplay = mBrightDisplaySwitch!!.isChecked
}
@OnClick(R.id.settings_stroboscope_holder)
fun handleStroboscope() {
mStroboscopeSwitch!!.isChecked = !mStroboscopeSwitch!!.isChecked
mConfig!!.stroboscope = mStroboscopeSwitch!!.isChecked
}
private fun restartActivity() {
TaskStackBuilder.create(applicationContext).addNextIntentWithParentStack(intent).startActivities()
}
companion object {
private var mConfig: Config? = null
} }
} }

View File

@ -8,23 +8,95 @@ import android.graphics.Color
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.view.View
import android.widget.ImageView
import android.widget.RemoteViews import android.widget.RemoteViews
import android.widget.SeekBar import android.widget.SeekBar
import butterknife.BindView import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import butterknife.ButterKnife import com.simplemobiletools.commons.extensions.adjustAlpha
import butterknife.OnClick
import com.simplemobiletools.commons.helpers.PREFS_KEY import com.simplemobiletools.commons.helpers.PREFS_KEY
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.helpers.MyWidgetProvider import com.simplemobiletools.flashlight.helpers.MyWidgetProvider
import com.simplemobiletools.flashlight.helpers.WIDGET_COLOR import com.simplemobiletools.flashlight.helpers.WIDGET_COLOR
import yuku.ambilwarna.AmbilWarnaDialog import kotlinx.android.synthetic.main.widget_config.*
class WidgetConfigureActivity : AppCompatActivity() { class WidgetConfigureActivity : AppCompatActivity() {
@BindView(R.id.config_widget_seekbar) internal var mWidgetSeekBar: SeekBar? = null companion object {
@BindView(R.id.config_widget_color) internal var mWidgetColorPicker: View? = null private var mWidgetAlpha = 0f
@BindView(R.id.config_image) internal var mImage: ImageView? = null private var mWidgetId = 0
private var mWidgetColor = 0
private var mWidgetColorWithoutTransparency = 0
}
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED)
setContentView(R.layout.widget_config)
initVariables()
val intent = intent
val extras = intent.extras
if (extras != null)
mWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
finish()
config_save.setOnClickListener { saveConfig() }
config_widget_color.setOnClickListener { pickBackgroundColor() }
}
private fun initVariables() {
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
mWidgetColor = prefs.getInt(WIDGET_COLOR, 1)
if (mWidgetColor == 1) {
mWidgetColor = resources.getColor(R.color.color_primary)
mWidgetAlpha = 1f
} else {
mWidgetAlpha = Color.alpha(mWidgetColor) / 255.toFloat()
}
mWidgetColorWithoutTransparency = Color.rgb(Color.red(mWidgetColor), Color.green(mWidgetColor), Color.blue(mWidgetColor))
config_widget_seekbar.setOnSeekBarChangeListener(seekbarChangeListener)
config_widget_seekbar.progress = (mWidgetAlpha * 100).toInt()
updateColors()
}
fun saveConfig() {
val appWidgetManager = AppWidgetManager.getInstance(this)
val views = RemoteViews(packageName, R.layout.widget)
appWidgetManager.updateAppWidget(mWidgetId, views)
storeWidgetColors()
requestWidgetUpdate()
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
setResult(Activity.RESULT_OK, resultValue)
finish()
}
fun pickBackgroundColor() {
ColorPickerDialog(this, mWidgetColorWithoutTransparency) {
mWidgetColorWithoutTransparency = it
updateColors()
}
}
private fun storeWidgetColors() {
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
prefs.edit().putInt(WIDGET_COLOR, mWidgetColor).apply()
}
private fun requestWidgetUpdate() {
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider::class.java)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mWidgetId))
sendBroadcast(intent)
}
private fun updateColors() {
mWidgetColor = mWidgetColorWithoutTransparency.adjustAlpha(mWidgetAlpha)
config_widget_color.setBackgroundColor(mWidgetColor)
config_image.background.mutate().setColorFilter(mWidgetColor, PorterDuff.Mode.SRC_IN)
}
private val seekbarChangeListener = object : SeekBar.OnSeekBarChangeListener { private val seekbarChangeListener = object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
@ -40,98 +112,4 @@ class WidgetConfigureActivity : AppCompatActivity() {
} }
} }
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED)
setContentView(R.layout.widget_config)
ButterKnife.bind(this)
initVariables()
val intent = intent
val extras = intent.extras
if (extras != null)
mWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
finish()
}
private fun initVariables() {
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
mWidgetColor = prefs.getInt(WIDGET_COLOR, 1)
if (mWidgetColor == 1) {
mWidgetColor = resources.getColor(R.color.colorPrimary)
mWidgetAlpha = 1f
} else {
mWidgetAlpha = Color.alpha(mWidgetColor) / 255.toFloat()
}
mWidgetColorWithoutTransparency = Color.rgb(Color.red(mWidgetColor), Color.green(mWidgetColor), Color.blue(mWidgetColor))
mWidgetSeekBar!!.setOnSeekBarChangeListener(seekbarChangeListener)
mWidgetSeekBar!!.progress = (mWidgetAlpha * 100).toInt()
updateColors()
}
@OnClick(R.id.config_save)
fun saveConfig() {
val appWidgetManager = AppWidgetManager.getInstance(this)
val views = RemoteViews(packageName, R.layout.widget)
appWidgetManager.updateAppWidget(mWidgetId, views)
storeWidgetColors()
requestWidgetUpdate()
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
setResult(Activity.RESULT_OK, resultValue)
finish()
}
@OnClick(R.id.config_widget_color)
fun pickBackgroundColor() {
val dialog = AmbilWarnaDialog(this, mWidgetColorWithoutTransparency, object : AmbilWarnaDialog.OnAmbilWarnaListener {
override fun onCancel(dialog: AmbilWarnaDialog) {}
override fun onOk(dialog: AmbilWarnaDialog, color: Int) {
mWidgetColorWithoutTransparency = color
updateColors()
}
})
dialog.show()
}
private fun storeWidgetColors() {
val prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
prefs.edit().putInt(WIDGET_COLOR, mWidgetColor).apply()
}
private fun requestWidgetUpdate() {
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider::class.java)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mWidgetId))
sendBroadcast(intent)
}
private fun updateColors() {
mWidgetColor = adjustAlpha(mWidgetColorWithoutTransparency, mWidgetAlpha)
mWidgetColorPicker!!.setBackgroundColor(mWidgetColor)
mImage!!.background.mutate().setColorFilter(mWidgetColor, PorterDuff.Mode.SRC_IN)
}
private fun adjustAlpha(color: Int, factor: Float): Int {
val alpha = Math.round(Color.alpha(color) * factor)
val red = Color.red(color)
val green = Color.green(color)
val blue = Color.blue(color)
return Color.argb(alpha, red, green, blue)
}
companion object {
private var mWidgetAlpha: Float = 0.toFloat()
private var mWidgetId: Int = 0
private var mWidgetColor: Int = 0
private var mWidgetColorWithoutTransparency: Int = 0
}
} }

View File

@ -6,25 +6,20 @@ import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraManager import android.hardware.camera2.CameraManager
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.util.Log
import com.simplemobiletools.flashlight.models.Events import com.simplemobiletools.flashlight.models.Events
import com.squareup.otto.Bus import com.squareup.otto.Bus
internal class MarshmallowCamera @TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.LOLLIPOP)
constructor(private val mContext: Context) { internal class MarshmallowCamera constructor(val context: Context) {
private val manager: CameraManager private val manager: CameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
private var cameraId: String? = null private var cameraId: String? = null
init { init {
manager = mContext.getSystemService(Context.CAMERA_SERVICE) as CameraManager
try { try {
val list = manager.cameraIdList cameraId = manager.cameraIdList[0]
cameraId = list[0]
} catch (ignored: CameraAccessException) { } catch (ignored: CameraAccessException) {
} }
} }
@TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.M)
@ -32,15 +27,10 @@ constructor(private val mContext: Context) {
try { try {
manager.setTorchMode(cameraId!!, enable) manager.setTorchMode(cameraId!!, enable)
} catch (e: CameraAccessException) { } catch (e: CameraAccessException) {
Log.e(TAG, "toggle marshmallow flashlight " + e.message) val mainRunnable = Runnable {
bus.post(Events.CameraUnavailable())
val mainRunnable = Runnable { bus.post(Events.CameraUnavailable()) } }
Handler(mContext.mainLooper).post(mainRunnable) Handler(context.mainLooper).post(mainRunnable)
} }
}
companion object {
private val TAG = MyCameraImpl::class.java.simpleName
} }
} }

View File

@ -1,109 +1,104 @@
package com.simplemobiletools.flashlight.helpers package com.simplemobiletools.flashlight.helpers
import android.annotation.TargetApi
import android.content.Context import android.content.Context
import android.graphics.SurfaceTexture import android.graphics.SurfaceTexture
import android.hardware.Camera import android.hardware.Camera
import android.os.Build
import android.os.Handler import android.os.Handler
import android.util.Log import com.simplemobiletools.commons.extensions.isMarshmallowPlus
import com.simplemobiletools.commons.extensions.isNougatPlus
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.models.Events import com.simplemobiletools.flashlight.models.Events
import com.squareup.otto.Bus import com.squareup.otto.Bus
import java.io.IOException import java.io.IOException
class MyCameraImpl(private val mContext: Context) { class MyCameraImpl(val context: Context) {
var stroboFrequency = 1000
companion object { companion object {
private val TAG = MyCameraImpl::class.java.simpleName private var camera: Camera? = null
private var mCamera: Camera? = null
private var mParams: Camera.Parameters? = null private var mParams: Camera.Parameters? = null
private var mBus: Bus? = null private var bus: Bus? = null
private var mIsFlashlightOn: Boolean = false private var mIsFlashlightOn = false
private var mIsMarshmallow: Boolean = false private var mIsMarshmallow = false
private var mShouldEnableFlashlight: Boolean = false private var mShouldEnableFlashlight = false
private var mStroboFrequency: Int = 0
} }
private var mMarshmallowCamera: MarshmallowCamera? = null private var marshmallowCamera: MarshmallowCamera? = null
@Volatile private var mShouldStroboscopeStop: Boolean = false @Volatile private var shouldStroboscopeStop = false
@Volatile private var mIsStroboscopeRunning: Boolean = false @Volatile private var isStroboscopeRunning = false
private val isMarshmallow: Boolean
get() = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
private val stroboscope = Runnable { private val stroboscope = Runnable {
if (mIsStroboscopeRunning) { if (isStroboscopeRunning) {
return@Runnable return@Runnable
} }
mShouldStroboscopeStop = false shouldStroboscopeStop = false
mIsStroboscopeRunning = true isStroboscopeRunning = true
if (Utils.isNougat) { if (context.isNougatPlus()) {
while (!mShouldStroboscopeStop) { while (!shouldStroboscopeStop) {
try { try {
mMarshmallowCamera!!.toggleMarshmallowFlashlight(mBus!!, true) marshmallowCamera!!.toggleMarshmallowFlashlight(bus!!, true)
Thread.sleep(mStroboFrequency.toLong()) Thread.sleep(stroboFrequency.toLong())
mMarshmallowCamera!!.toggleMarshmallowFlashlight(mBus!!, false) marshmallowCamera!!.toggleMarshmallowFlashlight(bus!!, false)
Thread.sleep(mStroboFrequency.toLong()) Thread.sleep(stroboFrequency.toLong())
} catch (ignored: InterruptedException) { } catch (ignored: InterruptedException) {
mShouldStroboscopeStop = true shouldStroboscopeStop = true
} catch (ignored: RuntimeException) { } catch (ignored: RuntimeException) {
mShouldStroboscopeStop = true shouldStroboscopeStop = true
} }
} }
} else { } else {
if (mCamera == null) { if (camera == null) {
initCamera() initCamera()
} }
val torchOn = mCamera!!.parameters val torchOn = camera!!.parameters
val torchOff = mCamera!!.parameters val torchOff = camera!!.parameters
torchOn.flashMode = Camera.Parameters.FLASH_MODE_TORCH torchOn.flashMode = Camera.Parameters.FLASH_MODE_TORCH
torchOff.flashMode = Camera.Parameters.FLASH_MODE_OFF torchOff.flashMode = Camera.Parameters.FLASH_MODE_OFF
val dummy = SurfaceTexture(1) val dummy = SurfaceTexture(1)
try { try {
mCamera!!.setPreviewTexture(dummy) camera!!.setPreviewTexture(dummy)
} catch (e: IOException) { } catch (e: IOException) {
Log.e(TAG, "setup stroboscope1 " + e.message)
} }
mCamera!!.startPreview() camera!!.startPreview()
while (!mShouldStroboscopeStop) { while (!shouldStroboscopeStop) {
try { try {
mCamera!!.parameters = torchOn camera!!.parameters = torchOn
Thread.sleep(mStroboFrequency.toLong()) Thread.sleep(stroboFrequency.toLong())
mCamera!!.parameters = torchOff camera!!.parameters = torchOff
Thread.sleep(mStroboFrequency.toLong()) Thread.sleep(stroboFrequency.toLong())
} catch (ignored: InterruptedException) { } catch (ignored: InterruptedException) {
mShouldStroboscopeStop = true shouldStroboscopeStop = true
} catch (ignored: RuntimeException) { } catch (ignored: RuntimeException) {
mShouldStroboscopeStop = true shouldStroboscopeStop = true
} }
} }
try { try {
if (mCamera != null) { if (camera != null) {
mCamera!!.parameters = torchOff camera!!.parameters = torchOff
if (!mShouldEnableFlashlight || mIsMarshmallow) { if (!mShouldEnableFlashlight || mIsMarshmallow) {
mCamera!!.release() camera!!.release()
mCamera = null camera = null
} }
} }
} catch (e: RuntimeException) { } catch (e: RuntimeException) {
Log.e(TAG, "setup stroboscope2 " + e.message)
} }
} }
mIsStroboscopeRunning = false isStroboscopeRunning = false
mShouldStroboscopeStop = false shouldStroboscopeStop = false
if (mShouldEnableFlashlight) { if (mShouldEnableFlashlight) {
enableFlashlight() enableFlashlight()
@ -112,12 +107,11 @@ class MyCameraImpl(private val mContext: Context) {
} }
init { init {
mIsMarshmallow = isMarshmallow mIsMarshmallow = context.isMarshmallowPlus()
mStroboFrequency = 1000
if (mBus == null) { if (bus == null) {
mBus = BusProvider.instance bus = BusProvider.instance
mBus!!.register(this) bus!!.register(this)
} }
handleCameraSetup() handleCameraSetup()
@ -129,26 +123,22 @@ class MyCameraImpl(private val mContext: Context) {
handleCameraSetup() handleCameraSetup()
} }
fun setStroboFrequency(frequency: Int) {
mStroboFrequency = frequency
}
fun toggleStroboscope(): Boolean { fun toggleStroboscope(): Boolean {
if (!mIsStroboscopeRunning) if (!isStroboscopeRunning)
disableFlashlight() disableFlashlight()
if (!Utils.isNougat) { if (!context.isNougatPlus()) {
if (mCamera == null) { if (camera == null) {
initCamera() initCamera()
} }
if (mCamera == null) { if (camera == null) {
Utils.showToast(mContext, R.string.camera_error) context.toast(R.string.camera_error)
return false return false
} }
} }
if (mIsStroboscopeRunning) { if (isStroboscopeRunning) {
stopStroboscope() stopStroboscope()
} else { } else {
Thread(stroboscope).start() Thread(stroboscope).start()
@ -157,7 +147,7 @@ class MyCameraImpl(private val mContext: Context) {
} }
fun stopStroboscope() { fun stopStroboscope() {
mShouldStroboscopeStop = true shouldStroboscopeStop = true
} }
fun handleCameraSetup() { fun handleCameraSetup() {
@ -170,8 +160,8 @@ class MyCameraImpl(private val mContext: Context) {
} }
private fun setupMarshmallowCamera() { private fun setupMarshmallowCamera() {
if (mMarshmallowCamera == null) { if (marshmallowCamera == null) {
mMarshmallowCamera = MarshmallowCamera(mContext) marshmallowCamera = MarshmallowCamera(context)
} }
} }
@ -179,20 +169,19 @@ class MyCameraImpl(private val mContext: Context) {
if (mIsMarshmallow) if (mIsMarshmallow)
return return
if (mCamera == null) { if (camera == null) {
initCamera() initCamera()
} }
} }
private fun initCamera() { private fun initCamera() {
try { try {
mCamera = Camera.open() camera = Camera.open()
mParams = mCamera!!.parameters mParams = camera!!.parameters
mParams!!.flashMode = Camera.Parameters.FLASH_MODE_OFF mParams!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
mCamera!!.parameters = mParams camera!!.parameters = mParams
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "setup mCamera " + e.message) bus!!.post(Events.CameraUnavailable())
mBus!!.post(Events.CameraUnavailable())
} }
} }
@ -206,8 +195,8 @@ class MyCameraImpl(private val mContext: Context) {
} }
fun enableFlashlight() { fun enableFlashlight() {
mShouldStroboscopeStop = true shouldStroboscopeStop = true
if (mIsStroboscopeRunning) { if (isStroboscopeRunning) {
mShouldEnableFlashlight = true mShouldEnableFlashlight = true
return return
} }
@ -216,21 +205,21 @@ class MyCameraImpl(private val mContext: Context) {
if (mIsMarshmallow) { if (mIsMarshmallow) {
toggleMarshmallowFlashlight(true) toggleMarshmallowFlashlight(true)
} else { } else {
if (mCamera == null || mParams == null) { if (camera == null || mParams == null) {
return return
} }
mParams!!.flashMode = Camera.Parameters.FLASH_MODE_TORCH mParams!!.flashMode = Camera.Parameters.FLASH_MODE_TORCH
mCamera!!.parameters = mParams camera!!.parameters = mParams
mCamera!!.startPreview() camera!!.startPreview()
} }
val mainRunnable = Runnable { mBus!!.post(Events.StateChanged(true)) } val mainRunnable = Runnable { bus!!.post(Events.StateChanged(true)) }
Handler(mContext.mainLooper).post(mainRunnable) Handler(context.mainLooper).post(mainRunnable)
} }
private fun disableFlashlight() { private fun disableFlashlight() {
if (mIsStroboscopeRunning) { if (isStroboscopeRunning) {
return return
} }
@ -238,18 +227,18 @@ class MyCameraImpl(private val mContext: Context) {
if (mIsMarshmallow) { if (mIsMarshmallow) {
toggleMarshmallowFlashlight(false) toggleMarshmallowFlashlight(false)
} else { } else {
if (mCamera == null || mParams == null) { if (camera == null || mParams == null) {
return return
} }
mParams!!.flashMode = Camera.Parameters.FLASH_MODE_OFF mParams!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
mCamera!!.parameters = mParams camera!!.parameters = mParams
} }
mBus!!.post(Events.StateChanged(false)) bus!!.post(Events.StateChanged(false))
} }
private fun toggleMarshmallowFlashlight(enable: Boolean) { private fun toggleMarshmallowFlashlight(enable: Boolean) {
mMarshmallowCamera!!.toggleMarshmallowFlashlight(mBus!!, enable) marshmallowCamera!!.toggleMarshmallowFlashlight(bus!!, enable)
} }
fun releaseCamera() { fun releaseCamera() {
@ -257,15 +246,11 @@ class MyCameraImpl(private val mContext: Context) {
disableFlashlight() disableFlashlight()
} }
if (mCamera != null) { camera?.release()
mCamera!!.release() camera = null
mCamera = null
}
if (mBus != null) { bus?.unregister(this)
mBus!!.unregister(this)
}
mIsFlashlightOn = false mIsFlashlightOn = false
mShouldStroboscopeStop = true shouldStroboscopeStop = true
} }
} }

View File

@ -11,6 +11,7 @@ import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.widget.RemoteViews import android.widget.RemoteViews
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.helpers.PREFS_KEY import com.simplemobiletools.commons.helpers.PREFS_KEY
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.models.Events import com.simplemobiletools.flashlight.models.Events
@ -40,7 +41,7 @@ class MyWidgetProvider : AppWidgetProvider() {
val prefs = initPrefs(context) val prefs = initPrefs(context)
val res = context.resources val res = context.resources
val defaultColor = res.getColor(R.color.colorPrimary) val defaultColor = res.getColor(R.color.color_primary)
val selectedColor = prefs.getInt(WIDGET_COLOR, defaultColor) val selectedColor = prefs.getInt(WIDGET_COLOR, defaultColor)
val alpha = Color.alpha(selectedColor) val alpha = Color.alpha(selectedColor)
@ -94,7 +95,7 @@ class MyWidgetProvider : AppWidgetProvider() {
@Subscribe @Subscribe
fun cameraUnavailable(event: Events.CameraUnavailable) { fun cameraUnavailable(event: Events.CameraUnavailable) {
if (mContext != null) { if (mContext != null) {
Utils.showToast(mContext!!, R.string.camera_error) mContext!!.toast(R.string.camera_error)
disableFlashlight() disableFlashlight()
} }
} }

View File

@ -1,17 +1,11 @@
package com.simplemobiletools.flashlight.helpers package com.simplemobiletools.flashlight.helpers
import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build
import android.widget.Toast
object Utils { object Utils {
val isNougat: Boolean
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
fun drawableToBitmap(drawable: Drawable): Bitmap { fun drawableToBitmap(drawable: Drawable): Bitmap {
val width = drawable.intrinsicWidth val width = drawable.intrinsicWidth
val height = drawable.intrinsicHeight val height = drawable.intrinsicHeight
@ -21,8 +15,4 @@ object Utils {
drawable.draw(canvas) drawable.draw(canvas)
return mutableBitmap return mutableBitmap
} }
fun showToast(context: Context, resId: Int) {
Toast.makeText(context, context.resources.getString(resId), Toast.LENGTH_SHORT).show()
}
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <FrameLayout
android:id="@+id/display_holder"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/display_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/white"/> android:background="@android:color/white"/>

View File

@ -12,28 +12,41 @@
android:orientation="vertical"> android:orientation="vertical">
<RelativeLayout <RelativeLayout
android:id="@+id/settings_bright_display_holder" android:id="@+id/settings_customize_colors_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/settings_padding" android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin"> android:padding="@dimen/activity_margin">
<TextView <com.simplemobiletools.commons.views.MyTextView
android:id="@+id/settings_bright_display_label" android:id="@+id/settings_customize_colors"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:paddingLeft="@dimen/settings_padding" android:paddingLeft="@dimen/medium_margin"
android:text="@string/bright_display"/> android:paddingStart="@dimen/medium_margin"
android:text="@string/customize_colors"/>
<android.support.v7.widget.SwitchCompat </RelativeLayout>
<RelativeLayout
android:id="@+id/settings_bright_display_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/settings_bright_display" android:id="@+id/settings_bright_display"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@null" android:background="@null"
android:clickable="false"/> android:clickable="false"
android:paddingLeft="@dimen/medium_margin"
android:paddingStart="@dimen/medium_margin"
android:text="@string/bright_display"/>
</RelativeLayout> </RelativeLayout>
@ -41,25 +54,19 @@
android:id="@+id/settings_stroboscope_holder" android:id="@+id/settings_stroboscope_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/settings_padding" android:layout_marginTop="@dimen/medium_margin"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:padding="@dimen/activity_margin"> android:padding="@dimen/activity_margin">
<TextView <com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/settings_stroboscope_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="@dimen/settings_padding"
android:text="@string/show_stroboscope"/>
<android.support.v7.widget.SwitchCompat
android:id="@+id/settings_stroboscope" android:id="@+id/settings_stroboscope"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@null" android:background="@null"
android:clickable="false"/> android:clickable="false"
android:paddingLeft="@dimen/medium_margin"
android:paddingStart="@dimen/medium_margin"
android:text="@string/show_stroboscope"/>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>

View File

@ -56,7 +56,7 @@
android:paddingLeft="@dimen/activity_margin" android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin" android:paddingRight="@dimen/activity_margin"
android:text="@string/ok" android:text="@string/ok"
android:textColor="@color/colorPrimary" android:textColor="@color/color_primary"
android:textSize="@dimen/config_text_size"/> android:textSize="@dimen/big_text_size"/>
</RelativeLayout> </RelativeLayout>

View File

@ -2,34 +2,12 @@
<string name="app_name">Schlichte Taschenlampe</string> <string name="app_name">Schlichte Taschenlampe</string>
<string name="app_launcher_name">Taschenlampe</string> <string name="app_launcher_name">Taschenlampe</string>
<string name="camera_error">Beanspruchen der Kamera fehlgeschlagen</string> <string name="camera_error">Beanspruchen der Kamera fehlgeschlagen</string>
<string name="ok">OK</string>
<string name="camera_permission">Kamera-Berechtigung ist für den Stroboskopeffekt erforderlich</string> <string name="camera_permission">Kamera-Berechtigung ist für den Stroboskopeffekt erforderlich</string>
<!-- Settings --> <!-- Settings -->
<string name="settings">Einstellungen</string>
<string name="dark_theme">Dunkles Design</string>
<string name="bright_display">Zeige Button für helles Display</string> <string name="bright_display">Zeige Button für helles Display</string>
<string name="show_stroboscope">Zeige Button für Stroboskop</string> <string name="show_stroboscope">Zeige Button für Stroboskop</string>
<!-- About -->
<string name="about">Über</string>
<string name="website">Weitere einfache Apps und Quellcode findest du auf:\nhttp://simplemobiletools.com</string>
<string name="email_label">Sende Vorschläge und Feedback an:</string>
<string name="third_party_licences_underlined"><u>Drittanbieterlizenzen</u></string>
<string name="invite_friends_underlined"><u>Freunde einladen</u></string>
<string name="share_text">Hey, wirf mal einen Blick auf %1$s: %2$s</string>
<string name="invite_via">Einladen via</string>
<string name="rate_us_underlined"><u>Bewerte uns im Play Store</u></string>
<string name="follow_us">Folge uns:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!--License-->
<string name="notice">Diese App nutzt die folgenden Drittanbieterbibliotheken, die mein Leben einfacher machen. Danke.</string>
<string name="third_party_licences">Drittanbieterlizenzen</string>
<string name="butterknife_title">Butter Knife (View Injector)</string>
<string name="ambilwarna_title"><u>AmbilWarna (Color Picker)</u></string>
<string name="otto_title"><u>Otto (Event Bus)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Eine schlichte Taschenlampe ohne Werbung.</string> <string name="app_short_description">Eine schlichte Taschenlampe ohne Werbung.</string>
<string name="app_long_description"> <string name="app_long_description">

View File

@ -2,40 +2,13 @@
<string name="app_name">Simple Flashlight</string> <string name="app_name">Simple Flashlight</string>
<string name="app_launcher_name">Linterna</string> <string name="app_launcher_name">Linterna</string>
<string name="camera_error">Ha fallado el acceso a la cámara</string> <string name="camera_error">Ha fallado el acceso a la cámara</string>
<string name="ok">Ok</string>
<string name="camera_permission">El permiso de acceso a la cámara es necesario para un apropiado efecto estroboscópico</string> <string name="camera_permission">El permiso de acceso a la cámara es necesario para un apropiado efecto estroboscópico</string>
<!-- Settings -->
<string name="settings">Opciones</string>
<string name="dark_theme">Tema oscuro</string>
<string name="bright_display">Mostrar un botón de brillo</string>
<string name="show_stroboscope">Mostrar un botón de estroboscopio</string>
<!-- About -->
<string name="about">Acerca de Simple Flashlight</string>
<string name="website">Más aplicaciones simples y su código fuente en:\nhttp://simplemobiletools.com</string>
<string name="email_label">Envíe sus comentarios y sugerencias a:</string>
<string name="third_party_licences_underlined"><u>Licencias de terceros</u></string>
<string name="invite_friends_underlined"><u>Invitar a amigos</u></string>
<string name="share_text">Hola, venga y échele un vistazo a %1$s en %2$s</string>
<string name="invite_via">Invitar vía</string>
<string name="rate_us_underlined"><u>Evalúenos en Google Play Store</u></string>
<string name="follow_us">Síganos:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!--License-->
<string name="notice">Esta aplicación usa las siguientes librerías de terceros para hacerme la vida más fácil. Gracias.</string>
<string name="third_party_licences">Licencias de terceros</string>
<string name="butterknife_title"><u>Butter Knife (Inyector de vistas)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (Selector de colores)</u></string>
<string name="otto_title"><u>Otto (Canal de eventos)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Una simple linterna sin anuncios.</string> <string name="app_short_description">Una simple linterna sin anuncios.</string>
<string name="app_long_description"> <string name="app_long_description">
Una sencilla linterna con brillo extra de pantalla y un personalizable estroboscopio. Si la enciende a través de la aplicación (no del widget), prevendrá que el dispositivo se duerma. Una sencilla linterna con brillo extra de pantalla y un personalizable estroboscopio. Si la enciende a través de la aplicación (no del widget), prevendrá que el dispositivo se duerma.
Viene con un widget 1x1 con color personalizable. Viene con un widget 1x1 con color personalizable.
No contiene anuncios ni permisos innecesarios. Es completamente OpenSource y además provee un tema oscuro. No contiene anuncios ni permisos innecesarios. Es completamente OpenSource y además provee un tema oscuro.

View File

@ -2,40 +2,17 @@
<string name="app_name">Simple Flashlight</string> <string name="app_name">Simple Flashlight</string>
<string name="app_launcher_name">Flashlight</string> <string name="app_launcher_name">Flashlight</string>
<string name="camera_error">Rilevamento fotocamera fallito</string> <string name="camera_error">Rilevamento fotocamera fallito</string>
<string name="ok">OK</string>
<string name="camera_permission">Camera permission is necessary for proper stroboscope effect</string> <string name="camera_permission">Camera permission is necessary for proper stroboscope effect</string>
<!-- Settings --> <!-- Settings -->
<string name="settings">Impostazioni</string>
<string name="dark_theme">Tema scuro</string>
<string name="bright_display">Mostra un pulsante per schermo luminoso</string> <string name="bright_display">Mostra un pulsante per schermo luminoso</string>
<string name="show_stroboscope">Show a stroboscope button</string> <string name="show_stroboscope">Show a stroboscope button</string>
<!-- About -->
<string name="about">Informazioni</string>
<string name="website">Altre semplici app e codici sorgenti in:\nhttp://simplemobiletools.com</string>
<string name="email_label">Invia la tua opinione o i tuoi suggerimenti a:</string>
<string name="third_party_licences_underlined"><u>Licenze di terze parti</u></string>
<string name="invite_friends_underlined"><u>Invite friends</u></string>
<string name="share_text">Hey, come check out %1$s at %2$s</string>
<string name="invite_via">Invite via</string>
<string name="rate_us_underlined"><u>Dacci un voto sul Play Store</u></string>
<string name="follow_us">Seguici:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!--License-->
<string name="notice">Questa app usa le seguenti librerie di terze parti per semplificarmi la vita. Grazie.</string>
<string name="third_party_licences">Licenze di terze parti</string>
<string name="butterknife_title">Butter Knife (view injector)</string>
<string name="ambilwarna_title"><u>AmbilWarna (color picker)</u></string>
<string name="otto_title"><u>Otto (event bus)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">A simple flashlight without ads.</string> <string name="app_short_description">A simple flashlight without ads.</string>
<string name="app_long_description"> <string name="app_long_description">
A clean flashlight with an extra bright display and customizable stroboscope. If turned on via the app (not widget), it will prevent the device from falling asleep. A clean flashlight with an extra bright display and customizable stroboscope. If turned on via the app (not widget), it will prevent the device from falling asleep.
Comes with a 1x1 widget with customizable color. Comes with a 1x1 widget with customizable color.
Contains no ads or unnecessary permissions. It is fully opensource, provides a Dark theme too. Contains no ads or unnecessary permissions. It is fully opensource, provides a Dark theme too.

View File

@ -2,40 +2,17 @@
<string name="app_name">シンプル フラッシュライト</string> <string name="app_name">シンプル フラッシュライト</string>
<string name="app_launcher_name">フラッシュライト</string> <string name="app_launcher_name">フラッシュライト</string>
<string name="camera_error">カメラの取得に失敗しました</string> <string name="camera_error">カメラの取得に失敗しました</string>
<string name="ok">OK</string>
<string name="camera_permission">適切なストロボ効果のために、カメラのアクセス許可が必要です</string> <string name="camera_permission">適切なストロボ効果のために、カメラのアクセス許可が必要です</string>
<!-- Settings --> <!-- Settings -->
<string name="settings">設定</string>
<string name="dark_theme">ダークテーマ</string>
<string name="bright_display">明るく表示ボタンを表示</string> <string name="bright_display">明るく表示ボタンを表示</string>
<string name="show_stroboscope">ストロボボタンを表示</string> <string name="show_stroboscope">ストロボボタンを表示</string>
<!-- About -->
<string name="about">アプリについて</string>
<string name="website">もっとシンプルなアプリとソースコード:\nhttp://simplemobiletools.com</string>
<string name="email_label">ご意見やご提案を送信してください:</string>
<string name="third_party_licences_underlined"><u>サードパーティー ライセンス</u></string>
<string name="invite_friends_underlined"><u>友達を招待</u></string>
<string name="share_text">%2$s で %1$s を確認してください</string>
<string name="invite_via">招待...</string>
<string name="rate_us_underlined"><u>Play ストアで評価してください</u></string>
<string name="follow_us">フォローしてください:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!--License-->
<string name="notice">このアプリは、私の暮らしにゆとりを持たせるために、次のサードパーティのライブラリーを使用しています。 ありがとうございます。</string>
<string name="third_party_licences">サードパーティー ライセンス</string>
<string name="butterknife_title">Butter Knife (ビュー インジェクター)</string>
<string name="ambilwarna_title"><u>AmbilWarna (カラー ピッカー)</u></string>
<string name="otto_title"><u>Otto (イベント バス)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">広告のないシンプルな懐中電灯です。</string> <string name="app_short_description">広告のないシンプルな懐中電灯です。</string>
<string name="app_long_description"> <string name="app_long_description">
特別に明るく表示とカスタマイズ可能なストロボを備えたシンプルな懐中電灯です。 (ウィジェットではなく)アプリでオンにすると、デバイスがスリープ状態にならないようになります。 特別に明るく表示とカスタマイズ可能なストロボを備えたシンプルな懐中電灯です。 (ウィジェットではなく)アプリでオンにすると、デバイスがスリープ状態にならないようになります。
カスタマイズ可能な色の 1x1 ウィジェットが付属しています。 カスタマイズ可能な色の 1x1 ウィジェットが付属しています。
広告や不要なアクセス許可は含まれていません。 完全にオープンソースで、ダークテーマも提供しています。 広告や不要なアクセス許可は含まれていません。 完全にオープンソースで、ダークテーマも提供しています。

View File

@ -2,40 +2,17 @@
<string name="app_name">Simple Flashlight</string> <string name="app_name">Simple Flashlight</string>
<string name="app_launcher_name">Lanterna</string> <string name="app_launcher_name">Lanterna</string>
<string name="camera_error">Falha ao obter a câmara</string> <string name="camera_error">Falha ao obter a câmara</string>
<string name="ok">OK</string>
<string name="camera_permission">A permissão da câmara é necessária para utilizar o efeito estroboscópico</string> <string name="camera_permission">A permissão da câmara é necessária para utilizar o efeito estroboscópico</string>
<!-- Settings --> <!-- Settings -->
<string name="settings">Definições</string>
<string name="dark_theme">Tema escuro</string>
<string name="bright_display">Mostrar botão para iluminar o ecrã</string> <string name="bright_display">Mostrar botão para iluminar o ecrã</string>
<string name="show_stroboscope">Mostrar botão de estroboscópio</string> <string name="show_stroboscope">Mostrar botão de estroboscópio</string>
<!-- About -->
<string name="about">Acerca</string>
<string name="website">Mais aplicações Simple e código fonte em:\nhttp://simplemobiletools.com</string>
<string name="email_label">Envie os seus comentários ou sugestões para:</string>
<string name="third_party_licences_underlined"><u>Licenças de terceiros</u></string>
<string name="invite_friends_underlined"><u>Convidar amigos</u></string>
<string name="share_text">Olá, experimenta %1$s em %2$s</string>
<string name="invite_via">Convidar via</string>
<string name="rate_us_underlined"><u>Avalie-nos na Play Store</u></string>
<string name="follow_us">Siga-nos:</string>
<string name="copyright">V %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!--License-->
<string name="notice">Esta aplicação usa as seguintes bibliotecas de terceiros para facilitar a minha vida. Obrigado.</string>
<string name="third_party_licences">Licenças de terceiros</string>
<string name="butterknife_title">Butter Knife (injetor de vistas)</string>
<string name="ambilwarna_title"><u>AmbilWarna (selector de sores)</u></string>
<string name="otto_title"><u>Otto (canal de eventos)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">Um lanterna básica.</string> <string name="app_short_description">Um lanterna básica.</string>
<string name="app_long_description"> <string name="app_long_description">
Uma lanterna simples com um brilho extra e um estroboscópio personalizável. Pode ser ativada na aplicação (não no widget), impedindo o adormecimento do dispositivo. Uma lanterna simples com um brilho extra e um estroboscópio personalizável. Pode ser ativada na aplicação (não no widget), impedindo o adormecimento do dispositivo.
Disponibiliza um widget 1x1 com uma cor personalizável. Disponibiliza um widget 1x1 com uma cor personalizável.
Não contém anúncios nem permissões desnecessárias. Disponibiliza um tema escuro e é totalmente \'open source\'. Não contém anúncios nem permissões desnecessárias. Disponibiliza um tema escuro e é totalmente \'open source\'.

View File

@ -2,40 +2,17 @@
<string name="app_name">Simple Flashlight</string> <string name="app_name">Simple Flashlight</string>
<string name="app_launcher_name">Ficklampa</string> <string name="app_launcher_name">Ficklampa</string>
<string name="camera_error">Det gick inte att komma åt kameran</string> <string name="camera_error">Det gick inte att komma åt kameran</string>
<string name="ok">OK</string>
<string name="camera_permission">Kamerabehörigheten behövs för en riktig stroboskopeffekt</string> <string name="camera_permission">Kamerabehörigheten behövs för en riktig stroboskopeffekt</string>
<!-- Settings --> <!-- Settings -->
<string name="settings">Inställningar</string>
<string name="dark_theme">Mörkt tema</string>
<string name="bright_display">Visa en knapp för ljus skärm</string> <string name="bright_display">Visa en knapp för ljus skärm</string>
<string name="show_stroboscope">Visa en stroboskopknapp</string> <string name="show_stroboscope">Visa en stroboskopknapp</string>
<!-- About -->
<string name="about">Om</string>
<string name="website">Fler enkla appar och källkod här:\nhttp://simplemobiletools.com</string>
<string name="email_label">Skicka feedback och förslag till:</string>
<string name="third_party_licences_underlined"><u>Tredjepartslicenser</u></string>
<string name="invite_friends_underlined"><u>Bjud in vänner</u></string>
<string name="share_text">Hej, läs om %1$s på %2$s</string>
<string name="invite_via">Bjud in via</string>
<string name="rate_us_underlined"><u>Betygsätt oss i Play Butiken</u></string>
<string name="follow_us">Följ oss:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!--License-->
<string name="notice">Denna app använder följande tredjepartsbibliotek för att göra mitt liv enklare. Tack.</string>
<string name="third_party_licences">Tredjepartslicenser</string>
<string name="butterknife_title"><u>Butter Knife (vyinjektor)</u></string>
<string name="ambilwarna_title"><u>AmbilWarna (färgväljare)</u></string>
<string name="otto_title"><u>Otto (händelsebuss)</u></string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">En enkel ficklampa utan reklam.</string> <string name="app_short_description">En enkel ficklampa utan reklam.</string>
<string name="app_long_description"> <string name="app_long_description">
En ren ficklampa med en extra ljus skärm och ett anpassningsbart stroboskop. Om den slås på via appen (inte widgeten), hindrar den enheten från att försättas i viloläge. En ren ficklampa med en extra ljus skärm och ett anpassningsbart stroboskop. Om den slås på via appen (inte widgeten), hindrar den enheten från att försättas i viloläge.
Har en 1x1-widget med anpassningsbar färg. Har en 1x1-widget med anpassningsbar färg.
Innehåller ingen reklam eller onödiga behörigheter. Den har helt öppen källkod och har även ett Mörkt tema. Innehåller ingen reklam eller onödiga behörigheter. Den har helt öppen källkod och har även ett Mörkt tema.

View File

@ -1,6 +0,0 @@
<resources>
<dimen name="social_padding">12dp</dimen>
<dimen name="social_logo">50dp</dimen>
<dimen name="normal_text_size">18sp</dimen>
</resources>

View File

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="colorPrimary">#fff68630</color>
<color name="colorPrimaryDark">#ffe27725</color>
<color name="colorAccent">@color/colorPrimary</color>
<color name="translucent_white">#eeffffff</color> <color name="translucent_white">#eeffffff</color>
<color name="translucent_black">#88000000</color> <color name="translucent_black">#88000000</color>
</resources> </resources>

View File

@ -1,13 +1,6 @@
<resources> <resources>
<dimen name="activity_margin">16dp</dimen>
<dimen name="buttons_margin">30dp</dimen> <dimen name="buttons_margin">30dp</dimen>
<dimen name="social_padding">8dp</dimen>
<dimen name="social_logo">40dp</dimen>
<dimen name="settings_padding">8dp</dimen>
<dimen name="seekbar_width">250dp</dimen> <dimen name="seekbar_width">250dp</dimen>
<dimen name="seekbar_vertical_padding">6dp</dimen> <dimen name="seekbar_vertical_padding">6dp</dimen>
<dimen name="main_button_size">150dp</dimen> <dimen name="main_button_size">150dp</dimen>
<dimen name="normal_text_size">14sp</dimen>
<dimen name="config_text_size">18sp</dimen>
</resources> </resources>

View File

@ -2,50 +2,20 @@
<string name="app_name">Simple Flashlight</string> <string name="app_name">Simple Flashlight</string>
<string name="app_launcher_name">Flashlight</string> <string name="app_launcher_name">Flashlight</string>
<string name="camera_error">Obtaining the camera failed</string> <string name="camera_error">Obtaining the camera failed</string>
<string name="ok">OK</string>
<string name="camera_permission">Camera permission is necessary for proper stroboscope effect</string> <string name="camera_permission">Camera permission is necessary for proper stroboscope effect</string>
<!-- Settings --> <!-- Settings -->
<string name="settings">Settings</string>
<string name="dark_theme">Dark theme</string>
<string name="bright_display">Show a bright display button</string> <string name="bright_display">Show a bright display button</string>
<string name="show_stroboscope">Show a stroboscope button</string> <string name="show_stroboscope">Show a stroboscope button</string>
<!-- About -->
<string name="about">About</string>
<string name="website">More simple apps and source code at:\nhttp://simplemobiletools.com</string>
<string name="email_label">Send your feedback or suggestions to:</string>
<string name="email" translatable="false">hello@simplemobiletools.com</string>
<string name="third_party_licences_underlined"><u>Third party licenses</u></string>
<string name="invite_friends_underlined"><u>Invite friends</u></string>
<string name="share_text">Hey, come check out %1$s at %2$s</string>
<string name="invite_via">Invite via</string>
<string name="rate_us_underlined"><u>Rate us in the Play Store</u></string>
<string name="follow_us">Follow us:</string>
<string name="copyright">v %1$s\nCopyright © Simple Mobile Tools %2$d</string>
<!--License-->
<string name="notice">This app uses the following third party libraries to make my life easier. Thank you.</string>
<string name="third_party_licences">Third party licenses</string>
<string name="butterknife_title">Butter Knife (view injector)</string>
<string name="butterknife_text" translatable="false">Copyright 2013 Jake Wharton\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="butterknife_url" translatable="false">https://github.com/JakeWharton/butterknife</string>
<string name="ambilwarna_title"><u>AmbilWarna (color picker)</u></string>
<string name="ambilwarna_text" translatable="false">Copyright 2009-2015 Yuku\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="ambilwarna_url" translatable="false">https://github.com/yukuku/ambilwarna</string>
<string name="otto_title"><u>Otto (event bus)</u></string>
<string name="otto_text" translatable="false">Copyright 2012 Square, Inc.\nCopyright 2010 Google, Inc.\n\nLicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</string>
<string name="otto_url" translatable="false">https://github.com/square/otto</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<string name="app_short_description">A simple flashlight without ads.</string> <string name="app_short_description">A simple flashlight without ads.</string>
<string name="app_long_description"> <string name="app_long_description">
A clean flashlight with an extra bright display and customizable stroboscope. If turned on via the app (not widget), it will prevent the device from falling asleep. A clean flashlight with an extra bright display and customizable stroboscope. If turned on via the app (not widget), it will prevent the device from falling asleep.
Comes with a 1x1 widget with customizable color. Comes with a 1x1 widget with customizable color.
Contains no ads or unnecessary permissions. It is fully opensource, provides a Dark theme too. Contains no ads or unnecessary permissions. It is fully opensource, provides customizable colors.
This app is just one piece of a bigger series of apps. You can find the rest of them at http://www.simplemobiletools.com This app is just one piece of a bigger series of apps. You can find the rest of them at http://www.simplemobiletools.com
</string> </string>

View File

@ -1,38 +1,5 @@
<resources> <resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="AppTheme" parent="AppTheme.Base"/>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="actionBarStyle">@style/AppTheme.ActionBarStyle</item>
<item name="android:textSize">@dimen/normal_text_size</item>
</style>
<style name="AppTheme.Dark" parent="Theme.AppCompat">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="actionBarStyle">@style/AppTheme.ActionBarStyle</item>
<item name="android:textSize">@dimen/normal_text_size</item>
<item name="android:windowBackground">@android:color/black</item>
</style>
<style name="BlackSplashScreen.Dark" parent="AppTheme.Dark">
<item name="android:windowBackground">@null</item>
</style>
<style name="MyWidgetConfigTheme" parent="@style/AppTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowShowWallpaper">true</item>
</style>
<style name="AppTheme.ActionBarStyle" parent="@style/Base.Widget.AppCompat.ActionBar">
<item name="background">@color/colorPrimary</item>
<item name="titleTextStyle">@style/AppTheme.ActionBar.TitleTextStyle</item>
</style>
<style name="AppTheme.ActionBar.TitleTextStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:fontFamily">sans-serif</item>
<item name="android:textSize">20sp</item>
</style>
</resources> </resources>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" <appwidget-provider
android:configure="com.simplemobiletools.flashlight.activities.WidgetConfigureActivity" xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget" android:configure="com.simplemobiletools.flashlight.activities.WidgetConfigureActivity"
android:minHeight="40dp" android:initialLayout="@layout/widget"
android:minWidth="40dp" android:minHeight="40dp"
android:previewImage="@drawable/circles_small"/> android:minWidth="40dp"
android:previewImage="@drawable/circles_small"/>

View File

@ -6,7 +6,6 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files