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

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);
}
}