[Cleanup] Added translations, made use of resources, etc

Some cleanup, added resources for dimensions, added
translations.
This commit is contained in:
Alexander Dörflinger
2025-04-01 10:43:30 +02:00
parent ed2693236c
commit 10d4b5c117
20 changed files with 1061 additions and 41 deletions

View File

@@ -43,7 +43,7 @@ dependencies {
// Glide // Glide
implementation 'com.github.bumptech.glide:glide:4.16.0' implementation 'com.github.bumptech.glide:glide:4.16.0'
implementation 'androidx.preference:preference:1.2.0'// Check for the latest version implementation 'androidx.preference:preference:1.2.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
//CircleImageView //CircleImageView

View File

@@ -2,6 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
@@ -9,6 +13,7 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@@ -19,26 +24,40 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.MyApplication" android:theme="@style/Theme.MyApplication"
tools:targetApi="31"> tools:targetApi="33">
<activity
android:name=".SettingsActivity"
android:exported="false"
android:label="@string/title_activity_settings" />
<meta-data <meta-data
android:name="com.google.android.geo.API_KEY" android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyBrwogmBLNjbhngmON_RWhKrV1woF6ypR4" /> android:value="AIzaSyB7C4QCJEBvS7mFa_DeIZdzqe2hddtl-vk" />
<activity
android:name=".FlashlightActivity"
android:exported="false"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".SettingsActivity"
android:exported="false"
android:label="@string/title_activity_settings"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity <activity
android:name=".HelperGridActivity" android:name=".HelperGridActivity"
android:exported="true"> android:exported="true"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".ShareLocationActivity" />
<activity
android:name=".ShareLocationActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<service <service
android:name=".workers.SleepTimerHelper" android:name=".workers.SleepTimerHelper"

View File

@@ -0,0 +1,117 @@
package com.aldo.apps.familyhelpers;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.PorterDuff;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.aldo.apps.familyhelpers.ui.FlashLightLevelShifter;
import com.aldo.apps.familyhelpers.utils.FlashlightHelper;
import com.google.android.material.button.MaterialButton;
/**
* Activity offering access to the devices flashlight and offering some helper methods to it.
*/
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
public class FlashlightActivity extends AppCompatActivity {
/**
* Tag for debugging purpose.
*/
private static final String TAG = "FlashlightActivity";
/**
* {@link ImageView} indicating the current status of the flashlight.
*/
private ImageView mLightOnIndicator;
/**
* The custom view {@link FlashLightLevelShifter} to adjust the privacy.
*/
private FlashLightLevelShifter mFlashlightLevelShifter;
/**
* Helper class to handle flashlight related code.
*/
private FlashlightHelper mFlashlightHelper;
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flashlight);
initButtons();
mLightOnIndicator = findViewById(R.id.flashlight_status_indicator);
mFlashlightLevelShifter = findViewById(R.id.flashlight_level_shifter);
mFlashlightHelper = new FlashlightHelper(this);
mFlashlightLevelShifter.setMaxProgress(mFlashlightHelper.getMaxBrightness());
mFlashlightLevelShifter.setProgress(mFlashlightHelper.getCurrentBrightness());
mLightOnIndicator.setOnClickListener(v -> mFlashlightHelper.toggleFlashlight());
mFlashlightLevelShifter.setOnProgressChangedListener(progress
-> mFlashlightHelper.setFlashlightBrightness(progress));
mFlashlightHelper.getStatusObservable()
.subscribe(this::onFlashlightStatusChanged, this::handleSubscriptionError);
}
private void initButtons() {
final MaterialButton minimumBrightness = findViewById(R.id.btn_flashlight_lowest);
minimumBrightness.setOnClickListener(v -> {
mFlashlightLevelShifter.setProgress(1);
mFlashlightHelper.setFlashlightBrightness(1);
});
final MaterialButton mediumBrightness = findViewById(R.id.btn_flashlight_medium);
mediumBrightness.setOnClickListener(v -> {
final int maxBrightness = mFlashlightHelper.getMaxBrightness();
mFlashlightLevelShifter.setProgress(maxBrightness/2);
mFlashlightHelper.setFlashlightBrightness(maxBrightness/2);
});
final MaterialButton maximumBrightness = findViewById(R.id.btn_flashlight_maximum);
maximumBrightness.setOnClickListener(v -> {
final int maxBrightness = mFlashlightHelper.getMaxBrightness();
mFlashlightLevelShifter.setProgress(maxBrightness);
mFlashlightHelper.setFlashlightBrightness(maxBrightness);
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mFlashlightHelper.destroy();
}
/**
* Apply new ImageResource and color to the {@link #mLightOnIndicator}.
*
* @param status true if flashlight on, false otherwise.
*/
private void onFlashlightStatusChanged(final boolean status) {
if (status) {
mLightOnIndicator.setImageResource(R.drawable.ic_flashlight_on);
mLightOnIndicator.setColorFilter(getColor(
R.color.md_theme_primary_highContrast), PorterDuff.Mode.SRC_IN);
} else {
mLightOnIndicator.setImageResource(R.drawable.ic_flashlight_off);
mLightOnIndicator.setColorFilter(getColor(
R.color.md_theme_outline), PorterDuff.Mode.SRC_IN);
}
}
/**
* Helper method to print any potential errors while subscribing to the current status observable.
*
* @param throwable The error that has been thrown.
*/
private void handleSubscriptionError(final Throwable throwable) {
Log.e(TAG, "handleSubscriptionError: Error while listening to flashlight status", throwable);
}
}

View File

@@ -1,5 +1,6 @@
package com.aldo.apps.familyhelpers; package com.aldo.apps.familyhelpers;
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.POST_NOTIFICATIONS; import static android.Manifest.permission.POST_NOTIFICATIONS;
import static com.aldo.apps.familyhelpers.utils.GlobalConstants.SIGN_IN_PROVIDERS; import static com.aldo.apps.familyhelpers.utils.GlobalConstants.SIGN_IN_PROVIDERS;
@@ -50,6 +51,11 @@ public class HelperGridActivity extends AppCompatActivity {
*/ */
private HelperGroupTile mShareLocationTile; private HelperGroupTile mShareLocationTile;
/**
* {@link HelperGroupTile} holding the flashlight.
*/
private HelperGroupTile mFlashlightTile;
/** /**
* {@link HelperGroupTile} holding the settings. * {@link HelperGroupTile} holding the settings.
*/ */
@@ -115,6 +121,7 @@ public class HelperGridActivity extends AppCompatActivity {
mDevicePolicyHelper = DevicePolicyManagerHelper.getInstance(this); mDevicePolicyHelper = DevicePolicyManagerHelper.getInstance(this);
initSleepTimer(); initSleepTimer();
initShareLocation(); initShareLocation();
initFlashlight();
initSettings(); initSettings();
} }
@@ -173,6 +180,23 @@ public class HelperGridActivity extends AppCompatActivity {
mShareLocationTile.setTitle(R.string.title_share_location); mShareLocationTile.setTitle(R.string.title_share_location);
} }
/**
* Helper method to initialize the settings tile.
*/
private void initFlashlight() {
mFlashlightTile = new HelperGroupTile(findViewById(R.id.tile_flashlight)) {
@Override
public void launchHelper() {
if (requestCameraPermission()) {
final Intent intent = new Intent(HelperGridActivity.this, FlashlightActivity.class);
startActivity(intent);
}
}
};
mFlashlightTile.setTitle(R.string.title_flashlight);
mFlashlightTile.setLogo(R.drawable.ic_flashlight);
}
/** /**
* Helper method to initialize the settings tile. * Helper method to initialize the settings tile.
*/ */
@@ -208,6 +232,27 @@ public class HelperGridActivity extends AppCompatActivity {
} }
} }
/**
* Helper method to request the CameraPermission as it is required to access the
* flashlight settings.
*
* @return true if the permission is granted, false otherwise.
*/
private boolean requestCameraPermission() {
if (ContextCompat.checkSelfPermission(this, CAMERA) ==
PackageManager.PERMISSION_GRANTED) {
// Permission already granted
return true;
} else {
if (shouldShowRequestPermissionRationale(CAMERA)) {
Toast.makeText(HelperGridActivity.this, R.string.flashlight_camera_rationale,
Toast.LENGTH_LONG).show();
}
mRequestPermissionLauncher.launch(CAMERA);
return false;
}
}
/** /**
* Handle the result of the sign in flow. * Handle the result of the sign in flow.
* *

View File

@@ -0,0 +1,317 @@
package com.aldo.apps.familyhelpers.ui;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import com.aldo.apps.familyhelpers.R;
/**
* A custom SeekBar-like view for displaying and selecting a discrete level,
* such as a flashlight brightness level. The view is composed of vertically
* stacked segments, where the number of segments is determined by the
* {@code maxProgress} property.
*
* NOTE: This class was mainly generated and documented by Google-AI.
*/
public class FlashLightLevelShifter extends View {
/**
* The paint used to draw the level segments.
*/
private final Paint mLevelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
/**
* The rectangle used to define the boundaries of each level segment.
*/
private final RectF mLevelRect = new RectF();
/**
* The width of the canvas.
*/
private int mCanvasWidth = 0;
/**
* The height of the canvas.
*/
private int mCanvasHeight = 0;
/**
* The bitmap used to cache the progress drawing.
*/
private Bitmap mProgressBitmap;
/**
* Listener interface for progress change events.
*/
private SeekBarChangeListener mOnProgressChangedListener;
/**
* The maximum progress value. This determines the number of segments.
*/
private int mMaxProgress = 1;
/**
* The current progress value.
*/
private int mProgress = 1;
/**
* The background color of the level segments.
*/
private int mLevelBackgroundColor = Color.LTGRAY;
/**
* The corner radius of the level segments.
*/
private float mLevelCornerRadius;
/**
* The gap between level segments.
*/
private float mLevelGap;
/**
* The color of the filled level segments (representing progress).
*/
private int mLevelProgressColor = Color.WHITE;
/**
* Constructor for FlashLightLevelShifter.
*
* @param context The context.
*/
public FlashLightLevelShifter(final Context context) {
this(context, null);
}
/**
* Constructor for FlashLightLevelShifter.
*
* @param context The context.
* @param attrs The attribute set.
*/
public FlashLightLevelShifter(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* Constructor for FlashLightLevelShifter.
*
* @param context The context.
* @param attrs The attribute set.
* @param defStyleAttr The default style attribute.
*/
public FlashLightLevelShifter(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLevelCornerRadius = calculateDp(4);
mLevelGap = calculateDp(2);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FlashLightLevelShifter);
mLevelBackgroundColor = typedArray.getColor(
R.styleable.FlashLightLevelShifter_level_background_color,
mLevelBackgroundColor
);
mLevelCornerRadius = typedArray.getDimension(
R.styleable.FlashLightLevelShifter_level_corner_radius,
mLevelCornerRadius
);
mLevelGap = typedArray.getDimension(R.styleable.FlashLightLevelShifter_level_gap, mLevelGap);
mLevelProgressColor = typedArray.getColor(
R.styleable.FlashLightLevelShifter_level_progress_color,
mLevelProgressColor
);
typedArray.recycle();
}
/**
* Gets the maximum progress value.
*
* @return The maximum progress value.
*/
public int getMaxProgress() {
return mMaxProgress;
}
/**
* Sets the maximum progress value.
*
* @param maxProgress The maximum progress value.
*/
public void setMaxProgress(final int maxProgress) {
this.mMaxProgress = maxProgress;
this.mProgress = maxProgress;
invalidate();
}
/**
* Gets the current progress value.
*
* @return The current progress value.
*/
public int getProgress() {
return mProgress;
}
/**
* Sets the current progress value.
*
* @param progress The current progress value.
*/
public void setProgress(final int progress) {
setProgressInternal(progress);
}
@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mCanvasWidth = w;
mCanvasHeight = h;
mProgressBitmap = Bitmap.createBitmap(getAvailableWidth(), getAvailableHeight(), Bitmap.Config.ARGB_8888);
}
@Override
protected void onDraw(final Canvas canvas) {
canvas.clipRect(
getPaddingLeft(),
getPaddingTop(),
mCanvasWidth,
mCanvasHeight
);
int availableWidth = getAvailableWidth();
int availableHeight = getAvailableHeight();
float totalLevelHeight = (float) availableHeight / mMaxProgress;
float levelHeight = totalLevelHeight - mLevelGap;
float previousLevelBottom = getPaddingTop();
for (int i = 0; i < mMaxProgress; i++) {
mLevelRect.set(
getPaddingLeft(),
previousLevelBottom,
availableWidth + getPaddingRight(),
previousLevelBottom + levelHeight
);
if (i + 1 <= mProgress) {
mLevelPaint.setColor(mLevelBackgroundColor);
} else {
mLevelPaint.setColor(mLevelProgressColor);
}
canvas.drawRoundRect(mLevelRect, mLevelCornerRadius, mLevelCornerRadius, mLevelPaint);
previousLevelBottom = mLevelRect.bottom + mLevelGap;
}
}
/**
* Sets the listener for progress change events.
*
* @param changedListener The listener to set.
*/
public void setOnProgressChangedListener(final SeekBarChangeListener changedListener) {
mOnProgressChangedListener = changedListener;
}
/**
*
* @param event
*/
private void updateProgress(final MotionEvent event) {
if (getRawProgress(event) != mProgress) {
mProgress = getRawProgress(event);
if (mOnProgressChangedListener != null) {
mOnProgressChangedListener.onProgressChanged(mMaxProgress - mProgress);
}
invalidate();
}
}
/**
* Gets the raw progress value from a MotionEvent.
*
* @param event The MotionEvent.
* @return The raw progress value.
*/
private int getRawProgress(final MotionEvent event) {
return Math.round(mMaxProgress * event.getY() / getAvailableHeight());
}
/**
* Sets the progress internally and triggers a redraw.
*
* @param progress The new progress value.
*/
protected void setProgressInternal(final int progress) {
this.mProgress = mMaxProgress - progress;
invalidate();
}
/**
* Gets the available width for drawing the level segments.
*
* @return The available width.
*/
private int getAvailableWidth() {
int width = mCanvasWidth - getPaddingLeft() - getPaddingRight();
if (width <= 0) width = 1;
return width;
}
/**
* Gets the available height for drawing the level segments.
*
* @return The available height.
*/
private int getAvailableHeight() {
int height = mCanvasHeight - getPaddingTop() - getPaddingBottom();
if (height <= 0) height = 1;
return height;
}
@Override
public boolean onTouchEvent(final MotionEvent event) {
if (!isEnabled()) return false;
if (event != null) {
updateProgress(event);
performClick();
}
return true;
}
@Override
public boolean performClick() {
super.performClick();
return true;
}
private float calculateDp(final int dp) {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
getResources().getDisplayMetrics()
);
}
/**
* Interface definition for a callback to be invoked when the progress
* level is changed.
*/
public interface SeekBarChangeListener {
/**
* Called when the progress level is changed.
*
* @param progress The new progress level.
*/
void onProgressChanged(final int progress);
}
}

View File

@@ -0,0 +1,202 @@
package com.aldo.apps.familyhelpers.utils;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import io.reactivex.rxjava3.subjects.BehaviorSubject;
/**
* Helper class to encapsulate all flashlight related logic.
*/
public class FlashlightHelper {
/**
* Tag for debugging purposes.
*/
private static final String TAG = "FlashlightHelper";
/**
* {@link BehaviorSubject} holding the current status of the flashlight.
*/
private final BehaviorSubject<Boolean> mFlashlightStatusObservable = BehaviorSubject.createDefault(false);
/**
* The {@link CameraManager} to get access to the flashlight.
*/
private final CameraManager mCameraManager;
/**
* Unique identifier of the camera that has a flashlight.
*/
private String mCameraId;
/**
* Max available brightness level.
*/
private Integer mMaxBrightness;
/**
* The currently selected brightness level (defaults to MAX)
*/
private Integer mCurrentBrightness;
/**
* The {@link CameraManager.TorchCallback} to be invoked when the flashlight status or availability
* changes.
*/
private final CameraManager.TorchCallback mTorchCallback = new CameraManager.TorchCallback() {
@Override
public void onTorchModeUnavailable(@NonNull final String cameraId) {
super.onTorchModeUnavailable(cameraId);
if (TextUtils.equals(mCameraId, cameraId)) {
Log.d(TAG, "onTorchModeUnavailable: Flashlight became unavailable, propagate off");
mFlashlightStatusObservable.onNext(false);
}
}
@Override
public void onTorchModeChanged(@NonNull final String cameraId, final boolean enabled) {
super.onTorchModeChanged(cameraId, enabled);
if (TextUtils.equals(mCameraId, cameraId)) {
Log.d(TAG, "onTorchModeChanged: Flashlight Status changed to [" + enabled + "]");
mFlashlightStatusObservable.onNext(enabled);
}
}
};
/**
* C'Tor.
*
* @param context The {@link Context} from where this was instantiated.
*/
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
public FlashlightHelper(final Context context) {
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
mCameraManager.registerTorchCallback(mTorchCallback, null);
try {
for (final String camId : mCameraManager.getCameraIdList()) {
final CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(camId);
if (Boolean.TRUE.equals(characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE))) {
mCameraId = camId;
mMaxBrightness = characteristics.get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
mCurrentBrightness = characteristics.get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
Log.d(TAG, "maxAvailable = [" + mMaxBrightness + "], current = [" + mCurrentBrightness + "]");
break;
}
}
} catch (final CameraAccessException e) {
Log.e(TAG, "onCreate: ", e);
}
}
/**
* Returns the {@link BehaviorSubject} holding the current status of the flashlight.
*
* @return The {@link BehaviorSubject} holding the current status of the flashlight.
*/
public BehaviorSubject<Boolean> getStatusObservable() {
return mFlashlightStatusObservable;
}
/**
* Returns the max available brightness.
*
* @return The max available brightness.
*/
public int getMaxBrightness() {
return mMaxBrightness == null ? 1 : mMaxBrightness;
}
/**
* Returns the currently set brightness.
*
* @return The currently set brightness.
*/
public int getCurrentBrightness() {
return mCurrentBrightness;
}
/**
* Helper method to toggle the flashlight to on/off based on the current state.
*/
public void toggleFlashlight() {
if (mFlashlightStatusObservable.getValue()) {
Log.d(TAG, "toggleFlashlight: Turning off flashlight");
turnFlashlightOff();
} else {
Log.d(TAG, "toggleFlashlight: Turning on flashlight");
turnFlashlightOn();
}
}
/**
* Sets the provided brightness level if applicable to the flashlight and turns it on.
*
* @param brightnessLevel The brightness level to be set.
*/
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
public void setFlashlightBrightness(final int brightnessLevel) {
if (mCameraId == null) {
Log.e("setFlashlightBrightness", "No camera with flash found.");
return;
}
if (brightnessLevel > mMaxBrightness || brightnessLevel < 1) {
Log.d(TAG, "setFlashlightBrightness: Invalid brightness setting [" + brightnessLevel + "], ignore...");
return;
}
try {
mCameraManager.turnOnTorchWithStrengthLevel(mCameraId, brightnessLevel);
} catch (final CameraAccessException e) {
Log.e("setFlashlightBrightness", "Error setting torch brightness: " + e.getMessage());
}
}
/**
* Turn on the flashlight without changing the brightness level.
*/
public void turnFlashlightOn() {
if (mCameraId == null) {
Log.e("turnFlashlightOn", "No camera with flash found.");
return;
}
try{
mCameraManager.setTorchMode(mCameraId, true);
}catch (final CameraAccessException e){
Log.e("turnFlashlightOn", "Error turning torch on: " + e.getMessage());
}
}
/**
* Turns off the flashlight.
*/
public void turnFlashlightOff() {
if (mCameraId == null) {
Log.e("turnFlashlightOff", "No camera with flash found.");
return;
}
try{
mCameraManager.setTorchMode(mCameraId, false);
}catch(final CameraAccessException e){
Log.e("turnFlashlightOff", "Error turning torch off: " + e.getMessage());
}
}
/**
* Clean up helper method.
*/
public void destroy() {
mCameraManager.unregisterTorchCallback(mTorchCallback);
}
}

View File

@@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="800dp"
android:height="800dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:pathData="M450.49,202.25L308.92,60.67c-19.51,-19.51 -51.27,-19.51 -70.79,0l-32.9,32.9c-11.37,11.37 -19.51,26.11 -22.82,42.63l-18.64,93.21L14.64,378.55c-19.52,19.52 -19.52,51.27 0,70.79l47.19,47.19c19.51,19.51 51.27,19.52 70.79,0l149.13,-149.13l93.21,-18.64c16.13,-3.23 30.97,-11.16 42.63,-22.82l32.9,-32.9C470.06,253.48 470.06,221.81 450.49,202.25zM109.02,472.93c-6.51,6.51 -17.09,6.51 -23.6,0l-47.19,-47.19c-6.51,-6.51 -6.51,-17.09 0,-23.6l11.8,-11.8l70.79,70.79L109.02,472.93zM144.42,437.54l-70.79,-70.79l46.52,-46.52l23.6,23.6c6.51,6.52 17.08,6.52 23.6,0c6.52,-6.52 6.52,-17.08 0,-23.6l-23.6,-23.6l35.4,-35.4l70.79,70.79L144.42,437.54zM279.01,313.92l-81.76,-81.76l15.73,-78.65l144.68,144.68L279.01,313.92zM426.9,249.44c-35.83,35.83 -33.6,33.66 -35.49,35.31L226.42,119.75c1.67,-1.92 -0.43,0.25 35.31,-35.48c6.5,-6.51 17.09,-6.51 23.59,0l141.58,141.58C433.42,232.37 433.42,242.92 426.9,249.44z"
android:fillColor="#000000"/>
<path
android:pathData="M473.8,36.79c-6.67,-6.36 -17.23,-6.1 -23.59,0.57L416.49,72.75c-6.36,6.67 -6.1,17.23 0.57,23.59c6.67,6.36 17.23,6.1 23.59,-0.57l33.72,-35.39C480.73,53.71 480.47,43.15 473.8,36.79z"
android:fillColor="#000000"/>
<path
android:pathData="M361.49,0.83c-9.22,0 -16.68,7.47 -16.68,16.68v33.37c0,9.22 7.47,16.68 16.68,16.68c9.22,0 16.68,-7.47 16.68,-16.68v-33.37C378.17,8.31 370.7,0.83 361.49,0.83z"
android:fillColor="#000000"/>
<path
android:pathData="M495.32,134.11h-33.37c-9.22,0 -16.68,7.47 -16.68,16.68s7.47,16.68 16.68,16.68h33.37c9.22,0 16.68,-7.47 16.68,-16.68S504.53,134.11 495.32,134.11z"
android:fillColor="#000000"/>
</vector>

View File

@@ -0,0 +1,36 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="200"
android:viewportHeight="200">
<path
android:pathData="M37.87,83.58L163.58,83.58A7,7 0,0 1,170.58 90.58L170.58,115.56A7,7 0,0 1,163.58 122.56L37.87,122.56A7,7 0,0 1,30.87 115.56L30.87,90.58A7,7 0,0 1,37.87 83.58z"
android:strokeWidth="3"
android:fillColor="#fff"
android:strokeColor="#000"/>
<path
android:pathData="M31.41,118.61L44.4,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M31.41,118.61L44.4,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M31.41,118.61L44.4,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M169.72,118.58L156.72,170.58"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M43.72,170.58L157.72,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
</vector>

View File

@@ -0,0 +1,51 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="200"
android:viewportHeight="200">
<path
android:pathData="M37.87,83.58L163.58,83.58A7,7 0,0 1,170.58 90.58L170.58,115.56A7,7 0,0 1,163.58 122.56L37.87,122.56A7,7 0,0 1,30.87 115.56L30.87,90.58A7,7 0,0 1,37.87 83.58z"
android:strokeWidth="3"
android:fillColor="#fff"
android:strokeColor="#000"/>
<path
android:pathData="M31.41,118.61L44.4,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M31.41,118.61L44.4,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M31.41,118.61L44.4,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M169.72,118.58L156.72,170.58"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M43.72,170.58L157.72,170.24"
android:strokeWidth="3"
android:fillColor="#00000000"
android:strokeColor="#000"/>
<path
android:pathData="M100,14.44L100,14.44A8.12,10 0,0 1,108.12 24.44L108.12,54.62A8.12,10 0,0 1,100 64.62L100,64.62A8.12,10 0,0 1,91.88 54.62L91.88,24.44A8.12,10 0,0 1,100 14.44z"
android:strokeWidth="3"
android:fillColor="#fff"
android:strokeColor="#000"/>
<path
android:pathData="M44.47,19.7L44.47,19.7A10,8.12 58,0 1,56.65 23.87L72.65,49.47A10,8.12 58,0 1,71.06 62.25L71.06,62.25A10,8.12 58,0 1,58.87 58.08L42.88,32.48A10,8.12 58,0 1,44.47 19.7z"
android:strokeWidth="3"
android:fillColor="#fff"
android:strokeColor="#000"/>
<path
android:pathData="M157.34,19.7L157.34,19.7A10,8.12 122,0 1,158.93 32.48L142.94,58.08A10,8.12 122,0 1,130.75 62.25L130.75,62.25A10,8.12 122,0 1,129.16 49.47L145.15,23.87A10,8.12 122,0 1,157.34 19.7z"
android:strokeWidth="3"
android:fillColor="#fff"
android:strokeColor="#000"/>
</vector>

View File

@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="75dp" android:layout_width="@dimen/active_share_view_holder_width"
android:layout_height="75dp" android:layout_height="@dimen/active_share_view_holder_height"
android:background="@drawable/currently_followed_user_selector" android:background="@drawable/currently_followed_user_selector"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<de.hdodenhof.circleimageview.CircleImageView <de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/active_share_profile_picture" android:id="@+id/active_share_profile_picture"
android:layout_width="50dp" android:layout_width="@dimen/active_share_profile_picture_width"
android:layout_height="50dp" android:layout_height="@dimen/active_share_profile_picture_height"
app:civ_border_width="2dp" app:civ_border_width="@dimen/active_share_profile_picture_border_width"
app:civ_border_color="#FF000000" app:civ_border_color="#FF000000"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@@ -20,7 +20,7 @@
android:id="@+id/active_share_name" android:id="@+id/active_share_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="11sp" android:textSize="@dimen/active_share_profile_name_text_size"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:gravity="center" android:gravity="center"

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".FlashlightActivity">
<ImageView
android:id="@+id/flashlight_status_indicator"
android:src="@drawable/ic_flashlight_off"
android:layout_width="@dimen/flashlight_header_image_width"
android:layout_height="wrap_content"
app:tint="@color/md_theme_outline"
app:layout_constraintBottom_toTopOf="@id/flashlight_level_shifter"
app:layout_constraintStart_toStartOf="@id/flashlight_level_shifter"
app:layout_constraintEnd_toEndOf="@id/flashlight_level_shifter"/>
<com.aldo.apps.familyhelpers.ui.FlashLightLevelShifter
android:id="@+id/flashlight_level_shifter"
android:layout_width="@dimen/flashlight_level_shifter_width"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/flashlight_level_shifter_margin_top"
android:layout_marginEnd="@dimen/flashlight_level_shifter_margin_end"
android:layout_marginBottom="@dimen/flashlight_activity_margin_bottom"
app:level_background_color="@color/md_theme_outline"
app:level_corner_radius="@dimen/flashlight_level_shifter_corner_radius"
app:level_gap="@dimen/flashlight_level_shifter_level_gap"
app:level_progress_color="@color/md_theme_primary_highContrast"
app:layout_constraintEnd_toEndOf="parent"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_flashlight_lowest"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="@integer/flashlight_material_button_max_lines"
android:lines="@integer/flashlight_material_button_lines"
android:layout_marginStart="@dimen/flashlight_material_button_margin_start"
android:layout_marginEnd="@dimen/flashlight_material_button_margin_end"
android:layout_marginBottom="@dimen/flashlight_activity_margin_bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/flashlight_level_shifter"
android:text="@string/flashlight_set_min_level"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_flashlight_medium"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="@integer/flashlight_material_button_max_lines"
android:lines="@integer/flashlight_material_button_lines"
app:layout_constrainedWidth="true"
android:layout_marginStart="@dimen/flashlight_material_button_margin_start"
android:layout_marginEnd="@dimen/flashlight_material_button_margin_end"
app:layout_constraintBottom_toTopOf="@id/btn_flashlight_lowest"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/flashlight_level_shifter"
android:text="@string/flashlight_set_med_level"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_flashlight_maximum"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="@integer/flashlight_material_button_max_lines"
android:lines="@integer/flashlight_material_button_lines"
android:layout_marginStart="@dimen/flashlight_material_button_margin_start"
android:layout_marginEnd="@dimen/flashlight_material_button_margin_end"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@id/btn_flashlight_medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/flashlight_level_shifter"
android:text="@string/flashlight_set_max_level"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -25,21 +25,28 @@
<include layout="@layout/helper_group_tile_item" <include layout="@layout/helper_group_tile_item"
android:id="@+id/tile_sleep_timer" android:id="@+id/tile_sleep_timer"
android:layout_margin="10dp" android:layout_margin="@dimen/main_helper_group_item_margin"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_columnWeight="1"/> android:layout_columnWeight="1"/>
<include layout="@layout/helper_group_tile_item" <include layout="@layout/helper_group_tile_item"
android:id="@+id/tile_share_location" android:id="@+id/tile_share_location"
android:layout_margin="10dp" android:layout_margin="@dimen/main_helper_group_item_margin"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"/>
<include layout="@layout/helper_group_tile_item"
android:id="@+id/tile_flashlight"
android:layout_margin="@dimen/main_helper_group_item_margin"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_columnWeight="1"/> android:layout_columnWeight="1"/>
<include layout="@layout/helper_group_tile_item" <include layout="@layout/helper_group_tile_item"
android:id="@+id/tile_settings" android:id="@+id/tile_settings"
android:layout_margin="10dp" android:layout_margin="@dimen/main_helper_group_item_margin"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_columnWeight="1"/> android:layout_columnWeight="1"/>

View File

@@ -9,7 +9,7 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/active_share_container" android:id="@+id/active_share_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="75dp" android:layout_height="@dimen/share_location_active_share_container_height"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<TextView <TextView
@@ -29,7 +29,6 @@
android:scrollbars="horizontal" android:scrollbars="horizontal"
android:visibility="gone"/> android:visibility="gone"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
@@ -56,8 +55,8 @@
<ImageView <ImageView
android:id="@+id/share_location_info_user_icon" android:id="@+id/share_location_info_user_icon"
android:layout_width="40dp" android:layout_width="@dimen/share_location_currently_following_picture_width"
android:layout_height="40dp" android:layout_height="@dimen/share_location_currently_following_picture_height"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"/> app:layout_constraintEnd_toEndOf="parent"/>

View File

@@ -12,8 +12,8 @@
<ImageView <ImageView
android:id="@+id/iv_helper_group_icon" android:id="@+id/iv_helper_group_icon"
android:layout_width="75dp" android:layout_width="@dimen/helper_group_item_image_width"
android:layout_height="75dp" android:layout_height="@dimen/helper_group_item_image_height"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@@ -26,12 +26,10 @@
app:layout_constraintTop_toBottomOf="@id/iv_helper_group_icon" app:layout_constraintTop_toBottomOf="@id/iv_helper_group_icon"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:gravity="center"
tools:text="Sleep Timer" tools:text="Sleep Timer"
android:textStyle="bold" android:textStyle="bold"
android:maxLines="1" android:maxLines="@integer/helper_group_item_title_max_lines"
android:textColor="@color/md_theme_primary" android:textColor="@color/md_theme_primary"
/> />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Doerflinger-Helpers</string>
<string name="warning_no_device_admin">Diese Aktion benötigt spezielle Geräte-Administratoren Rechte, bitte ertile diese bevor du weitermachts</string>
<string name="welcome_message_placeholder">Wilkommen <b>%s</b></string>
<string name="welcome_message_test">Wilkommen <b>Test Nutzer</b></string>
<string name="unknown_user">Unbekannter Nutzer</string>
<string name="title_sleep_timer">Sleep Timer</string>
<string name="description_sleep_timer">Bietet die Möglichkeit, einen Sleep Timer zu setzen, nach dem das Display ausgeschalten wird</string>
<string name="sleep_timer_rationale_device_admin">Geräte-Administratoren Rechte werden benötigt um den Bildschirm nach einem Timeout auszuschalten</string>
<string name="sleep_timer_show_notifications_rationale">Für diese Funktion wird die Berechtigung eine Benachrichtigung anzuzeigen benötigt</string>
<string name="sleep_timer_notification_content">Sleep-Timer läuft. Das Gerät wird in %s gesperrt</string>
<string name="sleep_timer_notification_cancel">Abbrechen</string>
<string name="title_share_location">Standort teilen</string>
<string name="share_location_notification_content">Du teilst deinen Standort gerade mit der Familie.</string>
<string name="share_location_no_sharings_in_progress">Aktuell teilt niemand seinen Standort</string>
<string name="share_location_info_title_empty">Du folgst gerade niemandem</string>
<string name="share_location_info_title">Du folgst %s</string>
<string name="share_location_info_location">Letzter bekannter Standort = %f;%f</string>
<string name="share_location_info_altitude">Letze bekannte Höhe = %.2f Meter</string>
<string name="share_location_info_speed">Letzte bekannte Geschwindigkeit: %.2f m/s (%.1f km/h)</string>
<string name="share_location_info_timestamp">Dieses Update wurde empfangen: %s</string>
<string name="share_location_toggle_button">Teile deinen Standort</string>
<string name="share_location_background_permission_rationale">Um deinen Standort auch zu teilen, während die App im Hintergrund ist, bitte wähle die \"Immer\" Option.</string>
<string name="title_activity_settings">Einstellungen</string>
<string name="title_flashlight">Taschenlampe</string>
<string name="flashlight_camera_rationale">Um auf die Taschenlampe zugreifen zu können, wird die Kamera Berechtigung gebraucht.</string>
<string name="flashlight_set_min_level">Aktiviere die Taschenlampe auf minimaler Helligkeit</string>
<string name="flashlight_set_med_level">Aktiviere die Taschenlampe auf mittlerer Helligkeit</string>
<string name="flashlight_set_max_level">Aktiviere die Taschenlampe auf maximaler Helligkeit</string>
<string name="title_settings">Einstellungen</string>
<string name="pref_share_location_header">Standort teilen</string>
<string name="pref_share_location_freq_title">Standort Update Frequenz</string>
<string name="pref_share_location_freq_summary">Die Minimal-Zeit in Sekunden zwischen zwei Standort updates. <b>Achtung:</b> Je niedriger dieser Wert, desto höher die Akku-Belastung</string>
<string name="pref_auto_accuracy_title">Automatische Genauigkeit</string>
<string name="pref_auto_accuracy_summary_on">Die Genauigkeit wird automatisch ausgewählt je nach Ladezustand des Geräts</string>
<string name="pref_auto_accuracy_summary_off">Wähle \"Hohe Genauigkeit\" oder \"Akku sparen\" unten aus</string>
<string name="pref_manual_accuracy_title">Hohe Genauigkeit erzwingen</string>
<string name="pref_manual_accuracy_summary_on">Hohe Genauigkeit, leert aber vermutlich den Akku schneller</string>
<string name="pref_manual_accuracy_summary_off">Niedrigere Genauigkeit, aber bessere Akku-Lebensdauer</string>
</resources>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Doerflinger-Helpers</string>
<string name="warning_no_device_admin">The action you would like to perform requires DeviceAdmin privileges, please grant them before continuing.</string>
<string name="welcome_message_placeholder">Welcome <b>%s</b></string>
<string name="welcome_message_test">Welcome <b>User Whatever</b></string>
<string name="unknown_user">Unknown User</string>
<string name="title_sleep_timer">Sleep Timer</string>
<string name="description_sleep_timer">Offers the possibility to set a sleep timer, after which the display will turn off</string>
<string name="sleep_timer_rationale_device_admin">Device Admin privileges are needed for locking the screen after a specified timeout</string>
<string name="sleep_timer_show_notifications_rationale">In order for this feature to work, the app must be allowed to show a Notification</string>
<string name="sleep_timer_notification_content">Sleep timer is scheduled. Your device will lock itself in %s</string>
<string name="sleep_timer_notification_cancel">Cancel</string>
<string name="title_share_location">Share Location</string>
<string name="share_location_notification_content">You are sharing your current location within the family</string>
<string name="share_location_no_sharings_in_progress">Currently nobody is sharing their location</string>
<string name="share_location_info_title_empty">You are currently not following anyone</string>
<string name="share_location_info_title">You are following %s</string>
<string name="share_location_info_location">Last Received Location = %f;%f</string>
<string name="share_location_info_altitude">Last received altitude = %.2f Meters</string>
<string name="share_location_info_speed">The last received velocity was %.2f m/s (%.1f km/h)</string>
<string name="share_location_info_timestamp">This update was received at: %s</string>
<string name="share_location_toggle_button">Share your location</string>
<string name="share_location_background_permission_rationale">In order to share your position also while in the background, please grant the always permission</string>
<string name="title_activity_settings">Settings</string>
<string name="title_flashlight">Flashlight</string>
<string name="flashlight_camera_rationale">In order to have access to the flashlight, you need to grant the Camera permission.</string>
<string name="flashlight_set_min_level">Activate flashlight on minimum brightness</string>
<string name="flashlight_set_med_level">Activate flashlight on medium brightness</string>
<string name="flashlight_set_max_level">Activate flashlight on maximum brightness</string>
<string name="title_settings">Settings</string>
<string name="pref_share_location_header">Share Location</string>
<string name="pref_share_location_freq_title">Location Update frequency</string>
<string name="pref_share_location_freq_summary">The minimum amount of seconds to wait between two location updates <b>Note:</b> The lower the value the higher the battery consumption</string>
<string name="pref_auto_accuracy_title">Automatic accuracy detection</string>
<string name="pref_auto_accuracy_summary_on">Accuracy will be auto selected based on the current charging state</string>
<string name="pref_auto_accuracy_summary_off">Select high accuracy vs. balanced power consumption below</string>
<string name="pref_manual_accuracy_title">Force high accuracy</string>
<string name="pref_manual_accuracy_summary_on">High accuracy for location data, may drain battery faster</string>
<string name="pref_manual_accuracy_summary_off">Lower accuracy for location data, but better battery consumption</string>
</resources>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FlashLightLevelShifter">
<attr name="level_background_color" format="color" />
<attr name="level_corner_radius" format="dimension" />
<attr name="level_gap" format="dimension" />
<attr name="level_progress_color" format="color" />
</declare-styleable>
</resources>

View File

@@ -1,4 +1,44 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<dimen name="text_size_welcome_message">28sp</dimen> <dimen name="text_size_welcome_message">28sp</dimen>
<!-- activity_main -->
<dimen name="main_helper_group_item_margin">10dp</dimen>
<!-- helper_group_tile_item -->
<dimen name="helper_group_item_image_height">75dp</dimen>
<dimen name="helper_group_item_image_width">75dp</dimen>
<integer name="helper_group_item_title_max_lines">1</integer>
<!-- activity_share_location -->
<dimen name="share_location_active_share_container_height">75dp</dimen>
<dimen name="share_location_currently_following_picture_height">40dp</dimen>
<dimen name="share_location_currently_following_picture_width">40dp</dimen>
<!-- active_share_view_holder -->
<dimen name="active_share_view_holder_width">75dp</dimen>
<dimen name="active_share_view_holder_height">75dp</dimen>
<dimen name="active_share_profile_picture_width">50dp</dimen>
<dimen name="active_share_profile_picture_height">50dp</dimen>
<dimen name="active_share_profile_picture_border_width">2dp</dimen>
<dimen name="active_share_profile_name_text_size">11sp</dimen>
<!-- activity_flashlight -->
<dimen name="flashlight_header_image_width">250dp</dimen>
<dimen name="flashlight_level_shifter_width">112dp</dimen>
<dimen name="flashlight_level_shifter_margin_top">200dp</dimen>
<dimen name="flashlight_level_shifter_margin_end">50dp</dimen>
<dimen name="flashlight_level_shifter_corner_radius">8dp</dimen>
<dimen name="flashlight_level_shifter_level_gap">2dp</dimen>
<dimen name="flashlight_activity_margin_bottom">25dp</dimen>
<dimen name="flashlight_material_button_margin_start">20dp</dimen>
<dimen name="flashlight_material_button_margin_end">30dp</dimen>
<integer name="flashlight_material_button_lines">3</integer>
<integer name="flashlight_material_button_max_lines">3</integer>
<!-- root_preferences -->
<integer name="pref_location_update_freq_min">1</integer>
<integer name="pref_location_update_freq_max">60</integer>
<integer name="pref_location_update_freq_increment">1</integer>
<integer name="pref_location_update_freq_default">10</integer>
</resources> </resources>

View File

@@ -1,6 +1,5 @@
<resources> <resources>
<string name="app_name">Doerflinger-Helpers</string> <string name="app_name">Doerflinger-Helpers</string>
<string name="warning_no_device_admin">The action you would like to perform requires DeviceAdmin privileges, please grant them before continuing.</string> <string name="warning_no_device_admin">The action you would like to perform requires DeviceAdmin privileges, please grant them before continuing.</string>
<!-- Global Strings --> <!-- Global Strings -->
@@ -10,29 +9,36 @@
<!-- Sleep Timer Functionality Strings --> <!-- Sleep Timer Functionality Strings -->
<string name="title_sleep_timer">Sleep Timer</string> <string name="title_sleep_timer">Sleep Timer</string>
<string name="sleep_timer_notification_channel">SleepTimer</string> <string name="sleep_timer_notification_channel" translatable="false">SleepTimer</string>
<string name="description_sleep_timer">Offers the possibility top set a sleep timer, after which the display will turn off</string> <string name="description_sleep_timer">Offers the possibility to set a sleep timer, after which the display will turn off</string>
<string name="sleep_timer_rationale_device_admin">Device Admin privileges are needed for locking the screen after a specified timeout</string> <string name="sleep_timer_rationale_device_admin">Device Admin privileges are needed for locking the screen after a specified timeout</string>
<string name="sleep_timer_show_notifications_rationale">In order for this feature to work, the app must be allowed to show a Notification</string> <string name="sleep_timer_show_notifications_rationale">In order for this feature to work, the app must be allowed to show a Notification</string>
<string name="sleep_timer_notification_content">Sleep timer is scheduled. Your device will lock itself in %s</string> <string name="sleep_timer_notification_content">Sleep timer is scheduled. Your device will lock itself in %s</string>
<string name="sleep_timer_notification_cancel">Cancel</string> <string name="sleep_timer_notification_cancel">Cancel</string>
<string name="sleep_timer_remaining_time_with_hour">%02d:%02d:%02d"</string> <string name="sleep_timer_remaining_time_with_hour" translatable="false">%02d:%02d:%02d"</string>
<string name="sleep_timer_remaining_time_without_hour">%02d:%02d"</string> <string name="sleep_timer_remaining_time_without_hour" translatable="false">%02d:%02d"</string>
<!-- Share Location Functionality Strings --> <!-- Share Location Functionality Strings -->
<string name="title_share_location">Share Location</string> <string name="title_share_location">Share Location</string>
<string name="share_location_notification_channel">ShareLocation</string> <string name="share_location_notification_channel" translatable="false">ShareLocation</string>
<string name="share_location_notification_content">You are sharing your current location within the family</string> <string name="share_location_notification_content">You are sharing your current location within the family</string>
<string name="share_location_no_sharings_in_progress">Currently nobody is sharing their location</string> <string name="share_location_no_sharings_in_progress">Currently nobody is sharing their location</string>
<string name="share_location_info_title_empty">You are currently not following anyone</string> <string name="share_location_info_title_empty">You are currently not following anyone</string>
<string name="share_location_info_title">You are following %s</string> <string name="share_location_info_title">You are following %s</string>
<string name="share_location_info_location">Last Received Location = %f;%f</string> <string name="share_location_info_location">Last Received Location = %f;%f</string>
<string name="share_location_info_altitude">Last received latitude = %.2f Meters</string> <string name="share_location_info_altitude">Last received altitude = %.2f Meters</string>
<string name="share_location_info_speed">The last received velocity was %.2f m/s (%.1f km/h)</string> <string name="share_location_info_speed">The last received velocity was %.2f m/s (%.1f km/h)</string>
<string name="share_location_info_timestamp">This update was received at: %s</string> <string name="share_location_info_timestamp">This update was received at: %s</string>
<string name="share_location_toggle_button">Share your location</string> <string name="share_location_toggle_button">Share your location</string>
<string name="share_location_background_permission_rationale">In order to share your position also while in the background, please grant the always permission</string> <string name="share_location_background_permission_rationale">In order to share your position also while in the background, please grant the always permission</string>
<string name="title_activity_settings">SettingsActivity</string> <string name="title_activity_settings">Settings</string>
<!-- Flashlight Functionality Strings -->
<string name="title_flashlight">Flashlight</string>
<string name="flashlight_camera_rationale">In order to have access to the flashlight, you need to grant the Camera permission.</string>
<string name="flashlight_set_min_level">Activate flashlight on minimum brightness</string>
<string name="flashlight_set_med_level">Activate flashlight on medium brightness</string>
<string name="flashlight_set_max_level">Activate flashlight on maximum brightness</string>
<!-- Settings --> <!-- Settings -->
<string name="title_settings">Settings</string> <string name="title_settings">Settings</string>
@@ -40,7 +46,7 @@
<!-- Share Location Preference --> <!-- Share Location Preference -->
<string name="pref_share_location_header">Share Location</string> <string name="pref_share_location_header">Share Location</string>
<string name="pref_share_location_freq_title">Location Update frequency</string> <string name="pref_share_location_freq_title">Location Update frequency</string>
<string name="pref_share_location_freq_summary">The minimum amount of seconds to wait between two location updates\n<b>Note:</b> The lower the value the higher the battery consumption</string> <string name="pref_share_location_freq_summary">The minimum amount of seconds to wait between two location updates <b>Note:</b> The lower the value the higher the battery consumption</string>
<string name="pref_auto_accuracy_title">Automatic accuracy detection</string> <string name="pref_auto_accuracy_title">Automatic accuracy detection</string>
<string name="pref_auto_accuracy_summary_on">Accuracy will be auto selected based on the current charging state</string> <string name="pref_auto_accuracy_summary_on">Accuracy will be auto selected based on the current charging state</string>
<string name="pref_auto_accuracy_summary_off">Select high accuracy vs. balanced power consumption below</string> <string name="pref_auto_accuracy_summary_off">Select high accuracy vs. balanced power consumption below</string>

View File

@@ -6,11 +6,11 @@
<SeekBarPreference <SeekBarPreference
app:key="@string/pref_key_share_location_freq" app:key="@string/pref_key_share_location_freq"
app:title="@string/pref_share_location_freq_title" app:title="@string/pref_share_location_freq_title"
app:min="1" app:min="@integer/pref_location_update_freq_min"
android:max="60" android:max="@integer/pref_location_update_freq_max"
app:seekBarIncrement="1" app:seekBarIncrement="@integer/pref_location_update_freq_increment"
app:showSeekBarValue="true" app:showSeekBarValue="true"
app:defaultValue="10" app:defaultValue="@integer/pref_location_update_freq_default"
app:summary="@string/pref_share_location_freq_summary"/> app:summary="@string/pref_share_location_freq_summary"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat