Skip to content
Snippets Groups Projects
Commit 9a3cd082 authored by Axel Glöckner's avatar Axel Glöckner
Browse files

projects

parent 09a2b34e
No related branches found
No related tags found
No related merge requests found
Showing
with 789 additions and 0 deletions
*.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
.cxx
local.properties
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
/build
\ No newline at end of file
plugins {
id("com.android.application")
}
android {
namespace = "com.example.passwordstrenghtmeter"
compileSdk = 34
defaultConfig {
applicationId = "com.example.passwordstrenghtmeter"
minSdk = 34
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.10.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
\ No newline at end of file
# 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
\ No newline at end of file
package com.example.passwordstrenghtmeter;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.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.getInstrumentation().getTargetContext();
assertEquals("com.example.passwordstrenghtmeter", appContext.getPackageName());
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PasswordStrenghtMeter"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package com.example.passwordstrenghtmeter;
/**
* A class for the default validation logic.
*/
public class DefaultValidator implements StrengthValidator {
@Override
public boolean ValidateLength(String password) {
return (password.length()>10);
}
@Override
public boolean ValidateSpecialCharacters(String password){
String specialChars = "/@#$%&.,;:)(=?!";
int requiredCount = 2;
int count = 0;
for (int i = 0; i < password.length(); i++) {
if (specialChars.contains(String.valueOf(password.charAt(i)))) {
count++;
if (count >= requiredCount) {
return true;
}
}
}
return false;
}
@Override
public boolean ValidateCapLetters(String password) {
for (int i=0; i<password.length(); i++) {
if (Character.isUpperCase(password.charAt(i))) {
return true;
}
}
return false;
}
@Override
public String ErrorMessage() {
return "Password should at least ten characters long with two special characters and one capital character.";
}
}
package com.example.passwordstrenghtmeter;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
/**
* An example of how a developer could use the PasswordStrengthMeter component.
*/
public class MainActivity extends AppCompatActivity {
private PasswordStrengthMeter passwordStrengthMeter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
passwordStrengthMeter = findViewById(R.id.passwordstrengthmeter);
// How to gain access to both views.
View passwordView = passwordStrengthMeter.getPasswordView();
View progressBarView = passwordStrengthMeter.getProgressBarView();
// Setting progressbar colors.
passwordStrengthMeter.setErrorMessageColor(Color.rgb(255, 0, 0));
passwordStrengthMeter.setProgressbarColors(Color.rgb(255, 0, 0),
Color.rgb(255, 165, 0),
Color.rgb(0, 255, 0));
// Setting text visuals.
passwordStrengthMeter.setPasswordTextColor(Color.BLACK);
// Implementing custom validation logic.
passwordStrengthMeter.setStrengthValidator(new StrengthValidator() {
@Override
public boolean ValidateLength(String password) {
return (password.length()>6);
}
@Override
public boolean ValidateSpecialCharacters(String password) {
String specialChars = "/@#$%&.,;:)(=?!+-|<>{}[]~^*'§";
int requiredCount = 1;
int count = 0;
for (int i = 0; i < password.length(); i++) {
if (specialChars.contains(String.valueOf(password.charAt(i)))) {
count++;
if (count >= requiredCount) {
return true;
}
}
}
return false;
}
@Override
public boolean ValidateCapLetters(String password) {
for (int i=0; i<password.length(); i++) {
if (Character.isUpperCase(password.charAt(i))) {
return true;
}
}
return false;
}
@Overridegit
public String ErrorMessage() {
return "Password should contain seven characters, one special character and one capital letter.";
}
});
}
}
\ No newline at end of file
package com.example.passwordstrenghtmeter;
import android.content.Context;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class Password extends androidx.appcompat.widget.AppCompatEditText {
private View passwordView;
public Password(@NonNull Context context) {
super(context);
init();
}
public Password(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public Password(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
setHint("enter password");
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD );
setGravity(android.view.Gravity.CENTER_VERTICAL | android.view.Gravity.CENTER_HORIZONTAL);
this.passwordView = this;
}
public void setView(View view){
this.passwordView = view;
}
public View getView(){
return this.passwordView;
}
protected void setPasswordTextColor(int color){
setTextColor(color);
}
}
package com.example.passwordstrenghtmeter;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class PasswordStrengthMeter extends LinearLayout {
private StrengthValidator strengthValidator; // an interface for validating password strength.
private Password password;
private StrengthBar strengthBar;
public PasswordStrengthMeter(Context context) {
super(context);
}
public PasswordStrengthMeter(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public PasswordStrengthMeter(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public PasswordStrengthMeter(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
/**
* Initialize all datastructures and adding all views.
*/
private void init(){
setOrientation(VERTICAL);
password = new Password(getContext());
strengthBar = new StrengthBar(getContext());
strengthValidator = new DefaultValidator();
password.addTextChangedListener(getTextWatcher());
strengthBar.setErrorMessage(strengthValidator.ErrorMessage());
addView(password);
addView(strengthBar);
addView(strengthBar.getErrorMessageView());
}
/**
* A text watcher to dynamically validate the password.
* @return TextWatcher
*/
private TextWatcher getTextWatcher(){
return new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
@Override
public void afterTextChanged(Editable s) {
final String text = s.toString();
strengthBar.updateStrengthNew(strengthValidator.ValidateLength(text),
strengthValidator.ValidateSpecialCharacters(text),
strengthValidator.ValidateCapLetters(text));
}
};
}
public void setProgressbarColors(int weakColor, int mediumColor, int strongColor){
strengthBar.setProgressbarColors(weakColor, mediumColor, strongColor);
}
public void setErrorMessageColor(int color){
strengthBar.setErrorMessageColor(color);
}
public void setPasswordTextColor(int color){
password.setPasswordTextColor(color);
}
/**
* Function for setting new validation logic.
* @param validator
*/
public void setStrengthValidator(StrengthValidator validator){
this.strengthValidator = validator;
strengthBar.setErrorMessage(strengthValidator.ErrorMessage());
}
/**
* Access to the EditText view.
* @return View
*/
public View getPasswordView(){
return password.getView();
}
/**
* Access to the ProgressBar view.
* @return View
*/
public View getProgressBarView(){
return strengthBar.getProgressBarView();
}
}
package com.example.passwordstrenghtmeter;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
public class StrengthBar extends ProgressBar {
private static final int defaultColor = Color.TRANSPARENT; // constant for transparent color.
private static final int alpha = 255; // constant for 100% opacity.
private TextView errorMessage;
private int weakColor;
private int mediumColor;
private int strongColor;
private View progressBarView;
public StrengthBar(Context context) {
super(context, null, android.R.attr.progressBarStyleHorizontal);
init();
}
public StrengthBar(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.progressBarStyleHorizontal);
init();
}
public StrengthBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, android.R.attr.progressBarStyleHorizontal);
init();
}
public StrengthBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, android.R.attr.progressBarStyleHorizontal);
init();
}
/**
* Initialize colors and error messages.
*/
private void init() {
this.weakColor = Color.rgb(255, 0, 0);
this.mediumColor = Color.rgb(255, 165, 0);
this.strongColor = Color.rgb(0, 255, 0);
errorMessage = new TextView(getContext());
errorMessage.setTextColor(Color.RED);
errorMessage.setVisibility(View.GONE);
errorMessage.setGravity(android.view.Gravity.CENTER_VERTICAL | android.view.Gravity.CENTER_HORIZONTAL);
this.progressBarView = this;
}
private void hideErrorMessage() {
errorMessage.setVisibility(View.GONE);
}
private void showErrorMessage() {
errorMessage.setVisibility(View.VISIBLE);
}
/**
* Updates the Progressbar based on three parameters from the interface.
* @param length
* @param specChar
* @param capLet
*/
public void updateStrengthNew(boolean length, boolean specChar, boolean capLet){
int trueCount = 0;
int progress = 0;
if(length){
trueCount++;
}if(specChar){
trueCount++;
}if(capLet){
trueCount++;
}
if(trueCount==0){
setProgressbarColor(defaultColor);
showErrorMessage();
setProgress(0);
}if(trueCount==1){
setProgressbarColor(weakColor);
showErrorMessage();
progress = 33;
}if(trueCount==2){
setProgressbarColor(mediumColor);
showErrorMessage();
progress = 66;
}if(trueCount==3){
setProgressbarColor(strongColor);
hideErrorMessage();
progress = 100;
}
setProgress(progress);
}
/**
* Setting the color of the progressbar with 100% opacity.
* @param color
*/
private void setProgressbarColor(int color) {
if (getIndeterminateDrawable() != null) {
getIndeterminateDrawable().setColorFilter(Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)), PorterDuff.Mode.SRC_IN);
}
if (getProgressDrawable() != null) {
getProgressDrawable().setColorFilter(Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)), PorterDuff.Mode.SRC_IN);
}
}
/**
* Getters and setters.
*/
public View getProgressBarView(){
return this.progressBarView;
}
public void setProgressBarView(View view){
this.progressBarView = view;
}
protected View getErrorMessageView(){
return errorMessage;
}
public void setProgressbarColors(int weakColor, int mediumColor, int strongColor) {
this.weakColor = weakColor;
this.mediumColor = mediumColor;
this.strongColor = strongColor;
}
protected void setErrorMessageColor(int color){
errorMessage.setTextColor(color);
}
protected void setErrorMessage(String message){
errorMessage.setText(message);
}
}
package com.example.passwordstrenghtmeter;
public interface StrengthValidator {
boolean ValidateLength(String password);
boolean ValidateSpecialCharacters(String password);
boolean ValidateCapLetters(String password);
String ErrorMessage();
}
<?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="#3DDC84"
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>
<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:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
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="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.passwordstrenghtmeter.PasswordStrengthMeter
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/passwordstrengthmeter">
</com.example.passwordstrenghtmeter.PasswordStrengthMeter>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment