Initial commit

This commit is contained in:
wesaphzt 2019-07-03 16:06:51 +01:00
commit fce85eb842
83 changed files with 3673 additions and 0 deletions

13
.gitignore vendored Normal file
View file

@ -0,0 +1,13 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild

4
.idea/encodings.xml generated Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

15
.idea/gradle.xml generated Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<compositeConfiguration>
<compositeBuild compositeDefinitionSource="SCRIPT" />
</compositeConfiguration>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

9
.idea/misc.xml generated Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

12
.idea/runConfigurations.xml generated Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

1
app/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

35
app/build.gradle Normal file
View file

@ -0,0 +1,35 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.wesaphzt.privatelock"
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.intuit.sdp:sdp-android:1.0.3'
implementation 'androidx.preference:preference:1.0.0'
implementation 'com.github.AppIntro:AppIntro:5.1.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

21
app/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# 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 *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,26 @@
package com.wesaphzt.privatelock;
import android.content.Context;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.wesaphzt.privatelock", appContext.getPackageName());
}
}

View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.wesaphzt.privatelock">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!--pre-oreo-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.wesaphzt.privatelock.IntroActivity"
android:theme="@style/Theme.AppCompat.NoActionBar" />
<receiver android:name=".receivers.DeviceAdminReceiver"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"
android:resource="@xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
<receiver android:name="com.wesaphzt.privatelock.receivers.NotificationReceiver"/>
<receiver android:name="com.wesaphzt.privatelock.receivers.PauseReceiver"/>
<receiver android:name=".receivers.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service
android:name=".service.LockService"
android:label="Service"
android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver android:name=".widget.LockWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/app_widget_info" />
</receiver>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,72 @@
package com.wesaphzt.privatelock;
import android.os.Bundle;
import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.github.paolorotolo.appintro.AppIntro;
import com.github.paolorotolo.appintro.AppIntroFragment;
import com.github.paolorotolo.appintro.model.SliderPage;
import static com.wesaphzt.privatelock.service.LockService.mInitialized;
public class IntroActivity extends AppIntro {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//fullscreen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//slider pages
SliderPage sliderPageOne = new SliderPage();
sliderPageOne.setTitle(getResources().getString(R.string.slider_page_one_title));
sliderPageOne.setDescription(getString(R.string.slider_page_one_desc));
sliderPageOne.setImageDrawable(R.drawable.ic_intro_lock);
sliderPageOne.setBgColor(getResources().getColor(R.color.colorPrimary));
addSlide(AppIntroFragment.newInstance(sliderPageOne));
SliderPage sliderPageTwo = new SliderPage();
sliderPageTwo.setTitle(getResources().getString(R.string.slider_page_two_title));
sliderPageTwo.setDescription(getResources().getString(R.string.slider_page_two_desc));
sliderPageTwo.setImageDrawable(R.drawable.ic_intro_iris);
sliderPageTwo.setBgColor(getResources().getColor(R.color.colorIntroGrey));
addSlide(AppIntroFragment.newInstance(sliderPageTwo));
SliderPage sliderPageThree = new SliderPage();
sliderPageThree.setTitle(getResources().getString(R.string.slider_page_three_title));
sliderPageThree.setDescription(getResources().getString(R.string.slider_page_three_desc));
sliderPageThree.setImageDrawable(R.drawable.ic_intro_shield);
sliderPageThree.setBgColor(getResources().getColor(R.color.colorIntroGreen));
addSlide(AppIntroFragment.newInstance(sliderPageThree));
//options
setFadeAnimation();
showSkipButton(false);
setProgressButtonEnabled(true);
//setBarColor(getResources().getColor(R.color.colorPrimary));
//setSeparatorColor(getResources().getColor(R.color.white));
}
@Override
public void onSkipPressed(Fragment currentFragment) {
super.onSkipPressed(currentFragment);
}
@Override
public void onDonePressed(Fragment currentFragment) {
super.onDonePressed(currentFragment);
mInitialized = false;
finish();
}
@Override
public void onSlideChanged(@Nullable Fragment oldFragment, @Nullable Fragment newFragment) {
super.onSlideChanged(oldFragment, newFragment);
}
}

View file

@ -0,0 +1,453 @@
package com.wesaphzt.privatelock;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.os.CountDownTimer;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.wesaphzt.privatelock.animation.Circle;
import com.wesaphzt.privatelock.animation.CircleAngleAnimation;
import com.wesaphzt.privatelock.fragments.FragmentAbout;
import com.wesaphzt.privatelock.fragments.FragmentDonate;
import com.wesaphzt.privatelock.fragments.FragmentSettings;
import com.wesaphzt.privatelock.receivers.DeviceAdminReceiver;
import com.wesaphzt.privatelock.receivers.PauseReceiver;
import com.wesaphzt.privatelock.service.LockService;
import com.wesaphzt.privatelock.widget.LockWidgetProvider;
import static com.wesaphzt.privatelock.service.LockService.CHANNEL_ID;
import static com.wesaphzt.privatelock.service.LockService.DEFAULT_SENSITIVITY;
import static com.wesaphzt.privatelock.service.LockService.activeListener;
import static com.wesaphzt.privatelock.service.LockService.disabled;
public class MainActivity extends AppCompatActivity {
private Context context;
private int mSensitivity;
private float mLastX, mLastY, mLastZ;
private boolean mInitialized;
private static SensorManager mSensorManager;
private Sensor mAccelerometer;
private final float NOISE = (float) 2.0;
private SensorEventListener mActiveListener;
//DevicePolicyManager
private DevicePolicyManager mDPM;
private ComponentName mDeviceAdmin;
private static final int REQUEST_CODE_ENABLE_ADMIN = 1;
private TextView tvSensitivityActualValue;
private SharedPreferences prefs;
public static final String PREFS_THRESHOLD = "THRESHOLD";
private CountDownTimer cdTimer;
private final int cdTimerLength = 2000;
private boolean isRunning = false;
private Circle circle;
private Circle circle_bg;
//circle bg color
private int circleBgR = 240; private int circleBgG = 240; private int circleBgB = 240;
//circle color
private int circleDefaultR = 88; private int circleDefaultG = 186; private int circleDefaultB = 255;
//circle lock color
private int circleLockR = 88; private int circleLockG = 255; private int circleLockB = 135;
int animationDuration = 220;
//first run
final private String PREF_VERSION_CODE_KEY = "VERSION_CODE";
final private int DOESNT_EXIST = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getApplicationContext();
this.prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
getFirstRun();
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
public void onBackStackChanged() {
//toggle back arrow on back stack change
if (getSupportActionBar() != null) {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
//set title
MainActivity.this.setTitle(R.string.app_name);
}
}
}
});
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(getSupportFragmentManager().getBackStackEntryCount() > 0){
getSupportFragmentManager().popBackStack();
}
}
});
//https://stackoverflow.com/questions/29381474/how-to-draw-a-circle-with-animation-in-android-with-circle-size-based-on-a-value
circle = findViewById(R.id.circle);
circle_bg = findViewById(R.id.circle_bg);
circle.setColor(circleDefaultR, circleDefaultG, circleDefaultB);
//set background circle
CircleAngleAnimation animation = new CircleAngleAnimation(circle_bg, 360);
//initial animation
animation.setDuration(500);
circle_bg.setColor(circleBgR,circleBgG,circleBgB);
circle_bg.startAnimation(animation);
//shared prefs
try {
mSensitivity = prefs.getInt(PREFS_THRESHOLD, DEFAULT_SENSITIVITY);
} catch (Exception e) {
Toast.makeText(context, "Unable to retrieve threshold", Toast.LENGTH_LONG).show();
}
//timer when lock hit
cdTimer = new CountDownTimer(cdTimerLength, 1000) {
public void onTick(long millisUntilFinished) {
isRunning = true;
}
public void onFinish() {
isRunning = false;
circle.setColor(circleDefaultR, circleDefaultG, circleDefaultB);
}
};
//prevent lock animation artifacts
mInitialized = false;
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//sensor listener
setSensorListener();
mSensorManager.registerListener(mActiveListener, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
//dpm
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mDeviceAdmin = new ComponentName(this, DeviceAdminReceiver.class);
tvSensitivityActualValue = findViewById(R.id.tvSensitivityActualValue);
tvSensitivityActualValue.setText(getString(R.string.sensitivity_value, Integer.toString(mSensitivity)));
//seek bar
SeekBar sbSensitivity = findViewById(R.id.sbSensitivity);
sbSensitivity.setProgress(mSensitivity);
sbSensitivity.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mSensitivity = progress;
tvSensitivityActualValue.setText(getString(R.string.sensitivity_value, Integer.toString(mSensitivity)));
//submit to shared prefs
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(PREFS_THRESHOLD, progress).apply();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) { }
@Override
public void onStopTrackingTouch(SeekBar seekBar) { }
});
}
private void startLockService(Intent intent) {
//check android api
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
minimizeApp();
} else {
context.startService(intent);
minimizeApp();
}
}
public void minimizeApp() {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}
public void requestDeviceAdmin() {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdmin);
startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//launch service if permission granted
if (requestCode == REQUEST_CODE_ENABLE_ADMIN) {
if(resultCode == Activity.RESULT_OK) {
startServicePrep();
}
}
}
//determine if we are an active admin
private boolean isActiveAdmin() {
return mDPM.isAdminActive(mDeviceAdmin);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mActiveListener, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
//recreate menu to set start/stop again
invalidateOptionsMenu();
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(mActiveListener);
}
private void setSensorListener() {
mActiveListener = new SensorEventListener() {
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
@Override
public void onSensorChanged(SensorEvent event) {
sensorCalc(event);
}
};
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//inflate actionbar menu
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private void startServicePrep() {
//stop this listener
mSensorManager.unregisterListener(mActiveListener);
Intent intent = new Intent(context, LockService.class);
try {
//stop any already running service
LockService.mSensorManager.unregisterListener(LockService.activeListener);
startLockService(intent);
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetStart(context);
//cancel any pause timer that might be running
try {
PauseReceiver.mCountdown.cancel();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
startLockService(intent);
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetStart(context);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.action_start) {
if (isActiveAdmin()) {
startServicePrep();
} else {
requestDeviceAdmin();
}
} else if (id == R.id.action_stop) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.deleteNotificationChannel(CHANNEL_ID);
disabled = true;
mSensorManager.unregisterListener(activeListener);
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetStop(context);
invalidateOptionsMenu();
} else {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(LockService.NOTIFICATION_ID);
disabled = true;
mSensorManager.unregisterListener(activeListener);
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetStop(context);
}
} else if (id == R.id.action_settings) {
fragment = new FragmentSettings();
} else if (id == R.id.action_donate) {
fragment = new FragmentDonate();
} else if (id == R.id.action_show_intro) {
Intent myIntent = new Intent(this, IntroActivity.class);
this.startActivity(myIntent);
} else if (id == R.id.action_about) {
fragment = new FragmentAbout();
}
//add fragment
if (fragment != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
fragmentTransaction.add(R.id.content_main, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem action_start = menu.findItem(R.id.action_start);
MenuItem action_stop = menu.findItem(R.id.action_stop);
setMenuStatus(action_start, action_stop);
return true;
}
public void setMenuStatus(MenuItem action_start, MenuItem action_stop) {
if (disabled) {
action_start.setEnabled(true);
action_stop.setEnabled(false);
} else {
//enabled
action_start.setEnabled(false);
action_stop.setEnabled(true);
}
}
private void getFirstRun() {
//get current version code
int currentVersionCode = BuildConfig.VERSION_CODE;
//get saved version code
int savedVersionCode = DOESNT_EXIST;
try {
savedVersionCode = this.prefs.getInt(PREF_VERSION_CODE_KEY, DOESNT_EXIST);
} catch (Exception e) {
e.printStackTrace();
}
//check first run
//noinspection StatementWithEmptyBody
if (currentVersionCode == savedVersionCode) {
//normal run
} else if (savedVersionCode == DOESNT_EXIST) {
//first run
Intent myIntent = new Intent(this, IntroActivity.class);
this.startActivity(myIntent);
}
//update shared prefs with current version code
this.prefs.edit().putInt(PREF_VERSION_CODE_KEY, currentVersionCode).apply();
}
private void sensorCalc(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
if (!mInitialized) {
mLastX = x;
mLastY = y;
mLastZ = z;
mInitialized = true;
} else {
float deltaX = Math.abs(mLastX - x);
float deltaY = Math.abs(mLastY - y);
float deltaZ = Math.abs(mLastZ - z);
if (deltaX < NOISE) deltaX = (float) 0.0;
if (deltaY < NOISE) deltaY = (float) 0.0;
if (deltaZ < NOISE) deltaZ = (float) 0.0;
mLastX = x;
mLastY = y;
mLastZ = z;
float total = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
int calculatedAngleInt;
if (total <= mSensitivity) {
//do nothing if timer currently running
if(isRunning)
return;
calculatedAngleInt = Math.round((total / mSensitivity) * 360);
CircleAngleAnimation animation = new CircleAngleAnimation(circle, calculatedAngleInt);
animation.setDuration(animationDuration);
circle.startAnimation(animation);
} else if (total > mSensitivity) {
//lock screen threshold hit
if(isRunning)
//do nothing if timer currently running
return;
CircleAngleAnimation animation = new CircleAngleAnimation(circle, 360);
animation.setDuration(animationDuration);
//set lock color
circle.setColor(circleLockR, circleLockG, circleLockB);
circle.startAnimation(animation);
cdTimer.start();
}
}
}
}

View file

@ -0,0 +1,56 @@
package com.wesaphzt.privatelock.animation;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class Circle extends View {
private static final int START_ANGLE_POINT = 90;
private final Paint paint;
private final RectF rect;
private float angle;
public Circle(Context context, AttributeSet attrs) {
super(context, attrs);
final int strokeWidth = 10;
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(strokeWidth);
//circle color (currently set upon instance)
//paint.setColor(Color.BLUE);
//size
rect = new RectF(strokeWidth, strokeWidth, 600 + strokeWidth, 600 + strokeWidth);
//initial angle (optional)
angle = 0;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(rect, START_ANGLE_POINT, angle, true, paint);
}
public float getAngle() {
return angle;
}
public void setColor(int r, int g, int b) {
paint.setColor(Color.rgb(r, g, b));
}
public void setAngle(float angle) {
this.angle = angle;
}
}

View file

@ -0,0 +1,26 @@
package com.wesaphzt.privatelock.animation;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class CircleAngleAnimation extends Animation {
private Circle circle;
private float oldAngle;
private float newAngle;
public CircleAngleAnimation(Circle circle, int newAngle) {
this.oldAngle = circle.getAngle();
this.newAngle = newAngle;
this.circle = circle;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation transformation) {
float angle = oldAngle + ((newAngle - oldAngle) * interpolatedTime);
circle.setAngle(angle);
circle.requestLayout();
}
}

View file

@ -0,0 +1,114 @@
package com.wesaphzt.privatelock.fragments;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.wesaphzt.privatelock.R;
public class FragmentAbout extends Fragment {
private static String GITHUB_URI;
private static final String LICENSE_URI = GITHUB_URI + "/blob/master/LICENSE.txt";
private static final String BUG_REPORT_URI = GITHUB_URI + "/issues";
private static String AUTHOR_GITHUB;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_about, container, false);
GITHUB_URI = getString(R.string.app_github);
AUTHOR_GITHUB = getString(R.string.app_github_dev);
String versionName = "";
try {
PackageInfo packageInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
versionName = packageInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
TextView version = v.findViewById(R.id.about_text_version);
version.setText(versionName);
LinearLayout license = v.findViewById(R.id.about_layout_license);
LinearLayout source = v.findViewById(R.id.about_layout_source);
license.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openURI(LICENSE_URI);
}
});
source.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openURI(GITHUB_URI);
}
});
LinearLayout authorLayout = v.findViewById(R.id.aboutLayoutAuthor);
authorLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openURI(AUTHOR_GITHUB);
}
});
LinearLayout bugReport = v.findViewById(R.id.about_layout_bugs);
bugReport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openURI(BUG_REPORT_URI);
}
});
return v;
}
@Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
private void openURI(String uri) {
try {
Intent openURI = new Intent(Intent.ACTION_VIEW);
openURI.setData(Uri.parse(uri));
startActivity(openURI);
} catch (Exception e) {
Log.d("app-error", "error opening uri");
}
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
//hide action bar menu
menu.setGroupVisible(R.id.menu_main, false);
super.onPrepareOptionsMenu(menu);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//set title
getActivity().setTitle(getString(R.string.fragment_about_title));
}
}

View file

@ -0,0 +1,181 @@
package com.wesaphzt.privatelock.fragments;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.wesaphzt.privatelock.R;
public class FragmentDonate extends Fragment {
private Context context;
private static final String BITCOIN_PREFIX = "bitcoin:";
private static final String LITECOIN_PREFIX = "litecoin:";
private static final String ETHEREUM_PREFIX = "ethereum:";
private static final String MONERO_PREFIX = "monero:";
private static String BITCOIN_ADDRESS;
private static String BITCOIN_FULL;
private static String LITECOIN_ADDRESS;
private static String LITECOIN_FULL;
private static String ETHEREUM_ADDRESS;
private static String ETHEREUM_FULL;
private static String MONERO_ADDRESS;
private static String MONERO_FULL;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_donate, container, false);
setHasOptionsMenu(true);
context = getContext();
final TextView tvAddressBtc = view.findViewById(R.id.donate_bitcoin_address);
final TextView tvAddressLtc = view.findViewById(R.id.donate_litecoin_address);
final TextView tvAddressEth = view.findViewById(R.id.donate_ethereum_address);
final TextView tvAddressXmr = view.findViewById(R.id.donate_monero_address);
BITCOIN_ADDRESS = getString(R.string.donate_bitcoin_address);
BITCOIN_FULL = BITCOIN_PREFIX + BITCOIN_ADDRESS;
tvAddressBtc.setText(BITCOIN_ADDRESS);
LITECOIN_ADDRESS = getString(R.string.donate_litecoin_address);
LITECOIN_FULL = LITECOIN_PREFIX + LITECOIN_ADDRESS;
tvAddressLtc.setText(LITECOIN_ADDRESS);
ETHEREUM_ADDRESS = getString(R.string.donate_ethereum_address);
ETHEREUM_FULL = ETHEREUM_PREFIX + ETHEREUM_ADDRESS;
tvAddressEth.setText(ETHEREUM_ADDRESS);
MONERO_ADDRESS = getString(R.string.donate_monero_address);
MONERO_FULL = MONERO_PREFIX + MONERO_ADDRESS;
tvAddressXmr.setText(MONERO_ADDRESS);
tvAddressBtc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//attempt to open bitcoin app, else copy to clipboard
try {
openURI(BITCOIN_FULL);
} catch(Exception ignored) {
copyToClipboard(BITCOIN_ADDRESS);
}
}
});
tvAddressBtc.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
copyToClipboard(BITCOIN_ADDRESS);
return true;
}
});
//litecoin
tvAddressLtc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//attempt to open litecoin app, else copy to clipboard
try {
openURI(LITECOIN_FULL);
} catch(Exception ignored) {
copyToClipboard(LITECOIN_ADDRESS);
}
}
});
tvAddressLtc.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
copyToClipboard(LITECOIN_ADDRESS);
return true;
}
});
//ethereum
tvAddressEth.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//attempt to open ethereum app, else copy to clipboard
try {
openURI(ETHEREUM_FULL);
} catch(Exception ignored) {
copyToClipboard(ETHEREUM_ADDRESS);
}
}
});
tvAddressEth.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
copyToClipboard(ETHEREUM_ADDRESS);
return true;
}
});
//monero
tvAddressXmr.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//attempt to open ethereum app, else copy to clipboard
try {
openURI(MONERO_FULL);
} catch(Exception ignored) {
copyToClipboard(MONERO_ADDRESS);
}
}
});
tvAddressXmr.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
copyToClipboard(MONERO_ADDRESS);
return true;
}
});
return view;
}
private void copyToClipboard(String AUTHOR_EXTRA) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(getString(R.string.fragment_donate_clipboard_label), AUTHOR_EXTRA);
clipboard.setPrimaryClip(clip);
Toast.makeText(context, R.string.fragment_donate_clipboard_message, Toast.LENGTH_SHORT).show();
}
private void openURI(String uri) {
Intent openURI = new Intent(Intent.ACTION_VIEW);
openURI.setData(Uri.parse(uri));
startActivity(openURI);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
//hide action bar menu
menu.setGroupVisible(R.id.menu_main, false);
super.onPrepareOptionsMenu(menu);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//set title
getActivity().setTitle(getString(R.string.fragment_donate_title));
}
}

View file

@ -0,0 +1,53 @@
package com.wesaphzt.privatelock.fragments;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import android.view.Menu;
import android.view.View;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import com.wesaphzt.privatelock.R;
public class FragmentSettings extends PreferenceFragmentCompat {
private SharedPreferences prefs;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
setHasOptionsMenu(true);
Context context = getContext();
//this static call will reset default values only on the first read
PreferenceManager.setDefaultValues(context, R.xml.preferences, false);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//set title
getActivity().setTitle("Settings");
//bg color
view.setBackgroundColor(getResources().getColor(R.color.white));
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
//hide action bar menu
menu.setGroupVisible(R.id.menu_main, false);
super.onPrepareOptionsMenu(menu);
}
}

View file

@ -0,0 +1,36 @@
package com.wesaphzt.privatelock.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import com.wesaphzt.privatelock.service.LockService;
import com.wesaphzt.privatelock.widget.LockWidgetProvider;
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);;
if(prefs.getBoolean("START_ON_BOOT", false)) {
Intent i = new Intent(context, LockService.class);
//check android api
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(i);
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetStart(context);
} else {
context.startService(i);
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetStart(context);
}
}
}
}
}

View file

@ -0,0 +1,13 @@
package com.wesaphzt.privatelock.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class DeviceAdminReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}

View file

@ -0,0 +1,60 @@
package com.wesaphzt.privatelock.receivers;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import com.wesaphzt.privatelock.service.LockService;
import com.wesaphzt.privatelock.widget.LockWidgetProvider;
import com.wesaphzt.privatelock.R;
import static com.wesaphzt.privatelock.service.LockService.activeListener;
import static com.wesaphzt.privatelock.service.LockService.mSensorManager;
import static com.wesaphzt.privatelock.service.LockService.disabled;
public class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getStringExtra("lock_service");
if (action.equals("lock_service_notification")) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String id = context.getString(R.string.notification_main_channel_id);
notificationManager.deleteNotificationChannel(id);
if(PauseReceiver.isRunning) {
PauseReceiver.mCountdown.cancel(); PauseReceiver.isRunning = false;
disabled = true;
mSensorManager.unregisterListener(activeListener);
lockWidgetProvider.setWidgetStop(context);
} else {
disabled = true;
mSensorManager.unregisterListener(activeListener);
lockWidgetProvider.setWidgetStop(context);
}
} else {
notificationManager.cancel(LockService.NOTIFICATION_ID);
if(PauseReceiver.isRunning) {
PauseReceiver.mCountdown.cancel(); PauseReceiver.isRunning = false;
disabled = true;
mSensorManager.unregisterListener(activeListener);
lockWidgetProvider.setWidgetStop(context);
} else {
disabled = true;
mSensorManager.unregisterListener(activeListener);
lockWidgetProvider.setWidgetStop(context);
}
}
}
}
}

View file

@ -0,0 +1,67 @@
package com.wesaphzt.privatelock.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.CountDownTimer;
import android.preference.PreferenceManager;
import android.widget.Toast;
import com.wesaphzt.privatelock.widget.LockWidgetProvider;
import static com.wesaphzt.privatelock.service.LockService.disabled;
import static com.wesaphzt.privatelock.service.LockService.mInitialized;
public class PauseReceiver extends BroadcastReceiver {
public static CountDownTimer mCountdown;
public static boolean isRunning = false;
@Override
public void onReceive(final Context context, Intent intent) {
String action = intent.getStringExtra("pause_service");
if (action.equals("pause_service_time")) {
//close notification tray
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(i);
if(disabled) {
Toast.makeText(context, "Service is already paused", Toast.LENGTH_SHORT).show();
return;
} else {
disabled = true;
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetPause(context);
}
//shared prefs
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
int pauseMinuteTime = Integer.parseInt(prefs.getString("PAUSE_TIME", String.valueOf(1)));
int milliPauseTime = pauseMinuteTime * 60 * 1000;
String plural;
if(pauseMinuteTime == 1) { plural = "minute"; } else { plural = "minutes"; }
Toast.makeText(context, "Service paused for " + pauseMinuteTime + " " + plural, Toast.LENGTH_LONG).show();
mCountdown = new CountDownTimer(milliPauseTime, 1000) {
public void onTick(long millisUntilFinished) {
isRunning = true;
}
public void onFinish() {
//prevent lock animation artifacts
mInitialized = false;
//init
disabled = false;
isRunning = false;
LockWidgetProvider lockWidgetProvider = new LockWidgetProvider();
lockWidgetProvider.setWidgetStart(context);
Toast.makeText(context, "Service resumed", Toast.LENGTH_LONG).show();
}
}.start();
}
}
}

View file

@ -0,0 +1,24 @@
package com.wesaphzt.privatelock.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import static com.wesaphzt.privatelock.service.LockService.disabled;
import static com.wesaphzt.privatelock.service.LockService.mInitialized;
public class PresenceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
//prevent lock animation artifacts
mInitialized = false;
disabled = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
disabled = true;
}
}
}

View file

@ -0,0 +1,251 @@
package com.wesaphzt.privatelock.service;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.IBinder;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
import androidx.core.app.NotificationCompat;
import android.preference.PreferenceManager;
import android.widget.Toast;
import com.wesaphzt.privatelock.MainActivity;
import com.wesaphzt.privatelock.R;
import com.wesaphzt.privatelock.receivers.DeviceAdminReceiver;
import com.wesaphzt.privatelock.receivers.NotificationReceiver;
import com.wesaphzt.privatelock.receivers.PauseReceiver;
import com.wesaphzt.privatelock.receivers.PresenceReceiver;
import static androidx.core.app.NotificationCompat.PRIORITY_MIN;
public class LockService extends JobIntentService {
private Context context;
private float mLastX, mLastY, mLastZ;
public static boolean mInitialized;
public static SensorManager mSensorManager;
private final float NOISE = (float) 2.0;
public static Sensor mAccelerometer;
public static SensorEventListener activeListener;
public static boolean disabled = true;
//DevicePolicyManager
DevicePolicyManager mDPM;
ComponentName mDeviceAdmin;
//notifications
Notification notification;
NotificationManager notificationManager;
//ids
public static String CHANNEL_ID;
public static String CHANNEL_NAME;
public static final int NOTIFICATION_ID = 1000;
//intents
public static PendingIntent pendingIntent;
public static PendingIntent pendingCloseIntent;
public static PendingIntent pendingPauseIntent;
//sensitivity
public static final int DEFAULT_SENSITIVITY = 10;
public static int SENSITIVITY;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = getApplicationContext();
CHANNEL_ID = getString(R.string.notification_main_channel_id);
CHANNEL_NAME = getString(R.string.notification_main_channel_name);
//------------------------------------------------------------------------------------------
PresenceReceiver presenceReceiver = new PresenceReceiver();
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_USER_PRESENT);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(presenceReceiver, intentFilter);
//------------------------------------------------------------------------------------------
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
try {
SENSITIVITY = prefs.getInt(MainActivity.PREFS_THRESHOLD, DEFAULT_SENSITIVITY);
} catch (Exception e) {
Toast.makeText(context, "Unable to retrieve threshold", Toast.LENGTH_LONG).show();
}
//------------------------------------------------------------------------------------------
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//dpm
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mDeviceAdmin = new ComponentName(this, DeviceAdminReceiver.class);
//prevent lock animation artifacts
mInitialized = false;
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
setSensorListener();
mSensorManager.registerListener(activeListener, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
setNotification();
//------------------------------------------------------------------------------------------
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//create foreground service
startForeground(NOTIFICATION_ID, notification);
disabled = false;
} else {
notificationManager.notify(NOTIFICATION_ID, notification);
disabled = false;
}
//------------------------------------------------------------------------------------------
return LockService.START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
protected void onHandleWork(@NonNull Intent intent) { }
private void setSensorListener() {
activeListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if(LockService.disabled)
return;
sensorCalc(event);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
};
}
private void sensorCalc(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
if (!mInitialized) {
mLastX = x;
mLastY = y;
mLastZ = z;
mInitialized = true;
} else {
float deltaX = Math.abs(mLastX - x);
float deltaY = Math.abs(mLastY - y);
float deltaZ = Math.abs(mLastZ - z);
if (deltaX < NOISE) deltaX = (float) 0.0;
if (deltaY < NOISE) deltaY = (float) 0.0;
if (deltaZ < NOISE) deltaZ = (float) 0.0;
mLastX = x;
mLastY = y;
mLastZ = z;
float total = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
if (total > SENSITIVITY) {
try {
mDPM.lockNow();
} catch (Exception e) {
Toast.makeText(context, "Error locking, does app have device admin permissions?", Toast.LENGTH_SHORT).show();
}
}
}
}
private void setNotification() {
//notification
pendingIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP),
0);
//notification stop button
Intent intentStopAction = new Intent(context, NotificationReceiver.class);
intentStopAction.putExtra("lock_service","lock_service_notification");
pendingCloseIntent = PendingIntent.getBroadcast(context,0, intentStopAction, PendingIntent.FLAG_UPDATE_CURRENT);
//notification pause button
Intent intentPauseAction = new Intent(context, PauseReceiver.class);
intentPauseAction.putExtra("pause_service","pause_service_time");
pendingPauseIntent = PendingIntent.getBroadcast(context,0, intentPauseAction, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
notificationBuilder = new NotificationCompat.Builder(this);
notification = notificationBuilder
.setSmallIcon(R.drawable.ic_lock_white_24dp)
.setContentTitle(getString(R.string.app_name) + " is running")
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setTicker(getString(R.string.app_name) + " is running")
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "STOP", pendingCloseIntent)
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "PAUSE", pendingPauseIntent)
.setOngoing(true)
.build();
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N| Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) {
notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
notification = notificationBuilder
.setSmallIcon(R.drawable.ic_lock_white_24dp)
.setContentTitle(getString(R.string.app_name) + " is running")
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setColor(getColor(R.color.colorPrimary))
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setTicker(getString(R.string.app_name) + " is running")
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "STOP", pendingCloseIntent)
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "PAUSE", pendingPauseIntent)
.setOngoing(true)
.build();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
channel.setImportance(NotificationManager.IMPORTANCE_LOW);
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
notificationManager.createNotificationChannel(channel);
notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
notification = notificationBuilder
.setSmallIcon(R.drawable.ic_lock_white_24dp)
.setContentTitle(getString(R.string.app_name) + " is running")
.setPriority(PRIORITY_MIN)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setColor(getColor(R.color.colorPrimary))
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setTicker(getString(R.string.app_name) + " is running")
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "STOP", pendingCloseIntent)
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "PAUSE", pendingPauseIntent)
.setOngoing(true)
.build();
}
}
}

View file

@ -0,0 +1,186 @@
package com.wesaphzt.privatelock.widget;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import android.widget.RemoteViews;
import com.wesaphzt.privatelock.service.LockService;
import com.wesaphzt.privatelock.R;
import com.wesaphzt.privatelock.receivers.PauseReceiver;
import static com.wesaphzt.privatelock.service.LockService.CHANNEL_ID;
import static com.wesaphzt.privatelock.service.LockService.activeListener;
import static com.wesaphzt.privatelock.service.LockService.disabled;
import static com.wesaphzt.privatelock.service.LockService.mSensorManager;
public class LockWidgetProvider extends AppWidgetProvider {
private static final String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
public boolean SERVICE_STATUS;
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.app_widget);
//default status
remoteViews.setTextViewText(R.id.tvWidgetToggle, context.getResources().getString(R.string.widget_start_text));
Intent intent = new Intent(context, LockWidgetProvider.class);
intent.setAction(ACTION_WIDGET_RECEIVER);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.llWidget, pendingIntent);
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
boolean value = prefs.getBoolean(context.getString(R.string.widget_prefs_service_id), false);
if (value) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(context.getString(R.string.widget_prefs_service_id), false);
editor.apply();
}
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_WIDGET_RECEIVER)) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
boolean value = prefs.getBoolean(context.getString(R.string.widget_prefs_service_id), false);
SharedPreferences.Editor editor = prefs.edit();
SERVICE_STATUS = value;
//if service is running
if (SERVICE_STATUS) {
editor.putBoolean(context.getString(R.string.widget_prefs_service_id), false);
editor.apply();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationManager.deleteNotificationChannel(CHANNEL_ID);
//if countdown timer is running (pause), cancel
if(PauseReceiver.isRunning) {
PauseReceiver.mCountdown.cancel(); PauseReceiver.isRunning = false;
disabled = true;
mSensorManager.unregisterListener(activeListener);
setWidgetStop(context);
} else {
disabled = true;
mSensorManager.unregisterListener(activeListener);
setWidgetStop(context);
}
} else {
notificationManager.cancel(LockService.NOTIFICATION_ID);
if(PauseReceiver.isRunning) {
PauseReceiver.mCountdown.cancel(); PauseReceiver.isRunning = false;
disabled = true;
mSensorManager.unregisterListener(activeListener);
setWidgetStop(context);
} else {
disabled = true;
mSensorManager.unregisterListener(activeListener);
setWidgetStop(context);
}
}
//if service is not running
} else {
editor.putBoolean(context.getString(R.string.widget_prefs_service_id), true);
editor.commit();
Intent i = new Intent(context, LockService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
disabled = false;
context.startForegroundService(i);
setWidgetStart(context);
} else {
disabled = false;
context.startService(i);
setWidgetStart(context);
}
}
}
super.onReceive(context, intent);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
boolean value = prefs.getBoolean(context.getString(R.string.widget_prefs_service_id), false);
if (value) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(context.getString(R.string.widget_prefs_service_id), false);
editor.apply();
}
super.onDeleted(context, appWidgetIds);
}
//update widget methods
public void setWidgetStart(Context context) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
prefs.edit().putBoolean(context.getString(R.string.widget_prefs_service_id), true).apply();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisWidget = new ComponentName(context, LockWidgetProvider.class);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.app_widget);
remoteViews.setTextViewText(R.id.tvWidgetToggle, context.getResources().getString(R.string.widget_stop_text));
remoteViews.setImageViewResource(R.id.ivWidgetLock, R.drawable.ic_lock_closed_outline_white_24dp);
remoteViews.setInt(R.id.llWidget, "setBackgroundResource", R.color.colorWidgetStart);
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
public void setWidgetStop(Context context) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
prefs.edit().putBoolean(context.getString(R.string.widget_prefs_service_id), false).apply();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisWidget = new ComponentName(context, LockWidgetProvider.class);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.app_widget);
remoteViews.setTextViewText(R.id.tvWidgetToggle, context.getResources().getString(R.string.widget_start_text));
remoteViews.setImageViewResource(R.id.ivWidgetLock, R.drawable.ic_lock_open_outline_white_24dp);
remoteViews.setInt(R.id.llWidget, "setBackgroundResource", R.color.colorWidgetStop);
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
public void setWidgetPause(Context context) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
prefs.edit().putBoolean(context.getString(R.string.widget_prefs_service_id), true).apply();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisWidget = new ComponentName(context, LockWidgetProvider.class);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.app_widget);
remoteViews.setTextViewText(R.id.tvWidgetToggle, context.getResources().getString(R.string.widget_stop_text));
remoteViews.setImageViewResource(R.id.ivWidgetLock, R.drawable.ic_lock_open_outline_white_24dp);
remoteViews.setInt(R.id.llWidget, "setBackgroundResource", R.color.colorWidgetPause);
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
}

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_shortAnimTime"/>
</set>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_shortAnimTime"/>
</set>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View file

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4zM14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10.08,10.86c0.05,-0.33 0.16,-0.62 0.3,-0.87s0.34,-0.46 0.59,-0.62c0.24,-0.15 0.54,-0.22 0.91,-0.23 0.23,0.01 0.44,0.05 0.63,0.13 0.2,0.09 0.38,0.21 0.52,0.36s0.25,0.33 0.34,0.53 0.13,0.42 0.14,0.64h1.79c-0.02,-0.47 -0.11,-0.9 -0.28,-1.29s-0.4,-0.73 -0.7,-1.01 -0.66,-0.5 -1.08,-0.66 -0.88,-0.23 -1.39,-0.23c-0.65,0 -1.22,0.11 -1.7,0.34s-0.88,0.53 -1.2,0.92 -0.56,0.84 -0.71,1.36S8,11.29 8,11.87v0.27c0,0.58 0.08,1.12 0.23,1.64s0.39,0.97 0.71,1.35 0.72,0.69 1.2,0.91 1.05,0.34 1.7,0.34c0.47,0 0.91,-0.08 1.32,-0.23s0.77,-0.36 1.08,-0.63 0.56,-0.58 0.74,-0.94 0.29,-0.74 0.3,-1.15h-1.79c-0.01,0.21 -0.06,0.4 -0.15,0.58s-0.21,0.33 -0.36,0.46 -0.32,0.23 -0.52,0.3c-0.19,0.07 -0.39,0.09 -0.6,0.1 -0.36,-0.01 -0.66,-0.08 -0.89,-0.23 -0.25,-0.16 -0.45,-0.37 -0.59,-0.62s-0.25,-0.55 -0.3,-0.88 -0.08,-0.67 -0.08,-1v-0.27c0,-0.35 0.03,-0.68 0.08,-1.01zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="200dp" android:viewportHeight="64"
android:viewportWidth="64" android:width="200dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#f7931a" android:pathData="m63.0393,39.741c-4.274,17.143 -21.637,27.576 -38.782,23.301 -17.138,-4.274 -27.571,-21.638 -23.295,-38.78 4.272,-17.145 21.635,-27.579 38.775,-23.305 17.144,4.274 27.576,21.64 23.302,38.784z"/>
<path android:fillColor="#FFF" android:pathData="m46.1093,27.441c0.637,-4.258 -2.605,-6.547 -7.038,-8.074l1.438,-5.768 -3.511,-0.875 -1.4,5.616c-0.923,-0.23 -1.871,-0.447 -2.813,-0.662l1.41,-5.653 -3.509,-0.875 -1.439,5.766c-0.764,-0.174 -1.514,-0.346 -2.242,-0.527l0.004,-0.018 -4.842,-1.209 -0.934,3.75s2.605,0.597 2.55,0.634c1.422,0.355 1.679,1.296 1.636,2.042l-1.638,6.571c0.098,0.025 0.225,0.061 0.365,0.117 -0.117,-0.029 -0.242,-0.061 -0.371,-0.092l-2.296,9.205c-0.174,0.432 -0.615,1.08 -1.609,0.834 0.035,0.051 -2.552,-0.637 -2.552,-0.637l-1.743,4.019 4.569,1.139c0.85,0.213 1.683,0.436 2.503,0.646l-1.453,5.834 3.507,0.875 1.439,-5.772c0.958,0.26 1.888,0.5 2.798,0.726l-1.434,5.745 3.511,0.875 1.453,-5.823c5.987,1.133 10.489,0.676 12.384,-4.739 1.527,-4.36 -0.076,-6.875 -3.226,-8.515 2.294,-0.529 4.022,-2.038 4.483,-5.155zM38.0873,38.69c-1.085,4.36 -8.426,2.003 -10.806,1.412l1.928,-7.729c2.38,0.594 10.012,1.77 8.878,6.317zM39.1733,27.378c-0.99,3.966 -7.1,1.951 -9.082,1.457l1.748,-7.01c1.982,0.494 8.365,1.416 7.334,5.553z"/>
</vector>

View file

@ -0,0 +1,23 @@
<vector android:height="200dp" android:viewportHeight="156.13971"
android:viewportWidth="98.0182" android:width="126dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="0.600006" android:fillColor="#010101"
android:fillType="nonZero"
android:pathData="M48.995,58.458 L2.774,79.467 48.995,106.788 95.217,79.467 48.995,58.458z"
android:strokeAlpha="0.600006" android:strokeColor="#00000000"/>
<path android:fillAlpha="0.449997" android:fillColor="#010101"
android:fillType="nonZero"
android:pathData="m2.774,79.467 l46.221,27.321 0,-48.33L48.996,2.774 2.774,79.467z"
android:strokeAlpha="0.449997" android:strokeColor="#00000000"/>
<path android:fillAlpha="0.800003" android:fillColor="#010101"
android:fillType="nonZero"
android:pathData="m48.995,2.774 l0,55.684 0,48.33L95.217,79.467 48.995,2.774z"
android:strokeAlpha="0.800003" android:strokeColor="#00000000"/>
<path android:fillAlpha="0.449997" android:fillColor="#010101"
android:fillType="nonZero"
android:pathData="m2.774,88.231 l46.221,65.134 0,-37.826L2.774,88.231z"
android:strokeAlpha="0.449997" android:strokeColor="#00000000"/>
<path android:fillAlpha="0.800003" android:fillColor="#010101"
android:fillType="nonZero"
android:pathData="m48.995,115.539 l0,37.826L95.244,88.232 48.995,115.539z"
android:strokeAlpha="0.800003" android:strokeColor="#00000000"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:height="200dp" android:viewportHeight="329.256"
android:viewportWidth="329.254" android:width="200dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#bebebe" android:pathData="M329.255,164.627c0,90.922 -73.705,164.629 -164.626,164.629C73.707,329.256 0.001,255.549 0.001,164.627 0.001,73.706 73.707,0 164.629,0c90.92,0 164.626,73.706 164.626,164.627"/>
<path android:fillColor="#bebebe" android:pathData="M294.303,164.629c0,71.613 -58.057,129.675 -129.674,129.675 -71.616,0 -129.677,-58.062 -129.677,-129.675 0,-71.619 58.061,-129.677 129.677,-129.677 71.618,0 129.674,58.057 129.674,129.677"/>
<path android:fillColor="#fff" android:pathData="M155.007,208.606l10.693,-40.264 25.316,-9.249 6.297,-23.663 -0.215,-0.587 -24.92,9.104 17.955,-67.608h-50.921l-23.481,88.23 -19.605,7.162 -6.478,24.395 19.59,-7.156 -13.839,51.998h135.521l8.688,-32.362h-84.601"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="200dp" android:viewportHeight="256"
android:viewportWidth="256" android:width="200dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F60" android:pathData="M127.998,0C57.318,0 0,57.317 0,127.999c0,14.127 2.29,27.716 6.518,40.43H44.8V60.733l83.2,83.2 83.198,-83.2v107.695h38.282c4.231,-12.714 6.521,-26.303 6.521,-40.43C256,57.314 198.681,0 127.998,0"/>
<path android:fillColor="#4C4C4C" android:pathData="M108.867,163.062l-36.31,-36.311v67.765H18.623c22.47,36.863 63.051,61.48 109.373,61.48s86.907,-24.617 109.374,-61.48h-53.933V126.75l-36.31,36.31 -19.13,19.129 -19.128,-19.128h-0.002z"/>
</vector>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,24 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="300"
android:viewportHeight="300">
<path
android:pathData="M150,150m-150,0a150,150 0,1 1,300 0a150,150 0,1 1,-300 0"
android:fillColor="#80e5ff"/>
<path
android:pathData="M150.56,0.01V300c82.587,-0.3 149.44,-67.335 149.44,-149.99 0,-82.657 -66.858,-149.69 -149.44,-149.99z"
android:fillColor="#aaeeff"/>
<path
android:pathData="m281.15,222.37c-33.736,-8.65 -75.566,-13.771 -120.88,-13.771 -54.476,0 -103.92,7.404 -140.32,19.445 26.154,43.955 74.127,73.412 128.99,73.412 57.19,0 106.9,-32.009 132.2,-79.086z"
android:fillColor="#57bd84"/>
<path
android:pathData="m160.28,208.6c-3.615,0 -7.205,0.035 -10.774,0.1v92.748c1.396,-0.005 2.786,-0.03 4.173,-0.073 0.654,-0.02 1.305,-0.052 1.957,-0.081 0.92,-0.04 1.84,-0.088 2.756,-0.145 0.674,-0.042 1.348,-0.084 2.018,-0.135 1.092,-0.082 2.178,-0.18 3.26,-0.285 0.789,-0.077 1.576,-0.16 2.361,-0.25 1.053,-0.119 2.104,-0.245 3.148,-0.387 0.658,-0.089 1.314,-0.185 1.971,-0.282 0.906,-0.134 1.809,-0.278 2.709,-0.429 0.613,-0.103 1.227,-0.2 1.838,-0.311 1.369,-0.246 2.732,-0.51 4.09,-0.793 0.568,-0.119 1.131,-0.25 1.697,-0.375 0.922,-0.204 1.842,-0.414 2.756,-0.635 0.621,-0.149 1.24,-0.302 1.857,-0.459 0.98,-0.25 1.955,-0.513 2.93,-0.781 0.498,-0.138 0.998,-0.269 1.494,-0.412 1.313,-0.378 2.617,-0.776 3.914,-1.189 0.564,-0.179 1.123,-0.366 1.684,-0.552 0.902,-0.299 1.801,-0.605 2.695,-0.921 0.541,-0.19 1.084,-0.379 1.621,-0.576 1.316,-0.48 2.627,-0.975 3.924,-1.491 0.387,-0.153 0.768,-0.317 1.154,-0.475 1.004,-0.409 2.006,-0.828 2.998,-1.259 0.512,-0.221 1.021,-0.446 1.529,-0.673 0.961,-0.43 1.916,-0.869 2.867,-1.318 0.4,-0.188 0.803,-0.372 1.199,-0.563 1.283,-0.62 2.555,-1.259 3.818,-1.914 0.406,-0.21 0.807,-0.428 1.211,-0.643 0.943,-0.501 1.883,-1.011 2.814,-1.531 0.426,-0.237 0.852,-0.475 1.273,-0.716 1.205,-0.688 2.402,-1.388 3.586,-2.107 0.111,-0.068 0.225,-0.136 0.336,-0.204 1.219,-0.747 2.424,-1.516 3.621,-2.296 0.365,-0.237 0.729,-0.479 1.092,-0.721 0.963,-0.641 1.92,-1.292 2.867,-1.954 0.295,-0.207 0.594,-0.41 0.889,-0.618 1.213,-0.861 2.414,-1.737 3.602,-2.634 0.199,-0.15 0.396,-0.307 0.596,-0.458 1.012,-0.771 2.012,-1.555 3.002,-2.352 0.295,-0.236 0.59,-0.474 0.883,-0.713 1.088,-0.888 2.166,-1.787 3.229,-2.705 0.07,-0.061 0.143,-0.118 0.211,-0.179 1.16,-1.006 2.303,-2.032 3.434,-3.073 0.211,-0.194 0.418,-0.393 0.629,-0.588 0.949,-0.886 1.889,-1.783 2.814,-2.693 0.195,-0.19 0.391,-0.381 0.586,-0.572 2.191,-2.176 4.316,-4.419 6.371,-6.726 0.178,-0.199 0.354,-0.4 0.531,-0.601 0.963,-1.092 1.912,-2.195 2.842,-3.315 0.051,-0.061 0.104,-0.121 0.154,-0.182 1.021,-1.232 2.023,-2.483 3.006,-3.749 0.074,-0.095 0.146,-0.191 0.219,-0.287 0.889,-1.15 1.76,-2.314 2.615,-3.491 0.123,-0.17 0.248,-0.339 0.371,-0.51 1.848,-2.563 3.615,-5.187 5.303,-7.867 0.094,-0.15 0.186,-0.301 0.279,-0.451 0.793,-1.27 1.568,-2.551 2.322,-3.845 0.047,-0.08 0.096,-0.159 0.143,-0.24 0.822,-1.416 1.623,-2.847 2.4,-4.292 -33.736,-8.65 -75.566,-13.771 -120.88,-13.771z"
android:fillColor="#67c18c"/>
<path
android:pathData="M151.859,35.355C124.259,35.355 101.859,57.755 101.859,85.355L101.859,105.355L91.859,105.355C80.859,105.355 71.859,114.355 71.859,125.355L71.859,225.355C71.859,236.355 80.859,245.355 91.859,245.355L151.859,245.355L151.859,195.355C140.859,195.355 131.859,186.355 131.859,175.355C131.859,164.355 140.859,155.355 151.859,155.355L151.859,105.355L120.859,105.355L120.859,85.355C120.859,68.255 134.759,54.355 151.859,54.355Z"
android:fillColor="#0066ff"/>
<path
android:pathData="M150.58,35.415C178.18,35.415 200.58,57.815 200.58,85.415L200.58,105.415L210.58,105.415C221.58,105.415 230.58,114.415 230.58,125.415L230.58,225.415C230.58,236.415 221.58,245.415 210.58,245.415L150.58,245.415L150.58,195.415C161.58,195.415 170.58,186.415 170.58,175.415C170.58,164.415 161.58,155.415 150.58,155.415L150.58,105.415L181.58,105.415L181.58,85.415C181.58,68.315 167.68,54.415 150.58,54.415Z"
android:fillColor="#2A7FFF"/>
</vector>

View file

@ -0,0 +1,17 @@
<vector android:height="200dp" android:viewportHeight="800"
android:viewportWidth="800" android:width="200dp"
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#1c8adb" android:pathData="M400,400m-400,0a400,400 0,1 1,800 0a400,400 0,1 1,-800 0"/>
<path android:fillType="evenOdd" android:pathData="m191.35,226.75 l-191.13,191.13c8.368,198.71 112.21,310.9 272.72,371.72 72.418,-72.1 144.67,-144.35 216.64,-217.35z">
<aapt:attr name="android:fillColor">
<gradient android:endX="27.94" android:endY="666.76"
android:startX="291.14" android:startY="440.49" android:type="linear">
<item android:color="#6B000000" android:offset="0"/>
<item android:color="#00000000" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:fillColor="#fff" android:fillType="evenOdd" android:pathData="m400,165.67c-68.55,33.477 -145.63,60.635 -208.65,61.081 38.706,239.37 60.915,331.87 208.65,407.59 147.74,-75.717 169.95,-168.22 208.65,-407.59 -63.019,-0.446 -140.1,-27.604 -208.65,-61.081z"/>
<path android:fillAlpha=".13473" android:fillColor="#FF000000"
android:fillType="evenOdd" android:pathData="m400,165.66v234.34h175.93c11.796,-47.668 21.583,-104.35 32.725,-173.26 -63.019,-0.446 -140.1,-27.601 -208.65,-61.078zM400,400h-175.93c29.182,117.93 70.72,180.41 175.93,234.33v-234.33z"/>
</vector>

View file

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="118.078514"
android:viewportHeight="118.078514">
<group android:translateX="19.351757"
android:translateY="19.351757">
<path
android:pathData="M-0.4501,-0.2048l80.2145,0l0,79.6689l-80.2145,0z"
android:fillColor="#131313"/>
<path
android:pathData="M39.4592,8.6879C30.4924,13.067 20.4094,16.6195 12.1658,16.6777C17.2289,47.9896 20.134,60.0895 39.4592,69.9947C58.7851,60.09 61.6902,47.9896 66.7528,16.6777C58.5092,16.6195 48.4262,13.067 39.4592,8.6879Z"
android:fillColor="#6F6F6F"
android:fillType="evenOdd"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.4592,8.6863L39.4592,39.3406L62.4726,39.3406C64.0157,33.1047 65.2957,25.6905 66.7533,16.6764C58.5099,16.6182 48.4269,13.0659 39.4599,8.6868ZM39.4592,39.3406L16.446,39.3406C20.2631,54.7669 25.6966,62.9399 39.4592,69.9931Z"
android:fillAlpha="0.44"
android:fillType="evenOdd"/>
<path
android:pathData="M39.9082,14.3248C34.5972,14.3248 30.2874,18.6351 30.2874,23.9461L30.2874,27.7945L28.3628,27.7945C26.2461,27.7945 24.5144,29.5264 24.5144,31.6431L24.5144,50.8855C24.5144,53.0021 26.2461,54.7338 28.3628,54.7338L39.9082,54.7338L39.9082,45.1128C37.7918,45.1128 36.0598,43.3808 36.0598,41.2642C36.0598,39.1477 37.7918,37.4158 39.9082,37.4158L39.9082,27.7945L33.9431,27.7945L33.9431,23.9461C33.9431,20.6558 36.6181,17.9811 39.9082,17.9811Z"
android:fillColor="#DADADA"/>
<path
android:pathData="M39.4697,14.3365C44.7805,14.3365 49.0908,18.6468 49.0908,23.9578L49.0908,27.8064L51.0151,27.8064C53.1318,27.8064 54.8635,29.5381 54.8635,31.6548L54.8635,50.8968C54.8635,53.0138 53.1318,54.7455 51.0151,54.7455L39.4697,54.7455L39.4697,45.1242C41.5864,45.1242 43.3181,43.3925 43.3181,41.2758C43.3181,39.1591 41.5864,37.4274 39.4697,37.4274L39.4697,27.8064L45.4348,27.8064L45.4348,23.9578C45.4348,20.6671 42.7601,17.9927 39.4697,17.9927Z"
android:fillColor="#FFFFFF"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.6663,41.2731m-3.8293,0a3.8293,3.8293 0,1 1,7.6586 0a3.8293,3.8293 0,1 1,-7.6586 0"/>
</group>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1s3.1,1.39 3.1,3.1v2L8.9,8L8.9,6zM18,20L6,20L6,10h12v10z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z"/>
</vector>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llWidget"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:background="#222222"
android:orientation="vertical"
android:padding="@dimen/_10sdp">
<ImageView
android:id="@+id/ivWidgetLock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_lock_open_outline_white_24dp"
android:contentDescription="@string/widget_padlock_image_desc" />
<TextView
android:id="@+id/tvWidgetToggle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/widget_start_text"
android:textColor="@color/white"
android:textSize="@dimen/_10sdp" />
</LinearLayout>

View file

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/_10sdp"
tools:ignore="UselessParent">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/activity_margin_large">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_margin="@dimen/activity_margin">
<TextView
android:id="@+id/tvSensitivityTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/main_lock_sensitivity_title"
android:textSize="@dimen/_12sdp"
android:textStyle="bold"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvSensitivityHigh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="@string/main_lock_sensitivity_title_high"
android:textSize="@dimen/_12sdp"
android:textStyle="italic"/>
<TextView
android:id="@+id/tvSensitivityTo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/main_lock_sensitivity_title_arrow"
android:textSize="@dimen/_12sdp" />
<TextView
android:id="@+id/tvSensitivityLow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:gravity="end"
android:text="@string/main_lock_sensitivity_title_low"
android:textSize="@dimen/_12sdp"
android:textStyle="italic"
tools:ignore="RelativeOverlap" />
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin">
<TextView
android:id="@+id/tvSensitivityMinValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="@string/main_seek_low"
android:textSize="@dimen/_12sdp" />
<SeekBar
android:id="@+id/sbSensitivity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/_25sdp"
android:paddingEnd="@dimen/_30sdp"
android:max="40" >
</SeekBar>
<TextView
android:id="@+id/tvSensitivityMaxValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:gravity="end"
android:text="@string/main_seek_high"
android:textSize="@dimen/_12sdp"
tools:ignore="RelativeOverlap" />
</RelativeLayout>
<TextView
android:id="@+id/tvSensitivityActualValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_margin"
android:textSize="@dimen/_12sdp"
android:textStyle="italic|bold"
android:text=""
android:gravity="center" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_large">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_margin="@dimen/activity_margin">
<TextView
android:id="@+id/tvTestTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_test_lock_sensitivity_title"
android:textSize="@dimen/_12sdp"
android:textStyle="bold"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/activity_margin_large"
android:layout_gravity="center_horizontal">
<com.wesaphzt.privatelock.animation.Circle
android:id="@+id/circle_bg"
android:layout_width="240dp"
android:layout_height="240dp"
android:layout_centerHorizontal="true" />
<com.wesaphzt.privatelock.animation.Circle
android:id="@+id/circle"
android:layout_width="240dp"
android:layout_height="240dp"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>

View file

@ -0,0 +1,324 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:clipToPadding="false"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/activity_margin_small"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/card_thumbnail_size"
android:layout_height="@dimen/card_thumbnail_size"
android:layout_marginEnd="@dimen/activity_margin_medium"
android:src="@mipmap/ic_launcher"
android:contentDescription="@string/about_overview_logo_desc" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold"
android:text="@string/app_name"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/app_desc" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- version -->
<LinearLayout
android:id="@+id/about_layout_version"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical">
<ImageView
android:id="@+id/aboutImgVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large"
android:src="@drawable/ic_about_info_outline_black_24dp"
android:contentDescription="@string/about_version_image_desc" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_version_title"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" />
<TextView
android:id="@+id/about_text_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</LinearLayout>
<!-- license -->
<LinearLayout
android:id="@+id/about_layout_license"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/aboutImgLicense"
android:contentDescription="@string/about_license_image_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large"
android:src="@drawable/ic_about_copyright_black_24dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="@string/about_license_title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_license_desc" />
</LinearLayout>
</LinearLayout>
<!-- source -->
<LinearLayout
android:id="@+id/about_layout_source"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/aboutImgSource"
android:contentDescription="@string/about_source_image_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large"
android:src="@drawable/ic_about_code_black_24dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_source_title"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/about_developer_card_title"
android:padding="@dimen/activity_margin_small"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"/>
<!-- developer -->
<LinearLayout
android:id="@+id/aboutLayoutAuthor"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/aboutImgAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/about_developer_image_desc"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large"
android:src="@drawable/ic_about_person_black_24dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_developer_title"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_developer_desc"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_margin="@dimen/activity_margin" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/activity_margin_small"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="@string/about_contribute_title"/>
<!-- bug reports -->
<LinearLayout
android:id="@+id/about_layout_bugs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/aboutImgBugs"
android:contentDescription="@string/about_bug_report_image_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large"
android:src="@drawable/ic_about_bug_report_black_24dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_contribute_title"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_contribute_desc"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,253 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:clipToPadding="false"
android:orientation="vertical" >
<!--note-->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:id="@+id/donate_note_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:gravity="center_vertical">
<TextView
android:id="@+id/donate_note_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin"
android:text="@string/donate_note_text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/_12sdp"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!--bitcoin-->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?android:attr/selectableItemBackground">
<LinearLayout
android:id="@+id/donate_bitcoin_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/donate_bitcoin_image"
android:contentDescription="@string/donate_bitcoin_image_desc"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:src="@drawable/ic_donate_bitcoin_logo" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<TextView
android:id="@+id/donate_bitcoin_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_margin"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!--litecoin-->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?android:attr/selectableItemBackground">
<LinearLayout
android:id="@+id/donate_litecoin_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/donate_litecoin_image"
android:contentDescription="@string/donate_litecoin_image_desc"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:src="@drawable/ic_donate_litecoin_logo" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<TextView
android:id="@+id/donate_litecoin_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_margin"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!--ethereum-->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?android:attr/selectableItemBackground">
<LinearLayout
android:id="@+id/donate_ethereum_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/donate_ethereum_image"
android:contentDescription="@string/donate_ethereum_image_desc"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:src="@drawable/ic_donate_ethereum_logo" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<TextView
android:id="@+id/donate_ethereum_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_margin"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!--monero-->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="?android:attr/selectableItemBackground">
<LinearLayout
android:id="@+id/donate_monero_layout"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightLarge"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small">
<ImageView
android:id="@+id/donate_monero_image"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:contentDescription="@string/donate_monero_image_desc"
android:src="@drawable/ic_donate_monero_logo" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/donate_monero_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_margin"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,36 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.wesaphzt.privatelock.MainActivity"
tools:ignore="AlwaysShowAction">
<group
android:id="@+id/menu_main">
<item
android:id="@+id/action_start"
android:title="@string/action_start"
app:showAsAction="always" />
<item
android:id="@+id/action_stop"
android:title="@string/action_stop"
app:showAsAction="always" />
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
android:icon="@drawable/ic_action_settings_white_24dp"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_donate"
android:title="@string/action_donate"
app:showAsAction="never" />
<item
android:id="@+id/action_show_intro"
android:title="@string/action_show_intro"
app:showAsAction="never" />
<item
android:id="@+id/action_about"
android:title="@string/action_about"
app:showAsAction="never" />
</group>
</menu>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--pause time-->
<string-array name="array_pause_minutes">
<item>1 minute</item>
<item>2 minutes</item>
<item>3 minutes</item>
<item>5 minutes</item>
<item>10 minutes</item>
<item>15 minutes</item>
</string-array>
<string-array name="array_pause_minutes_vals">
<item>1</item>
<item>2</item>
<item>3</item>
<item>5</item>
<item>10</item>
<item>15</item>
</string-array>
</resources>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#0081dc</color>
<color name="colorPrimaryDark">#0065ac</color>
<color name="colorAccent">#D81B60</color>
<color name="white">#FFFFFF</color>
<color name="lightGrey">#f3f3f3</color>
<color name="colorWidgetStart">@color/colorPrimary</color>
<color name="colorWidgetStop">#222222</color>
<color name="colorWidgetPause">#ff9600</color>
<color name="colorIntroGrey">#7e7e7e</color>
<color name="colorIntroGreen">#4caf50</color>
</resources>

View file

@ -0,0 +1,21 @@
<resources>
<!--default screen margins, as android design guidelines-->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="nav_header_vertical_spacing">8dp</dimen>
<dimen name="nav_header_height">176dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<!--default screen margins, as android design guidelines-->
<dimen name="activity_margin_xsmall">4dp</dimen>
<dimen name="activity_margin_small">8dp</dimen>
<dimen name="activity_margin">16dp</dimen>
<dimen name="activity_margin_medium">24dp</dimen>
<dimen name="activity_margin_large">32dp</dimen>
<dimen name="activity_margin_xlarge">40dp</dimen>
<dimen name="card_padding_without_corners">14dp</dimen>
<dimen name="card_thumbnail_size">46dp</dimen>
<dimen name="author_image_size">64dp</dimen>
</resources>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#F3F3F3</color>
</resources>

View file

@ -0,0 +1,88 @@
<resources>
<string name="app_name">Private Lock</string>
<string name="app_desc">Open-Source Lock Privacy</string>
<string name="app_github_dev">https://github.com/wesaphzt</string>
<string name="app_github">https://github.com/wesaphzt/PrivateLock</string>
<!--main-->
<string name="main_lock_sensitivity_title">Set the lock sensitivity</string>
<string name="main_lock_sensitivity_title_high">High</string>
<string name="main_lock_sensitivity_title_low">Low</string>
<string name="main_seek_low">0</string>
<string name="main_seek_high">40</string>
<string name="main_test_lock_sensitivity_title">Test the lock sensitivity</string>
<string name="main_lock_sensitivity_title_arrow"></string>
<string name="sensitivity_value">Value: %1$s</string>
<!--intro-->
<string name="slider_page_one_title">Private Lock</string>
<string name="slider_page_one_desc">Private Lock, the perfect companion to help protect your phone privacy and security.</string>
<string name="slider_page_two_title">Protect against theft</string>
<string name="slider_page_two_desc">If someone takes your phone while you\'re using it, your phone is unlocked and all your private data is up for grabs.</string>
<string name="slider_page_three_title">Always running</string>
<string name="slider_page_three_desc">Should something happen, your phone will be quickly locked, dependent on the sensitivity you\'ve set.</string>
<!--actionbar-->
<string name="action_start">Start</string>
<string name="action_stop">Stop</string>
<string name="action_settings">Settings</string>
<string name="action_donate">Donate</string>
<string name="action_show_intro">Show Intro</string>
<string name="action_about">About</string>
<!--titles-->
<string name="fragment_donate_title">Donate</string>
<string name="fragment_donate_clipboard_label">Copied address</string>
<string name="fragment_donate_clipboard_message">Address copied to clipboard</string>
<string name="fragment_about_title">About</string>
<!--about-->
<string name="about_overview_logo_desc">About overview app logo</string>
<string name="about_contribute_card_title">Contribute</string>
<string name="about_contribute_title">Report Bugs</string>
<string name="about_contribute_desc">Report bugs or request new features</string>
<string name="about_developer_image_desc">Author image</string>
<string name="about_developer_title">wesaphzt</string>
<string name="about_developer_desc">Developer</string>
<string name="about_developer_card_title">Developer</string>
<string name="about_version_title">Version</string>
<string name="about_version_image_desc">Version image</string>
<string name="about_license_title">License</string>
<string name="about_license_desc">GPL v3.0</string>
<string name="about_license_image_desc">License image</string>
<string name="about_source_title">Source code</string>
<string name="about_source_image_desc">Source code image</string>
<string name="about_bug_report_image_desc">Bug report image</string>
<!--donate-->
<string name="donate_bitcoin_image_desc">Bitcoin image</string>
<string name="donate_litecoin_image_desc">Litecoin image</string>
<string name="donate_ethereum_image_desc">Ethereum image</string>
<string name="donate_monero_image_desc">Monero image</string>
<string name="donate_bitcoin_address">1GCkvAg9oG79niQTbh6EH9rPALQDXKyHKK</string>
<string name="donate_litecoin_address">LV687s3wVdhmLZyJMFxomJHdHFXeFAKT5R</string>
<string name="donate_ethereum_address">0x785a8804c85b88683a5cce5e53f60878831e5d03</string>
<string name="donate_monero_address">43Vijzdt3y42mmT954rSYPjXYabDsjYEV2KyhxfC46JibR2ny9VmRS1fjdJTHxxPVPFE8ajgArwjWfyaRgjh9vcNAwmkfJj</string>
<string name="donate_note_text">If you find these apps useful, consider supporting me in some way in my mission to create simple, useful, privacy-oriented, open-source apps.</string>
<string name="donate_note_image_desc">Text emoji image</string>
<!--widget-->
<string name="widget_start_text">Start</string>
<string name="widget_stop_text">Stop</string>
<string name="widget_prefs_service_id">SERVICE_STATUS</string>
<string name="widget_padlock_image_desc">Widget padlock image</string>
<!--notification-->
<string name="notification_main_channel_id">lock_notification_channel_id</string>
<string name="notification_main_channel_name">Lock Notification Service</string>
</resources>

View file

@ -0,0 +1,20 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="0"
android:initialLayout="@layout/app_widget"
android:resizeMode="none"
android:widgetCategory="home_screen|keyguard"
android:previewImage="@mipmap/ic_launcher_round">
</appwidget-provider>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<device-admin>
<uses-policies>
<force-lock />
</uses-policies>
</device-admin>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="Lock Service">
<ListPreference
android:defaultValue="1"
android:entries="@array/array_pause_minutes"
android:entryValues="@array/array_pause_minutes_vals"
android:key="PAUSE_TIME"
android:summary="%s"
android:title="Pause time" />
</PreferenceCategory>
<PreferenceCategory
android:title="Application">
<CheckBoxPreference
android:defaultValue="false"
android:key="START_ON_BOOT"
android:title="System start" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -0,0 +1,17 @@
package com.wesaphzt.privatelock;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

27
build.gradle Normal file
View file

@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

17
gradle.properties Normal file
View file

@ -0,0 +1,17 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,6 @@
#Sun May 26 22:24:42 BST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

172
gradlew vendored Executable file
View file

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored Normal file
View file

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

1
settings.gradle Normal file
View file

@ -0,0 +1 @@
include ':app'