From 6a277e4dde18b291d6d199047e919dbe6a00916a Mon Sep 17 00:00:00 2001 From: Apalak Dutta Date: Fri, 22 Sep 2023 18:18:33 +0530 Subject: [PATCH] Dated 22-09-2023 --- .../example/.idea/assetWizardSettings.xml | 6 +- .../example_bestshot/example/app/build.gradle | 6 +- .../example/app/src/main/AndroidManifest.xml | 33 +- .../main/java/ru/visionlab/constant/Url.java | 2 +- .../main/java/ru/visionlab/femdemo/App.java | 3 +- .../femdemo/ApprovalListActivity.java | 119 +++ .../ru/visionlab/femdemo/CheckInActivity.java | 868 ++++++++++++++++-- .../visionlab/femdemo/CheckInNewActivity.java | 211 +++++ .../femdemo/LeaveRequestActivity.java | 47 + .../femdemo/LeaveRequestDetailsActivity.java | 115 +++ .../femdemo/PermissionRequestActivity.java | 383 ++++++++ .../femdemo/RegisterFromCheckActivity.java | 565 ++++++++++++ .../ru/visionlab/femdemo/ReportActivity.java | 203 ++++ .../femdemo/ReportDetailsActivity.java | 122 +++ .../ru/visionlab/femdemo/Splashactivity.java | 31 +- .../java/ru/visionlab/femdemo/Storage.java | 10 +- .../femdemo/api/JsonPlaceHolderApi.java | 16 +- .../femdemo/api/RegisterApiImplLocal.java | 43 +- .../AuthenticationActivity.java | 3 + .../visionlab/femdemo/base/PhotoFragment.java | 2 +- .../visionlab/femdemo/di/NetworkModule.java | 2 + .../femdemo/login/LoginActivity.java | 12 +- .../femdemo/login/LoginActivityNew.java | 397 +++++++- .../femdemo/register/RegisterActivity.java | 83 +- .../femdemo/register/RegisterActivityNew.java | 133 ++- .../femdemo/register/RegisterFragment.java | 15 + .../femdemo/register/SavePhotoFragment.java | 3 + .../app/src/main/res/drawable/approval.png | Bin 0 -> 20329 bytes .../src/main/res/drawable/attendance_icon.png | Bin 0 -> 25642 bytes .../res/drawable/bg_btn_with_stroke_grey.xml | 7 + .../res/drawable/bg_btn_with_stroke_red.xml | 7 + .../src/main/res/drawable/bg_button_sos.xml | 11 + .../src/main/res/drawable/bg_button_time.xml | 6 + .../src/main/res/drawable/bg_linear_grey.xml | 6 + .../app/src/main/res/drawable/calender.png | Bin 0 -> 9179 bytes .../app/src/main/res/drawable/calender2.xml | 5 + .../app/src/main/res/drawable/cross.png | Bin 0 -> 426 bytes .../drawable/custom_spinner_background.xml | 7 + .../app/src/main/res/drawable/down_arrow.xml | 5 + .../src/main/res/drawable/edittext_border.xml | 18 + .../app/src/main/res/drawable/emergency.png | Bin 0 -> 16225 bytes .../example/app/src/main/res/drawable/ese.png | Bin 0 -> 13278 bytes .../app/src/main/res/drawable/frank.png | Bin 0 -> 4909 bytes .../app/src/main/res/drawable/permission.png | Bin 0 -> 9137 bytes .../app/src/main/res/drawable/report.png | Bin 0 -> 9684 bytes .../app/src/main/res/drawable/tick.png | Bin 0 -> 295 bytes .../app/src/main/res/drawable/time.xml | 6 + .../res/layout/activity_approval_list.xml | 393 ++++++++ .../main/res/layout/activity_check_in_new.xml | 170 ++++ .../src/main/res/layout/activity_checkin.xml | 124 ++- .../res/layout/activity_leave_request.xml | 238 +++++ .../layout/activity_leave_request_details.xml | 212 +++++ .../src/main/res/layout/activity_login.xml | 80 +- .../main/res/layout/activity_login_new.xml | 26 +- .../layout/activity_permission_request.xml | 231 +++++ .../layout/activity_register_from_check.xml | 321 +++++++ .../main/res/layout/activity_register_new.xml | 55 +- .../src/main/res/layout/activity_report.xml | 123 +++ .../res/layout/activity_report_details.xml | 251 +++++ .../res/layout/activity_splashactivity.xml | 5 +- .../src/main/res/layout/fragment_register.xml | 42 +- .../main/res/layout/fragment_save_photo.xml | 8 +- .../app/src/main/res/layout/layout.xml | 171 +++- .../app/src/main/res/values/strings.xml | 11 +- 64 files changed, 5799 insertions(+), 173 deletions(-) create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ApprovalListActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInNewActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestDetailsActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/PermissionRequestActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/RegisterFromCheckActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportDetailsActivity.java create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/approval.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/attendance_icon.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/bg_btn_with_stroke_grey.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/bg_btn_with_stroke_red.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/bg_button_sos.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/bg_button_time.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/bg_linear_grey.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/calender.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/calender2.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/cross.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/custom_spinner_background.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/down_arrow.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/edittext_border.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/emergency.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/ese.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/frank.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/permission.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/report.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/tick.png create mode 100644 examples/example_bestshot/example/app/src/main/res/drawable/time.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_approval_list.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_check_in_new.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_leave_request.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_leave_request_details.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_permission_request.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_register_from_check.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_report.xml create mode 100644 examples/example_bestshot/example/app/src/main/res/layout/activity_report_details.xml diff --git a/examples/example_bestshot/example/.idea/assetWizardSettings.xml b/examples/example_bestshot/example/.idea/assetWizardSettings.xml index 8934cf4..5d79692 100644 --- a/examples/example_bestshot/example/.idea/assetWizardSettings.xml +++ b/examples/example_bestshot/example/.idea/assetWizardSettings.xml @@ -18,7 +18,7 @@ @@ -28,8 +28,8 @@ diff --git a/examples/example_bestshot/example/app/build.gradle b/examples/example_bestshot/example/app/build.gradle index a55d981..32c7f6c 100644 --- a/examples/example_bestshot/example/app/build.gradle +++ b/examples/example_bestshot/example/app/build.gradle @@ -172,7 +172,7 @@ dependencies { implementation 'com.trello:rxlifecycle-components:1.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'com.google.android.material:material:1.0.0' - + implementation 'com.google.android.gms:play-services-location:18.0.0' @@ -181,6 +181,10 @@ dependencies { implementation 'io.github.inflationx:calligraphy3:3.1.1' implementation 'io.github.inflationx:viewpump:2.0.3' + implementation 'com.android.volley:volley:1.2.1' + implementation 'com.github.f0ris.sweetalert:library:1.6.2' + /*implementation 'com.github.f0ris.sweetalert:library:1.5.1'*/ + // implementation('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') { // transitive = true; // } diff --git a/examples/example_bestshot/example/app/src/main/AndroidManifest.xml b/examples/example_bestshot/example/app/src/main/AndroidManifest.xml index e7805d4..98fb172 100644 --- a/examples/example_bestshot/example/app/src/main/AndroidManifest.xml +++ b/examples/example_bestshot/example/app/src/main/AndroidManifest.xml @@ -11,6 +11,8 @@ + + @@ -19,10 +21,35 @@ + android:theme="@style/AppTheme" + android:usesCleartextTraffic="true"> + + + + + + + + diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/constant/Url.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/constant/Url.java index dfd7439..ed2c978 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/constant/Url.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/constant/Url.java @@ -2,5 +2,5 @@ package ru.visionlab.constant; public class Url { - public static final String Base_url= "https://reqres.in/api/"; + public static final String Base_url= "http://huaiglobal.com/api/"; } diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/App.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/App.java index 7153f4f..6dfd6b6 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/App.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/App.java @@ -2,7 +2,6 @@ package ru.visionlab.femdemo; import android.app.Application; import android.os.StrictMode; -import android.widget.Toast; //import com.crashlytics.android.Crashlytics; @@ -90,5 +89,7 @@ public class App extends Application { void inject(AuthSuccessActivity activity); void inject(ServerSettingsActivity activity); + + void inject(RegisterFromCheckActivity registerFromCheckActivity); } } diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ApprovalListActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ApprovalListActivity.java new file mode 100644 index 0000000..cb552e6 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ApprovalListActivity.java @@ -0,0 +1,119 @@ +package ru.visionlab.femdemo; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.ProgressDialog; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class ApprovalListActivity extends AppCompatActivity { + + ImageButton back; + TextView RequestIDVal,EmployeeIDVal,EmployeeNameVal,LDateVal,LTimeOutVal,LTimeInVal,NoOfHrsVal,LeaveTypeVal,ApproverIDVal,ApproverNameVal,ReasonVal; + + String RequestID,EmployeeID,EmployeeName,LDate,LTimeOut,LTimeIn,NoOfHrs,LeaveType,ApproverID,ApproverName,Reason; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_approval_list); + + back = findViewById(R.id.back); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + onBackPressed(); + + } + }); + + PermissionApprovalList(); + + RequestIDVal = findViewById(R.id.RequestIDVal); + EmployeeIDVal = findViewById(R.id.EmployeeIDVal); + EmployeeNameVal = findViewById(R.id.EmployeeNameVal); + LDateVal = findViewById(R.id.LDateVal); + LTimeOutVal = findViewById(R.id.LTimeOutVal); + LTimeInVal = findViewById(R.id.LTimeInVal); + NoOfHrsVal = findViewById(R.id.NoOfHrsVal); + LeaveTypeVal = findViewById(R.id.LeaveTypeVal); + ApproverIDVal = findViewById(R.id.ApproverIDVal); + ApproverNameVal = findViewById(R.id.ApproverNameVal); + ReasonVal = findViewById(R.id.ReasonVal); + + + + } + + public void PermissionApprovalList(){ + final ProgressDialog loading = ProgressDialog.show(ApprovalListActivity.this, "Fetching information", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/PermissionApprovallist?ApproverID=27256"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + try { + JSONArray jsonArray=new JSONArray(response); + JSONObject jb1=jsonArray.getJSONObject(0); + RequestID = jb1.getString("RequestID"); + EmployeeID = jb1.getString("EmployeeID"); + EmployeeName = jb1.getString("EmployeeName"); + LDate = jb1.getString("LDate"); + LTimeOut = jb1.getString("LTimeOut"); + LTimeIn = jb1.getString("LTimeIn"); + NoOfHrs = jb1.getString("NoOfHrs"); + LeaveType = jb1.getString("LeaveType"); + ApproverID = jb1.getString("ApproverID"); + ApproverName = jb1.getString("ApproverName"); + Reason = jb1.getString("Reason"); + + RequestIDVal.setText(RequestID); + EmployeeIDVal.setText(EmployeeID); + EmployeeNameVal.setText(EmployeeName); + LDateVal.setText(LDate); + LTimeOutVal.setText(LTimeOut); + LTimeInVal.setText(LTimeIn); + NoOfHrsVal.setText(NoOfHrs); + LeaveTypeVal.setText(LeaveType); + ApproverIDVal.setText(ApproverID); + ApproverNameVal.setText(ApproverName); + ReasonVal.setText(Reason); + + + } catch (JSONException e) { + throw new RuntimeException(e); + } + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(ApprovalListActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(ApprovalListActivity.this).add(stringRequest); + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInActivity.java index 83286ec..feaf1b7 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInActivity.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInActivity.java @@ -1,26 +1,57 @@ package ru.visionlab.femdemo; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.LinearLayoutCompat; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; +import android.location.Location; import android.os.Bundle; +import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; -import android.view.MenuItem; import android.view.View; import android.view.WindowManager; -import android.widget.Button; import android.widget.ImageView; -import android.widget.PopupMenu; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import com.android.volley.Request; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.tasks.OnSuccessListener; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + + +import javax.inject.Inject; + +import cn.pedant.SweetAlert.SweetAlertDialog; +import ru.visionlab.femdemo.authentication.AuthSuccessActivity; import ru.visionlab.femdemo.login.LoginActivity; -import ru.visionlab.femdemo.register.RegisterActivityNew; +import ru.visionlab.femdemo.login.LoginActivityNew; +import ru.visionlab.femdemo.register.RegisterActivity; +import ru.visionlab.femdemo.settings.VLPreferences; public class CheckInActivity extends AppCompatActivity { @@ -28,19 +59,108 @@ public class CheckInActivity extends AppCompatActivity { ImageView menu; AlertDialog dialogBuilder; + TextView btnCheckIn,btnCheckOut; + + private static final int LOCATION_PERMISSION_REQUEST_CODE = 1; + private FusedLocationProviderClient fusedLocationClient; + + String targetLat1="",targetlat2="",targetLon1="",targetLon2=""; + + SharedPreferences sharedPreferences; + + private Context mContext; + + boolean FromRegister=true,FromRegisterCheck,backToCheck; + + private static boolean RUN_ONCE = true; + boolean checkInprssd = false; + + String valueFromApiCheckIn,valueFromApiCheckInFromReg,valueEmer; + + LinearLayoutCompat checkSuccess; + + TextView txtSuccess; + + @Inject + VLPreferences preferences; + + String login="", currentDateAndTime; + + RelativeLayout rel3; + + boolean _approverstatus; + + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_checkin); + + + checkSuccess = findViewById(R.id.checkSuccess); + txtSuccess = findViewById(R.id.txtSuccess); + + + + Intent intent = getIntent(); + FromRegister = intent.getBooleanExtra("FromRegister",false); + FromRegisterCheck = intent.getBooleanExtra("FromRegisterCheck",false); + backToCheck = intent.getBooleanExtra("backToCheck",false); + valueFromApiCheckInFromReg = intent.getStringExtra("valueFromApiCheckIn"); + System.out.println("Value of FromRegisterCheck "+FromRegisterCheck + FromRegister + " "+backToCheck + " " + valueFromApiCheckInFromReg); + + login = intent.getStringExtra("UserName"); + System.out.println("Value of loginUserName "+login); + /*if(login == null){ + login = ""; + } + else{ + login = "User"; + + }*/ + leaveApprover(); + + SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss "); + + // on below line we are creating a variable + // for current date and time and calling a simple date format in it. + currentDateAndTime = sdf.format(new Date()); + + System.out.println("Current date and time " + currentDateAndTime); + + SharedPreferences shared = getSharedPreferences("MyPrefs", MODE_PRIVATE); + String loginFromShare = shared.getString("login", ""); + String Descriptor = shared.getString("Descriptor", ""); + + + + + + + + + + + sharedPreferences= this.getSharedPreferences("MyPrefs", MODE_PRIVATE); + String userId = sharedPreferences.getString("id", ""); + + + + System.out.println("Value of userId: "+ userId); + logout = findViewById(R.id.logout); logout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Intent intent = new Intent(CheckInActivity.this, LoginActivity.class); + + + Intent intent = new Intent(CheckInActivity.this, LoginActivityNew.class); startActivity(intent); + finish(); } }); @@ -49,36 +169,95 @@ public class CheckInActivity extends AppCompatActivity { @Override public void onClick(View view) { LayoutInflater inflater = LayoutInflater.from(getApplicationContext()); - view = inflater.inflate(R.layout.layout, null); + view = inflater.inflate(R.layout.layout, null); TextView popup_log_out = view.findViewById(R.id.popup_log_out); + login = ""; + + + rel3 = view.findViewById(R.id.rel3); + if(!_approverstatus){ + rel3.setVisibility(View.GONE); + } + + + popup_log_out.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Intent intent = new Intent(CheckInActivity.this, LoginActivity.class); + Intent intent = new Intent(CheckInActivity.this, LoginActivityNew.class); + startActivity(intent); + finish(); + } + }); + System.out.println("Value of username "+ login); + if(login==""){ + + login = "User"; + + } + else{ + System.out.println("Value of username in else "+ login); + login = intent.getStringExtra("UserName"); + } + + + + + + TextView username = view.findViewById(R.id.username); + username.setText(loginFromShare); + + TextView request = view.findViewById(R.id.request); + + TextView permissionApproval = view.findViewById(R.id.permissionApproval); + permissionApproval.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(CheckInActivity.this, ApprovalListActivity.class); startActivity(intent); } }); + request.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(CheckInActivity.this, PermissionRequestActivity.class); + startActivity(intent); + //leaveApprover(); + } + }); + TextView report = view.findViewById(R.id.report); + report.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + - /*Button btn_confirm = view.findViewById(R.id.btn_confirm); - Button btn_cancel = view.findViewById(R.id.btn_cancel); - TextView txt_title = view.findViewById(R.id.txt_title); - TextView txt_content = view.findViewById(R.id.txt_content); + Intent intent = new Intent(CheckInActivity.this, ReportActivity.class); + startActivity(intent); + //getReport(); + //checkIn(); + } + }); + + TextView emergency = view.findViewById(R.id.emergency); + emergency.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + emergencySos(); + } + }); - btn_cancel.setVisibility(View.GONE); - btn_confirm.setText("OK"); - txt_title.setText("WARNING"); - txt_content.setText("This job is not active. Please synchronize to get the latest data, then contact your coordinator if needed.");*/ final AlertDialog alertDialog = new AlertDialog.Builder(CheckInActivity.this) .setView(view) .create(); alertDialog.show(); - alertDialog.getWindow().setLayout(600,460); - alertDialog.getWindow().setGravity(Gravity.TOP|Gravity.LEFT); + // alertDialog.getWindow().setLayout(780, ); + alertDialog.getWindow().setGravity(Gravity.TOP | Gravity.LEFT); alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); @@ -87,60 +266,635 @@ public class CheckInActivity extends AppCompatActivity { params.horizontalMargin = -100; alertDialog.getWindow().setAttributes(params); - /*btn_confirm.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - alertDialog.cancel(); - } - }); - btn_cancel.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - alertDialog.cancel(); - } - });*/ } }); - /*menu.setOnClickListener(new View.OnClickListener() { + + btnCheckIn = findViewById(R.id.btnCheckIn); + btnCheckIn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + System.out.println("Clicked check in button"); + checkInprssd = true; + System.out.println(checkInprssd); + //requestLocationUpdates(); + if (ContextCompat.checkSelfPermission(CheckInActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) { + // Permission granted, so request location updates + //requestLocationUpdates(); + targetLocationListFromCheckIn(); - // instance of alert dialog to build alert dialog - AlertDialog.Builder builder = new AlertDialog.Builder(CheckInActivity.this); - builder.setIcon(R.drawable.andrew); - builder.setTitle("Andrew Bahl"); - // builder.setMessage("Bottom Alert dialog"); + } else { + // Permission not granted, request it + ActivityCompat.requestPermissions(CheckInActivity.this, + new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, + LOCATION_PERMISSION_REQUEST_CODE); + } + } + }); + btnCheckOut = findViewById(R.id.btnCheckOut); + btnCheckOut.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + System.out.println("Clicked check in button"); - // set the neutral button to do some actions - builder.setNeutralButton("Logout", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent = new Intent(CheckInActivity.this, LoginActivity.class); - startActivity(intent); + //requestLocationUpdates(); + if (ContextCompat.checkSelfPermission(CheckInActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) { + // Permission granted, so request location updates + // requestLocationUpdates(); + targetLocationListFromCheckOut(); + + } else { + // Permission not granted, request it + ActivityCompat.requestPermissions(CheckInActivity.this, + new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, + LOCATION_PERMISSION_REQUEST_CODE); + } + } + }); + + SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean("loggedBefore",true); + editor.apply(); + + runOnce(); + + } + + private void runOnce() { + if (RUN_ONCE) { + RUN_ONCE = false; + FromRegister = true; + + // do something + } + else { + + new SweetAlertDialog(CheckInActivity.this, SweetAlertDialog.SUCCESS_TYPE) + .setTitleText(valueFromApiCheckIn) + .setConfirmText("OK") + .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { + @Override + public void onClick(SweetAlertDialog sDialog) { + sDialog.dismissWithAnimation(); + + } + }) + .setContentText(valueFromApiCheckInFromReg).show(); + + /*if(FromRegister){ + new SweetAlertDialog(CheckInActivity.this, SweetAlertDialog.SUCCESS_TYPE) + .setTitleText("You have checked in successfully") + .setConfirmText("Thanks you.") + .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { + @Override + public void onClick(SweetAlertDialog sDialog) { + sDialog.dismissWithAnimation(); + + } + }) + .setContentText("Have a productive day").show(); + } + else{ + new SweetAlertDialog(CheckInActivity.this, SweetAlertDialog.SUCCESS_TYPE) + .setTitleText("You have checked out successfully") + .setConfirmText("Thanks you.") + .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { + @Override + public void onClick(SweetAlertDialog sDialog) { + sDialog.dismissWithAnimation(); + + } + }) + .setContentText("").show(); + }*/ + + /*if(!backToCheck) { + if(checkInprssd){ + new SweetAlertDialog(CheckInActivity.this, SweetAlertDialog.SUCCESS_TYPE) + .setTitleText("You have checked in successfully") + .setConfirmText("Thanks you.") + .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { + @Override + public void onClick(SweetAlertDialog sDialog) { + sDialog.dismissWithAnimation(); + + } + }) + .setContentText("Have a productive day").show(); } - }); - // show the alert dialog - AlertDialog alertDialog = builder.create(); - alertDialog.show(); - alertDialog.getWindow().setLayout(800,400); - alertDialog.getWindow().setGravity(Gravity.TOP); - *//*PopupMenu popupMenu = new PopupMenu(CheckInActivity.this, menu); - popupMenu.getMenuInflater().inflate(R.menu.navigation_menu, popupMenu.getMenu()); - popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + + }*/ + } + } + + private void requestLocationUpdates() { + if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return; + } + fusedLocationClient = new FusedLocationProviderClient(getApplicationContext()); + fusedLocationClient.getLastLocation() + .addOnSuccessListener(this, new OnSuccessListener() { @Override - public boolean onMenuItemClick(MenuItem menuItem) { - // Toast message on menu item clicked - Toast.makeText(CheckInActivity.this, "You Clicked " + menuItem.getTitle(), Toast.LENGTH_SHORT).show(); - return true; + public void onSuccess(Location location) { + if (location != null) { + double latitude = location.getLatitude(); + double longitude = location.getLongitude(); + + // Do something with the latitude and longitude + String message = "Latitude: " + latitude + "\nLongitude: " + longitude; + System.out.println("My current location: "+ message); + Toast.makeText(CheckInActivity.this, message, Toast.LENGTH_SHORT).show(); + Location target = new Location(""); + target.setLatitude(latitude); + target.setLongitude(longitude); + + Location current = new Location(""); + current.setLatitude(20.5109958); + current.setLongitude(88.4009709); + + float distance = current.distanceTo(target); + System.out.println("Distance: "+distance); + if(distance<500){ + Toast.makeText(CheckInActivity.this, "You are out of range!Please get back to location", Toast.LENGTH_SHORT).show(); + //showFailedDialog(); + } + else{ + //showSuccessDialog(); + Toast.makeText(CheckInActivity.this, "Attendance ready to be captured", Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(CheckInActivity.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",true); + startActivity(intent); + } + } else { + Toast.makeText(CheckInActivity.this, "Location not available", Toast.LENGTH_SHORT).show(); + } } }); - // Showing the popup menu - popupMenu.show();*//* + + + } + public void leaveApprover(){ + final ProgressDialog loading = ProgressDialog.show(CheckInActivity.this, "Authenticating", "Please wait while logging", false, false); + String url= "http://43.242.212.92:7001/api/lgt/IsELeaveApprover?employeeid=27256"; + //String url= "http://43.242.212.92:7001/api/lgt/IsELeaveApprover?employeeid=29034"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + try { + JSONArray jsonArray=new JSONArray(response); + JSONObject jb1=jsonArray.getJSONObject(0); + _approverstatus=jb1.getBoolean("_approverstatus"); + + + + System.out.println("_approverstatus " + _approverstatus); + } catch (JSONException e) { + throw new RuntimeException(e); + } + + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(CheckInActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(CheckInActivity.this).add(stringRequest); + } + + public void emergencySos(){ + final ProgressDialog loading = ProgressDialog.show(CheckInActivity.this, "Authenticating", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/EmargencySOS"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + JSONObject jsonObject= null; + try { + jsonObject = new JSONObject(response); + } catch (JSONException e) { + throw new RuntimeException(e); + } + try { + valueEmer = jsonObject.getString("_statusMessage"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + Toast.makeText(CheckInActivity.this, valueEmer, Toast.LENGTH_LONG).show(); + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(CheckInActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + params.put("employeeid", "29034"); + params.put("userid", "skumar"); + + + return params; + } + }; + Volley.newRequestQueue(CheckInActivity.this).add(stringRequest); + } + public void getReport(){ + final ProgressDialog loading = ProgressDialog.show(CheckInActivity.this, "Authenticating", "Please wait ", false, false); + //String url= "http://43.242.212.92:7001/api/lgt/AttendanceReport"; + String url= "http://43.242.212.92:7001/api/lgt/AttendanceReport?employeeid="+"101"+"&fromdate="+"06/06/2023"+"&todate="+"06/07/2023"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + Toast.makeText(CheckInActivity.this, "Response successful", Toast.LENGTH_SHORT).show(); + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(CheckInActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + /*params.put("employeeid", "101"); + params.put("fromdate", "06/06/2023"); + params.put("todate", "06/07/2023");*/ + + return params; + } + }; + Volley.newRequestQueue(CheckInActivity.this).add(stringRequest); + } + public void checkIn(){ + final ProgressDialog loading = ProgressDialog.show(CheckInActivity.this, "Checking in", "Please wait while checking", false, false); + String url= "http://43.242.212.92:7001/api/lgt/CheckIn"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Log.d("data-=>",response); + + + try { + JSONObject jsonObject=new JSONObject(response); + valueFromApiCheckIn = jsonObject.getString("_statusMessage"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + + Toast.makeText(CheckInActivity.this, valueFromApiCheckIn, Toast.LENGTH_LONG).show(); + + Intent intent = new Intent(CheckInActivity.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",true); + intent.putExtra("valueFromApiCheckIn",valueFromApiCheckIn); + startActivity(intent); + + + loading.dismiss(); + + + } + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(CheckInActivity.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + params.put("employeeid", "101"); + params.put("location", "loca1"); + params.put("latitude", "10.235"); + params.put("longitude", "55.666"); + params.put("checkintime", currentDateAndTime); + params.put("locStateDevice", "1"); + params.put("locStateApp", "1"); + params.put("batteryPercent", "1"); + params.put("cellInfo", "1"); + params.put("accuracy", "1"); + params.put("locTS", "1"); + params.put("spoofingEnb", "0"); + params.put("providerNetTime", "10/07/2023 12:10:05"); + + return params; + } + }; + Volley.newRequestQueue(CheckInActivity.this).add(stringRequest); + } + public void checkOut(){ + final ProgressDialog loading = ProgressDialog.show(CheckInActivity.this, "Checking out", "Please wait while checking", false, false); + String url= "http://43.242.212.92:7001/api/lgt/CheckOut"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + try { + JSONObject jsonObject=new JSONObject(response); + valueFromApiCheckIn = jsonObject.getString("_statusMessage"); + + System.out.println("Value from api check out "+valueFromApiCheckIn); + } catch (JSONException e) { + throw new RuntimeException(e); + } + + Log.d("data-=>",response); + Toast.makeText(CheckInActivity.this, valueFromApiCheckIn, Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(CheckInActivity.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",true); + intent.putExtra("valueFromApiCheckIn",valueFromApiCheckIn); + startActivity(intent); + /*new SweetAlertDialog(CheckInActivity.this, SweetAlertDialog.SUCCESS_TYPE) + .setTitleText("You have successfully checked out.") + .setConfirmText("Face recognition") + .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { + @Override + public void onClick(SweetAlertDialog sDialog) { + sDialog.dismissWithAnimation(); + + } + }) + .setContentText("Thank you.").show();*/ + loading.dismiss(); + } + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(CheckInActivity.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + params.put("employeeid", "29034"); + params.put("location", "loca1"); + params.put("latitude", "10.235"); + params.put("longitude", "55.666"); + params.put("checkouttime", currentDateAndTime); + params.put("locStateDevice", "1"); + params.put("locStateApp", "1"); + params.put("batteryPercent", "1"); + params.put("cellInfo", "1"); + params.put("accuracy", "1"); + params.put("locTS", "1"); + params.put("spoofingEnb", "0"); + params.put("providerNetTime", "10/07/2023 12:10:05"); + + return params; } - });*/ + }; + Volley.newRequestQueue(CheckInActivity.this).add(stringRequest); } + public void targetLocationListFromCheckIn(){ + final ProgressDialog loading = ProgressDialog.show(CheckInActivity.this, "Checking location", "Please wait while checking", false, false); + String url= "http://43.242.212.92:7001/api/lgt/EmployeeLocation?employeeid=29034"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Log.d("data-=>",response); + try { + JSONObject jsonObject=new JSONObject(response); + JSONArray jsonArray=jsonObject.getJSONArray("_lstEmployee_Location"); + /*for(int i=0;i",error.getMessage()); + Toast.makeText(CheckInActivity.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(CheckInActivity.this).add(stringRequest); + } + + public void targetLocationListFromCheckOut(){ + final ProgressDialog loading = ProgressDialog.show(CheckInActivity.this, "Checking location", "Please wait while checking", false, false); + String url= "http://43.242.212.92:7001/api/lgt/EmployeeLocation?employeeid=29034"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Log.d("data-=>",response); + try { + JSONObject jsonObject=new JSONObject(response); + JSONArray jsonArray=jsonObject.getJSONArray("_lstEmployee_Location"); + /*for(int i=0;i",error.getMessage()); + Toast.makeText(CheckInActivity.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(CheckInActivity.this).add(stringRequest); + } + + private void showSuccessDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Success"); + builder.setMessage("Attendance ready to be captured."); + builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Perform any necessary action when the user clicks the "OK" button. + dialog.dismiss(); // Close the dialog. + } + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + } + private void showFailedDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Failed"); + builder.setMessage("You are out of range!Please get back to location"); + builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Perform any necessary action when the user clicks the "OK" button. + dialog.dismiss(); // Close the dialog. + } + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + } + + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // Permission granted, so request location updates + requestLocationUpdates(); + } else { + Toast.makeText(this, "Location permission denied", Toast.LENGTH_SHORT).show(); + } + } + } + } \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInNewActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInNewActivity.java new file mode 100644 index 0000000..a80194b --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/CheckInNewActivity.java @@ -0,0 +1,211 @@ +package ru.visionlab.femdemo; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.Location; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +import cn.pedant.SweetAlert.SweetAlertDialog; +import ru.visionlab.femdemo.register.RegisterActivity; + +public class CheckInNewActivity extends AppCompatActivity { + + TextView btnCheckIn,btnCheckOut; + private static final int LOCATION_PERMISSION_REQUEST_CODE = 1; + + String targetLat1="",targetlat2="",targetLon1="",targetLon2=""; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_check_in_new); + + /*new SweetAlertDialog(CheckInNewActivity.this, SweetAlertDialog.SUCCESS_TYPE) + .setTitleText("You have successfully checked out.") + .setConfirmText("Face recognition") + .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { + @Override + public void onClick(SweetAlertDialog sDialog) { + sDialog.dismissWithAnimation(); + + } + }) + .setContentText("Thank you.").show();*/ + + btnCheckIn = findViewById(R.id.btnCheckIn); + btnCheckIn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + System.out.println("Clicked check in button"); + //requestLocationUpdates(); + if (ContextCompat.checkSelfPermission(CheckInNewActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) { + // Permission granted, so request location updates + //requestLocationUpdates(); + targetLocationListFromCheckIn(); + + } else { + // Permission not granted, request it + ActivityCompat.requestPermissions(CheckInNewActivity.this, + new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, + LOCATION_PERMISSION_REQUEST_CODE); + } + } + }); + } + + public void targetLocationListFromCheckIn(){ + final ProgressDialog loading = ProgressDialog.show(CheckInNewActivity.this, "Checking location", "Please wait while checking", false, false); + String url= "http://43.242.212.92:7001/api/lgt/EmployeeLocation?employeeid=29034"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Log.d("data-=>",response); + try { + JSONObject jsonObject=new JSONObject(response); + JSONArray jsonArray=jsonObject.getJSONArray("_lstEmployee_Location"); + /*for(int i=0;i",error.getMessage()); + Toast.makeText(CheckInNewActivity.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(CheckInNewActivity.this).add(stringRequest); + } + + public void checkIn(){ + final ProgressDialog loading = ProgressDialog.show(CheckInNewActivity.this, "Checking in", "Please wait while checking", false, false); + String url= "http://43.242.212.92:7001/api/lgt/CheckIn"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Log.d("data-=>",response); + + + + Toast.makeText(CheckInNewActivity.this, "Attendance captured", Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(CheckInNewActivity.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",true); + intent.putExtra("FromNewCheck",true); + startActivity(intent); + + + loading.dismiss(); + + + } + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(CheckInNewActivity.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + params.put("employeeid", "101"); + params.put("location", "loca1"); + params.put("latitude", "10.235"); + params.put("longitude", "55.666"); + params.put("checkintime", "10/07/2023 12:10:05"); + params.put("locStateDevice", "1"); + params.put("locStateApp", "1"); + params.put("batteryPercent", "1"); + params.put("cellInfo", "1"); + params.put("accuracy", "1"); + params.put("locTS", "1"); + params.put("spoofingEnb", "0"); + params.put("providerNetTime", "10/07/2023 12:10:05"); + + return params; + } + }; + Volley.newRequestQueue(CheckInNewActivity.this).add(stringRequest); + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestActivity.java new file mode 100644 index 0000000..abd2d09 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestActivity.java @@ -0,0 +1,47 @@ +package ru.visionlab.femdemo; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageButton; +import android.widget.LinearLayout; + +public class LeaveRequestActivity extends AppCompatActivity { + LinearLayout lin1,lin2; + + ImageButton back; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_leave_request); + + back = findViewById(R.id.back); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onBackPressed(); + } + }); + + lin1 = findViewById(R.id.lin1); + lin1.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(LeaveRequestActivity.this, LeaveRequestDetailsActivity.class); + startActivity(intent); + } + }); + + lin2 = findViewById(R.id.lin2); + lin2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(LeaveRequestActivity.this, LeaveRequestDetailsActivity.class); + startActivity(intent); + } + }); + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestDetailsActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestDetailsActivity.java new file mode 100644 index 0000000..280fc85 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/LeaveRequestDetailsActivity.java @@ -0,0 +1,115 @@ +package ru.visionlab.femdemo; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.ProgressDialog; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +import ru.visionlab.femdemo.R; + +public class LeaveRequestDetailsActivity extends AppCompatActivity { + + Button btnapprove,btnreject; + + ImageButton back; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_leave_request_details); + + back = findViewById(R.id.back); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onBackPressed(); + } + }); + + btnapprove = findViewById(R.id.btnapprove); + btnapprove.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + PermissionApprovalAction(); + } + }); + + btnreject = findViewById(R.id.btnreject); + } + + public void PermissionApprovalAction(){ + + + final ProgressDialog loading = ProgressDialog.show(LeaveRequestDetailsActivity.this, "Fetching information", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/PermissionApprovalAction"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + + try { + JSONObject jsonObject = new JSONObject(response); + String _statusMessage3 = jsonObject.getString("_statusMessage"); + System.out.println("_statusMessage "+_statusMessage3); + if(_statusMessage3.equals("Saved Successfully")){ + Toast.makeText(LeaveRequestDetailsActivity.this, "Current Status :A", Toast.LENGTH_SHORT).show(); + } + + } catch (JSONException e) { + throw new RuntimeException(e); + } + + + + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(LeaveRequestDetailsActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + params.put("permissionID", "27507"); + params.put("eleavetype", "27256"); + params.put("actionby", "asaif"); + params.put("remark", "Testing Approve"); + params.put("actionflag", "A"); + + + + return params; + } + }; + Volley.newRequestQueue(LeaveRequestDetailsActivity.this).add(stringRequest); + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/PermissionRequestActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/PermissionRequestActivity.java new file mode 100644 index 0000000..d1e026f --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/PermissionRequestActivity.java @@ -0,0 +1,383 @@ +package ru.visionlab.femdemo; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.ProgressDialog; +import android.app.TimePickerDialog; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.TimePicker; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; + +import ru.visionlab.femdemo.R; +import ru.visionlab.femdemo.login.LoginActivity; + +public class PermissionRequestActivity extends AppCompatActivity { + + ImageButton back; + Button btnSubmit,btn_private; + String _statusMessage; + EditText edtRemarks; + String remarks=""; + LinearLayout timePickerFrom,timePickerTo; + private int mDay, mHour, mMinute; + TextView textTimeFrom,textTimeTo; + + LinearLayout linearLayout1; + + Spinner spinner; + + String permission_type; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_permission_request); + linearLayout1 = findViewById(R.id.linearLayout1); + + IsELeaveApprover(); + //PermissionInsert(); + PermissionApprovalList(); + PermissionTypes(); + + + spinner = findViewById(R.id.spinner); + ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.spinner_items, android.R.layout.simple_spinner_item); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parentView, View selectedItemView, int position, long id) { + // Handle the selected item here + permission_type = parentView.getItemAtPosition(position).toString(); + System.out.println("Value of permission_type "+permission_type); + // Do something with the selected item + } + + @Override + public void onNothingSelected(AdapterView parentView) { + // Handle the case where nothing is selected (if needed) + } + }); + + + back = findViewById(R.id.back); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + /*Intent intent = new Intent(PermissionRequestActivity.this, CheckInActivity.class); + intent.putExtra("backToCheck",true); + startActivity(intent);*/ + onBackPressed(); + + } + }); + + btn_private = findViewById(R.id.btn_private); + btn_private.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(PermissionRequestActivity.this, LeaveRequestActivity.class); + startActivity(intent); + } + }); + + btnSubmit = findViewById(R.id.btnSubmit); + btnSubmit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + getPermission(); + } + }); + edtRemarks = findViewById(R.id.edtRemarks); + + timePickerFrom = findViewById(R.id.timePickerFrom); + textTimeFrom = findViewById(R.id.textTimeFrom); + timePickerFrom.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + final Calendar c = Calendar.getInstance(); + mHour = c.get(Calendar.HOUR_OF_DAY); + mMinute = c.get(Calendar.MINUTE); + + // Launch Time Picker Dialog + TimePickerDialog timePickerDialog = new TimePickerDialog(PermissionRequestActivity.this, + new android.app.TimePickerDialog.OnTimeSetListener() { + + @Override + public void onTimeSet(TimePicker view, int hourOfDay, + int minute) { + + + + textTimeFrom.setText(hourOfDay + ":" + minute); + } + }, mHour, mMinute, false); + timePickerDialog.show(); + } + }); + timePickerTo = findViewById(R.id.timePickerTo); + textTimeTo = findViewById(R.id.textTimeTo); + timePickerTo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + final Calendar c = Calendar.getInstance(); + mHour = c.get(Calendar.HOUR_OF_DAY); + mMinute = c.get(Calendar.MINUTE); + + // Launch Time Picker Dialog + TimePickerDialog timePickerDialog = new TimePickerDialog(PermissionRequestActivity.this, + new android.app.TimePickerDialog.OnTimeSetListener() { + + @Override + public void onTimeSet(TimePicker view, int hourOfDay, + int minute) { + + + + textTimeTo.setText(hourOfDay + ":" + minute); + } + }, mHour, mMinute, false); + timePickerDialog.show(); + } + }); + + + + + } + + public void getPermission(){ + final ProgressDialog loading = ProgressDialog.show(PermissionRequestActivity.this, "Fetching information", "Please wait ", false, false); + remarks = edtRemarks.getText().toString(); + String url= "http://43.242.212.92:7001/api/lgt/PermissionInsert"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + JSONObject jsonObject= null; + try { + jsonObject = new JSONObject(response); + } catch (JSONException e) { + throw new RuntimeException(e); + } + try { + _statusMessage = jsonObject.getString("_statusMessage"); + System.out.println("Status message: "+_statusMessage); + } catch (JSONException e) { + throw new RuntimeException(e); + } + Toast.makeText(PermissionRequestActivity.this, _statusMessage, Toast.LENGTH_SHORT).show(); + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(PermissionRequestActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + params.put("employeeid", "101"); + params.put("eleavetype", "P"); + params.put("datedaytype", "Today"); + params.put("fromtime", "13:22"); + params.put("totime", "15:22"); + params.put("reason", remarks); + params.put("attachment", ""); + params.put("userid", "a"); + + + return params; + } + }; + Volley.newRequestQueue(PermissionRequestActivity.this).add(stringRequest); + } + public void IsELeaveApprover(){ + + + final ProgressDialog loading = ProgressDialog.show(PermissionRequestActivity.this, "Fetching information", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/IsELeaveApprover?employeeid=29034"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + + try { + JSONArray jsonArray=new JSONArray(response); + JSONObject jb1=jsonArray.getJSONObject(0); + boolean _approverstatus=jb1.getBoolean("_approverstatus"); + + if(!_approverstatus){ + linearLayout1.setVisibility(View.GONE); + } + + + System.out.println("_approverstatus " + _approverstatus); + } catch (JSONException e) { + throw new RuntimeException(e); + } + + + + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(PermissionRequestActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(PermissionRequestActivity.this).add(stringRequest); + } + + public void PermissionInsert(){ + final ProgressDialog loading = ProgressDialog.show(PermissionRequestActivity.this, "Fetching information", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/PermissionInsert"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + try { + JSONObject jsonObject = new JSONObject(response); + String _statusMessage = jsonObject.getString("_statusMessage"); + System.out.println("_statusMessage "+_statusMessage); + } catch (JSONException e) { + throw new RuntimeException(e); + } + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(PermissionRequestActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + params.put("employeeid", "101"); + params.put("eleavetype", "P"); + params.put("datedaytype", "Today"); + params.put("fromtime", "13:22"); + params.put("totime", "15:22"); + params.put("reason", "Meeting"); + params.put("attachment", ""); + params.put("userid", "a"); + params.put("startdate", "demouser1"); + params.put("enddate", ""); + + + return params; + } + }; + Volley.newRequestQueue(PermissionRequestActivity.this).add(stringRequest); + } + public void PermissionApprovalList(){ + final ProgressDialog loading = ProgressDialog.show(PermissionRequestActivity.this, "Fetching information", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/PermissionApprovallist?ApproverID=27256"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Toast.makeText(PermissionRequestActivity.this, "Response successful1", Toast.LENGTH_SHORT).show(); + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(PermissionRequestActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(PermissionRequestActivity.this).add(stringRequest); + } + public void PermissionTypes(){ + final ProgressDialog loading = ProgressDialog.show(PermissionRequestActivity.this, "Fetching information", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/PermissionTypes"; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Toast.makeText(PermissionRequestActivity.this, "Response successful2", Toast.LENGTH_SHORT).show(); + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(PermissionRequestActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + + }; + Volley.newRequestQueue(PermissionRequestActivity.this).add(stringRequest); + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/RegisterFromCheckActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/RegisterFromCheckActivity.java new file mode 100644 index 0000000..0f22b92 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/RegisterFromCheckActivity.java @@ -0,0 +1,565 @@ +package ru.visionlab.femdemo; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Intent; +import android.graphics.Bitmap; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.provider.MediaStore; +import android.util.Base64; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +import com.tbruyelle.rxpermissions.RxPermissions; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.net.SocketException; +import java.util.List; + +import javax.inject.Inject; + +import butterknife.BindView; +import cn.pedant.SweetAlert.SweetAlertDialog; +import ru.PreferenceManager.PreferenceManager; +import ru.visionlab.femdemo.CheckInActivity; +import ru.visionlab.femdemo.Config; +import ru.visionlab.femdemo.Core.PhotoProcessor; +import ru.visionlab.femdemo.App; +import ru.visionlab.femdemo.BuildConfig; +import ru.visionlab.femdemo.LocationHelper; +import ru.visionlab.femdemo.R; +import ru.visionlab.femdemo.Storage; +import ru.visionlab.femdemo.Utils; +import ru.visionlab.femdemo.api.RegisterApiImplLuna2; +import ru.visionlab.femdemo.api.RegisterApiImplLocal; +import ru.visionlab.femdemo.api.RegisterApiInterface; +import ru.visionlab.femdemo.api.VLApi; +import ru.visionlab.femdemo.api.VerifyApiImplLuna2; +import ru.visionlab.femdemo.api.VerifyApiImplLunaLocal; +import ru.visionlab.femdemo.api.VerifyApiInterface; +import ru.visionlab.femdemo.authentication.AuthSuccessActivity; +import ru.visionlab.femdemo.authentication.AuthenticationActivity; +import ru.visionlab.femdemo.authentication.FaceNotRecognizedFragment; +import ru.visionlab.femdemo.base.PhotoFragment; +import ru.visionlab.femdemo.base.ToolbarActivity; +import ru.visionlab.femdemo.login.LoginActivity; +import ru.visionlab.femdemo.login.LoginActivityNew; +import ru.visionlab.femdemo.models.SearchResult; +import ru.visionlab.femdemo.models.SearchResultPerson; +import ru.visionlab.femdemo.register.FaceNotFoundFragment; +import ru.visionlab.femdemo.register.RegisterFragment; +import ru.visionlab.femdemo.register.RegistrationModel; +import ru.visionlab.femdemo.register.SavePhotoFragment; +import ru.visionlab.femdemo.settings.VLPreferences; + +public class RegisterFromCheckActivity extends ToolbarActivity implements RegisterFragment.Listener, PhotoFragment.Listener, + SavePhotoFragment.Listener, FaceNotFoundFragment.Listener, RegisterApiInterface.Listener, VerifyApiInterface.Listener, FaceNotRecognizedFragment.Listener{ + + public static final String REGISTER_FRAGMENT = "REGISTER FRAGMENT"; + public static final String PHOTO_FRAGMENT = "PHOTO_FRAGMENT"; + public static final String SAVE_PHOTO_FRAGMENT = "SAVE PHOTO FRAGMENT"; + public static final String FACE_NOT_FOUND_FRAGMENT = "FACE NOT FOUND FRAGMENT"; + public static final String SAVE_PHOTO_NAME = "PhotomakerAndroidDemo Registration Photo"; + private Thread thread; + EditText compId,username,otp; + String company_ID="",user="",OTP=""; + + + @Inject + VLPreferences preferences; + + @Inject + VLApi api; + + @Inject + LocationHelper locationHelper; + + @Inject + PhotoProcessor photoProcessor; + @Nullable + @BindView(R.id.toolbar) + Toolbar toolbar; + + Bitmap bitmap; + + RegistrationModel registrationModel; + + ImageButton back_img; + Button verifynproceed; + ImageView photo; + private static final int pic_id = 123; + PreferenceManager preferenceManager; + Bitmap photo2=null; + Button save,retry; + String encodedImage=""; + boolean fromLoginPage,FromNewCheck; + private PhotoFragment fragment; + String login; + private long verifEndTime; + private long verifStartTime; + + private int faceFailCount; + + private boolean goingSomewhere = false; + + @SuppressLint("MissingInflatedId") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ((App) getApplication()).getComponent().inject(this); + setContentView(R.layout.activity_register); + + //ButterKnife.bind(this); + setToolbar(); + Intent intent = getIntent(); + fromLoginPage = intent.getBooleanExtra("FromLoginPage",true); + System.out.println("Value of FromLoginPage "+fromLoginPage); + if(fromLoginPage){ + showPhotoScreen(); + } + else { + showRegisterScreen(); + } + FromNewCheck = intent.getBooleanExtra("FromLoginPage",false); + System.out.println("Value of FromNewCheck "+FromNewCheck); + + + /*back_img.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(RegisterActivity.this, LoginActivity.class); + startActivity(intent); + } + });*/ + // compId = findViewById(R.id.compId); +// username = findViewById(R.id.username); + // otp = findViewById(R.id.otp); + + + // company_ID = compId.getText().toString().trim(); +// user = username.getText().toString().trim(); + // OTP = otp.getText().toString().trim(); + + /*verifynproceed = findViewById(R.id.verifynproceed); + verifynproceed.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(company_ID.equals("002") *//*&& user.equals("34") *//* && OTP.equals("444")){ + Intent intent = new Intent(RegisterActivity.this, LoginActivity.class); + startActivity(intent); + } + } + });*/ + + preferenceManager=PreferenceManager.getInstance(this); + } + + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + // Match the request 'pic id with requestCode + if (requestCode == pic_id) { + // BitMap is data structure of image file which store the image in memory + photo2 = (Bitmap) data.getExtras().get("data"); + // Set the image in imageview for display + + if(photo2.equals("") || photo2==null){ + photo.setBackgroundResource(R.drawable.user1); + + } + else { + photo.setImageDrawable(null); + photo.setImageBitmap(photo2); + System.out.println("imageview "+ photo.getDrawable()); + System.out.println("imageview photo2 "+ photo2); + + Toast.makeText(this, "Image set", Toast.LENGTH_SHORT).show(); + } + + } + } + + @Override + protected void onDestroy() + { + photoProcessor.release(); + super.onDestroy(); + } + + private void showRegisterScreen() { + final RegisterFragment fragment = RegisterFragment.newInstance(); + fragment.setListener(this); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.container, fragment, PHOTO_FRAGMENT) + .addToBackStack(fragment.toString()) + .commit(); + } + + private void setToolbar() { + setSupportActionBar(toolbar); + final ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayShowHomeEnabled(true); + } + } + + @Override + public void onBackPressed() { + Log.i("STATUS","STACK COUNT "+getSupportFragmentManager().getBackStackEntryCount()); + preferences.setStartTime(String.valueOf(System.currentTimeMillis())); + if (getSupportFragmentManager().getBackStackEntryCount() > 1) { + getSupportFragmentManager().popBackStack(); + } else { + super.onBackPressed(); + } + } + + @Override + public void onSignUpClick(RegistrationModel registrationModel) { + if((!BuildConfig.IS_OFFLINE_VERSION) && preferences.getLuna2()) { + thread = new Thread(() -> { + Storage.getInstance().updateDatabase(preferences.getLuna2Server(), preferences.getEncodedUserData(), api, preferences.getServerChanged()); + }); + thread.start(); + } + this.registrationModel = registrationModel; + Utils.hideKeyboard(this, getCurrentFocus()); + new Handler().post(this::showPhotoScreen); + } + + private void showPhotoScreen() { + fragment = PhotoFragment.newInstance(); + fragment.setPhotoProcessor(photoProcessor); + fragment.setListener(this); + fragment.enableLivenessCheck(false); + + preferences.setStartTime(String.valueOf(System.currentTimeMillis())); + preferences.setNeedPortrait(false); + System.out.println("Inside photo screen method"); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.container, fragment, PHOTO_FRAGMENT) + .addToBackStack(fragment.toString()) + .commit(); + } + + private void showPhotoReadyScreen(Bitmap bitmap) { + final SavePhotoFragment fragment = SavePhotoFragment.newInstance(); + fragment.setPhoto(bitmap); + fragment.setListener(this); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.container, fragment, SAVE_PHOTO_FRAGMENT) + .addToBackStack(fragment.toString()) + .commit(); + System.out.println("Inside save photo screen method"); + } + + @Override + public void onBestFrameReady(Bitmap bitmap) { + this.bitmap = bitmap; + if(fromLoginPage){ + verifyPhoto(bitmap); + } + showPhotoReadyScreen(bitmap); + } + + private void verifyPhoto(Bitmap bitmap){ + fragment.showWaitState(); + login=preferences.getUsername(); + System.out.println("Value of login while verification " + login); + try { + if (thread != null) + thread.join(); + }catch (InterruptedException e) { + e.printStackTrace(); + } + VerifyApiInterface verifyApi; + if (BuildConfig.IS_OFFLINE_VERSION) { + verifyApi = new VerifyApiImplLunaLocal(this, photoProcessor, login, this); + } else { //if (preferences.getLuna2()) { + Log.i("LUNA2 ", preferences.getLuna2Server()); + verifyApi = new VerifyApiImplLuna2(this, preferences.getLuna2Server(), login, api, this, bitmap, preferences.getEncodedUserData()); + } + + verifStartTime = System.nanoTime(); + verifyApi.verifyPerson(); + } + + @Override + public void onTimeout(FaceNotFoundFragment.Reason reason) { + final FaceNotFoundFragment fragment = FaceNotFoundFragment.newInstance(); + fragment.setReason(reason); + fragment.setListener(this); + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.container, fragment, FACE_NOT_FOUND_FRAGMENT) + .addToBackStack(fragment.toString()) + .commit(); + } + + @Override + public void onNeedCameraPermission() { + goToAppDetails(R.string.permission_need_for_register); + } + + @Override + public void onInteractionWaitingOpenedEyes() {} + + @Override + public void onTimeout(){} + + @Override + public void onLivenessResult(int livenessState, int blinkState, int livenessType){} + + @Override + public void onRetryClick() { + onBackPressed(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + if (menuItem.getItemId() == android.R.id.home) { + if (getSupportFragmentManager().findFragmentByTag(SAVE_PHOTO_FRAGMENT) != null) { + getSupportFragmentManager().popBackStack(); + getSupportFragmentManager().popBackStack(); + return true; + } + } + return super.onOptionsItemSelected(menuItem); + } + + @Override + public void onSaveClick() { + registerPerson(); + } + + private void registerPerson() { + RegisterApiInterface registerApi; + try { + if (thread != null) { + thread.join(); + } + }catch (InterruptedException e){ + e.printStackTrace(); + } + + if (BuildConfig.IS_OFFLINE_VERSION) { + registerApi = new RegisterApiImplLocal(this, registrationModel, photoProcessor, this, bitmap); + } else { + registerApi = new RegisterApiImplLuna2(this, preferences.getLuna2Server(), registrationModel, api, locationHelper, this, bitmap, preferences.getEncodedUserData()); + } + + registerApi.registerPerson(); + } + + private void SaveBitmapToGallery(Bitmap finalBitmap) { + String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString(); + + File myDir = new File(root + "/saved_images"); + myDir.mkdirs(); + + File file = null; + int num = 0; + // find next name + do { + try { + file = new File (myDir, new String(SAVE_PHOTO_NAME + num + ".jpg")); + } catch (Exception e) { + e.printStackTrace(); + break; + } + + ++num; + } + while(file.exists()); + + try { + FileOutputStream out = new FileOutputStream(file); + finalBitmap.compress(Bitmap.CompressFormat.JPEG, 50, out); + out.flush(); + out.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + + // Tell the media scanner about the new file so that it is + // immediately available to the user. + MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null, + new MediaScannerConnection.OnScanCompletedListener() { + public void onScanCompleted(String path, Uri uri) { + Log.i("ExternalStorage", "Scanned " + path + ":"); + Log.i("ExternalStorage", "-> uri=" + uri); + } + }); + System.out.println("Inside saving image method"); + } + + @Override + public void onRegistrationFail(Throwable throwable) { + + if(throwable instanceof RegisterApiImplLuna2.InternetConnectionException){ + Toast.makeText(this,getResources().getString(R.string.bad_internet_conneciton), Toast.LENGTH_LONG).show(); + }else if(throwable instanceof RegisterApiImplLuna2.SocketTimeOutException || + throwable instanceof SocketException) { + Toast.makeText(this,getResources().getString(R.string.TimeOut), Toast.LENGTH_LONG).show(); + }else if(throwable instanceof RegisterApiImplLuna2.WrongAccDataException){ + Toast.makeText(this,getResources().getString(R.string.bad_acc_data), Toast.LENGTH_LONG).show(); + }else if(throwable instanceof RegisterApiImplLuna2.WrongServAddrException || + throwable instanceof IllegalArgumentException){ + Toast.makeText(this,getResources().getString(R.string.bad_server_address), Toast.LENGTH_LONG).show(); + }else if(throwable instanceof retrofit2.adapter.rxjava.HttpException ){ + Toast.makeText(this,throwable.getMessage(), Toast.LENGTH_LONG).show(); + } + else if(throwable instanceof RegisterApiImplLocal.DescriptorNotExtractedException) { + Toast.makeText(this,throwable.getMessage(), Toast.LENGTH_LONG).show(); + } + + if(preferences.getLuna2()){ + Storage.getInstance().clearConnectionFlags(); + } + if (getSupportFragmentManager().findFragmentByTag(SAVE_PHOTO_FRAGMENT) != null) { + getSupportFragmentManager().popBackStack(); + getSupportFragmentManager().popBackStack(); + } + } + + @Override + public void onRegistrationSuccess() { + preferences.setServerChanged(false); + if (preferences.getSavePhoto()) { + RxPermissions.getInstance(this) + .request(Manifest.permission.WRITE_EXTERNAL_STORAGE) + .subscribe(granted -> { + if (granted) { + SaveBitmapToGallery(bitmap); + + Toast.makeText(this, R.string.photo_saved_to_gallery, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, R.string.permission_need_for_write_external, Toast.LENGTH_SHORT).show(); + } + + // finish on any case + finishRegistration(); + }); + } + else + { + finishRegistration(); + } + } + + private void finishRegistration() + { + preferences.setUsername(registrationModel.login); + + // preferences.setPin(registrationModel.password); + Intent intent = new Intent(RegisterFromCheckActivity.this, LoginActivityNew.class); + startActivity(intent); + finish(); + } + + @Override + public void onVerificationSuccess(SearchResult searchResult) { + verifEndTime = System.nanoTime(); + preferences.setServerChanged(false); + final List persons = searchResult.getPersons(); + if (persons != null && !persons.isEmpty()) { + final SearchResultPerson person = persons.get(0); + if (person.similarity > Config.MIN_SIMILARITY) { + onFaceAuthSuccess(); + } else { + onFaceAuthFail(AuthenticationActivity.AuthFailReason.SIMILARITY); + } + } else { + onFaceAuthFail(AuthenticationActivity.AuthFailReason.SIMILARITY); + } + } + + @Override + public void onVerificationFail(Throwable throwable) { + + } + + private void onFaceAuthSuccess() { + showSuccess(); + /*if (preferences.getFingerAuth()) { + onFingerClick(finger); + } else { + showSuccess(); + }*/ + } + private void showSuccess() { + + + + final Intent intent = new Intent(RegisterFromCheckActivity.this, CheckInActivity.class); + intent.putExtra(AuthSuccessActivity.LOGIN, login); + intent.putExtra("FromRegisterCheck", true); + + if (BuildConfig.IS_OFFLINE_VERSION) { + intent.putExtra(AuthSuccessActivity.TIME, (int) (((double) (verifEndTime - verifStartTime)) / 1e6)); + } + + startActivity(intent); + + finish(); + + + + } + + private void onFaceAuthFail(AuthenticationActivity.AuthFailReason reason) { + if (faceFailCount < 4) { + final FaceNotRecognizedFragment fragment = FaceNotRecognizedFragment.newInstance(); + fragment.setListener(this); + if (reason == AuthenticationActivity.AuthFailReason.SIMILARITY && BuildConfig.IS_OFFLINE_VERSION) + { + fragment.setVerificationTime((int)((double)(verifEndTime - verifStartTime) / 1e6)); + } + fragment.setFailReason(reason); + showFragment(fragment); + } else { + showFail(); + } + } + + private void showFail() { + Toast.makeText(this, R.string.access_denied, Toast.LENGTH_SHORT).show(); + finish(); + } + + private void showFragment(Fragment fragment) { + final FragmentManager fragmentManager = getSupportFragmentManager(); + if (fragmentManager.findFragmentByTag(fragment.toString()) == null) { + if (!goingSomewhere) { + goingSomewhere = true; + fragmentManager + .beginTransaction() + .replace(R.id.container, fragment, fragment.toString()) + .commit(); + goingSomewhere = false; + } + } + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportActivity.java new file mode 100644 index 0000000..a849969 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportActivity.java @@ -0,0 +1,203 @@ +package ru.visionlab.femdemo; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.DatePickerDialog; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; + +public class ReportActivity extends AppCompatActivity { + + Button btnReport; + ImageButton back; + + LinearLayout fromDate,toDate; + TextView textFromDate,textToDate; + + int yearFrom,monthOfYearFrom,dayOfmonthFrom; + int yearTo,monthOfYearTo,dayOfmonthTo; + + String valuefromApi=""; + + String passingDateFrom,passingDateTo; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_report); + + btnReport = findViewById(R.id.btnReport); + btnReport.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + Intent intent = new Intent(ReportActivity.this, ReportDetailsActivity.class); + intent.putExtra("passingDateFrom",passingDateFrom); + intent.putExtra("passingDateTo",passingDateTo); + startActivity(intent); + //getReport(); + } + }); + back = findViewById(R.id.back); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + /*Intent intent = new Intent(ReportActivity.this, CheckInActivity.class); + intent.putExtra("backToCheck",true); + startActivity(intent);*/ + onBackPressed(); + } + }); + + fromDate = findViewById(R.id.fromDate); + textFromDate = findViewById(R.id.textFromDate); + fromDate.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + final Calendar c = Calendar.getInstance(); + int year = c.get(Calendar.YEAR); + int month = c.get(Calendar.MONTH); + int day = c.get(Calendar.DAY_OF_MONTH); + + DatePickerDialog datePickerDialog = new DatePickerDialog( + // on below line we are passing context. + ReportActivity.this, + new DatePickerDialog.OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int year, + int monthOfYear, int dayOfMonth) { + // on below line we are setting date to our text view. + textFromDate.setText(dayOfMonth + "/" + (monthOfYear + 1) + "/" + year); + + yearFrom = year; + dayOfmonthFrom = dayOfMonth; + monthOfYearFrom = monthOfYear; + + System.out.println("Date from values: " + dayOfmonthFrom + "/" + (monthOfYearFrom + 1) + "/" + yearFrom); + + passingDateFrom = dayOfmonthFrom + "/" + (monthOfYearFrom + 1) + "/" + yearFrom; + System.out.println("passingDateFrom " + passingDateFrom); + } + }, + // on below line we are passing year, + // month and day for selected date in our date picker. + year, month, day); + // at last we are calling show to + // display our date picker dialog. + datePickerDialog.show(); + + } + }); + + toDate = findViewById(R.id.toDate); + textToDate = findViewById(R.id.textToDate); + toDate.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + final Calendar c = Calendar.getInstance(); + int year = c.get(Calendar.YEAR); + int month = c.get(Calendar.MONTH); + int day = c.get(Calendar.DAY_OF_MONTH); + + DatePickerDialog datePickerDialog = new DatePickerDialog( + // on below line we are passing context. + ReportActivity.this, + new DatePickerDialog.OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int year, + int monthOfYear, int dayOfMonth) { + // on below line we are setting date to our text view. + textToDate.setText(dayOfMonth + "/" + (monthOfYear + 1) + "/" + year); + + yearTo = year; + dayOfmonthTo = dayOfMonth; + monthOfYearTo = monthOfYear; + + System.out.println("Date from values: " + dayOfmonthTo + "/" + (monthOfYearTo + 1) + "/" + yearTo); + + passingDateTo = dayOfmonthTo + "/" + (monthOfYearTo + 1) + "/" + yearTo; + System.out.println("passingDateTo " + passingDateTo); + + } + }, + // on below line we are passing year, + // month and day for selected date in our date picker. + year, month, day); + // at last we are calling show to + // display our date picker dialog. + datePickerDialog.show(); + + } + }); + + } + + public void getReport(){ + final ProgressDialog loading = ProgressDialog.show(ReportActivity.this, "Authenticating", "Please wait ", false, false); + //String url= "http://43.242.212.92:7001/api/lgt/AttendanceReport"; + //String url= "http://43.242.212.92:7001/api/lgt/AttendanceReport?employeeid="+"101"+"&fromdate="+"06/06/2023"+"&todate="+"06/07/2023"; + String url= "http://43.242.212.92:7001/api/lgt/AttendanceReport?employeeid="+"101"+"&fromdate="+dayOfmonthFrom + "/" + (monthOfYearFrom + 1) + "/" + yearFrom+"&todate="+dayOfmonthTo + "/" + (monthOfYearTo + 1) + "/" + yearTo; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + try { + JSONObject jsonObject=new JSONObject(response); + JSONObject jb1=jsonObject.getJSONObject("statusModel"); + valuefromApi = jb1.getString("_statusMessage"); + System.out.println("Report status from api " + valuefromApi); + } catch (JSONException e) { + throw new RuntimeException(e); + } + Toast.makeText(ReportActivity.this, valuefromApi, Toast.LENGTH_SHORT).show(); + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(ReportActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + /*params.put("employeeid", "101"); + params.put("fromdate", "06/06/2023"); + params.put("todate", "06/07/2023");*/ + + return params; + } + }; + Volley.newRequestQueue(ReportActivity.this).add(stringRequest); + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportDetailsActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportDetailsActivity.java new file mode 100644 index 0000000..ed4d2a2 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/ReportDetailsActivity.java @@ -0,0 +1,122 @@ +package ru.visionlab.femdemo; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +public class ReportDetailsActivity extends AppCompatActivity { + + String passingDateFrom,passingDateTo; + TextView empIdVal,pdateVal,Check_InVal,Check_OutVal,statusVal; + + ImageView back; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_report_details); + + empIdVal = findViewById(R.id.empIdVal); + pdateVal = findViewById(R.id.pdateVal); + Check_InVal = findViewById(R.id.Check_InVal); + Check_OutVal = findViewById(R.id.Check_OutVal); + statusVal = findViewById(R.id.statusVal); + + back = findViewById(R.id.back); + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(ReportDetailsActivity.this, ReportActivity.class); + startActivity(intent); + } + }); + + + + Intent intent = getIntent(); + passingDateFrom = intent.getStringExtra("passingDateFrom"); + passingDateTo = intent.getStringExtra("passingDateTo"); + + System.out.println("passingDateFrom " + passingDateFrom + " " + passingDateTo); + + getReport(); + } + + public void getReport(){ + final ProgressDialog loading = ProgressDialog.show(ReportDetailsActivity.this, "Authenticating", "Please wait ", false, false); + + String url= "http://43.242.212.92:7001/api/lgt/AttendanceReport?employeeid="+"101"+"&fromdate="+passingDateFrom+"&todate="+passingDateTo; + StringRequest stringRequest=new StringRequest(Request.Method.GET, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + try { + JSONObject jsonObject=new JSONObject(response); + JSONArray jsonArray=jsonObject.getJSONArray("_lstAttendanceData"); + JSONObject jb1=jsonArray.getJSONObject(0); + String EmployeeID = jb1.getString("EmployeeID"); + String pdate = jb1.getString("pdate"); + String Check_In = jb1.getString("Check_In"); + String Check_Out = jb1.getString("Check_Out"); + String status = jb1.getString("status"); + + empIdVal.setText(EmployeeID); + pdateVal.setText(pdate); + Check_InVal.setText(Check_In); + Check_OutVal.setText(Check_Out); + statusVal.setText(status); + + System.out.println("data from api " + EmployeeID + " " + pdate+" "+Check_In+" "+Check_Out+" "+status); + } catch (JSONException e) { + throw new RuntimeException(e); + } + + + Toast.makeText(ReportDetailsActivity.this, "Successfull" , Toast.LENGTH_SHORT).show(); + loading.dismiss(); + } + + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(ReportDetailsActivity.this, "Failed to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + loading.dismiss(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() { + Map params = new HashMap(); + + /*params.put("employeeid", "101"); + params.put("fromdate", "06/06/2023"); + params.put("todate", "06/07/2023");*/ + + return params; + } + }; + Volley.newRequestQueue(ReportDetailsActivity.this).add(stringRequest); + } +} \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Splashactivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Splashactivity.java index 48f1828..5131472 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Splashactivity.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Splashactivity.java @@ -2,12 +2,16 @@ package ru.visionlab.femdemo; import androidx.appcompat.app.AppCompatActivity; +import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.view.WindowManager; +import cn.pedant.SweetAlert.SweetAlertDialog; import ru.visionlab.femdemo.login.LoginActivity; +import ru.visionlab.femdemo.login.LoginActivityNew; public class Splashactivity extends AppCompatActivity { @@ -23,15 +27,28 @@ public class Splashactivity extends AppCompatActivity { public void run() { // on below line we are // creating a new intent - Intent i = new Intent(Splashactivity.this, LoginActivity.class); + SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE); + boolean loggedBefore = sharedPreferences.getBoolean("loggedBefore",false); + + System.out.println("Value of loggedBefore "+ loggedBefore); + + if(loggedBefore){ + Intent i = new Intent(Splashactivity.this, LoginActivity.class); + startActivity(i); + } + else { + + + Intent i = new Intent(Splashactivity.this, LoginActivity.class); // on below line we are + // starting a new activity. + startActivity(i); + + // on the below line we are finishing + // our current activity. + finish(); + } - // on below line we are - // starting a new activity. - startActivity(i); - // on the below line we are finishing - // our current activity. - finish(); } }, 2000); } diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Storage.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Storage.java index 65e3797..5f8cc90 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Storage.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/Storage.java @@ -88,8 +88,10 @@ public class Storage { } public void addToStorageLunaLocal(String login, String Descriptor) { + + System.out.println("making sure this metyhos " + login +" "+ Descriptor); if (!LunaLocalData.containsKey(login)){ - Log.i(TAG, "Pushed new person!: login"+login+"DESCR"+LunaLocalData.get(login)); + Log.i(TAG, "Pushed new person!: login "+login+" DESCR "+Descriptor); LunaLocalData.put(login,Descriptor); } else{ @@ -102,10 +104,10 @@ public class Storage { public String getDescriptorLocal(String Login){ if(LunaLocalData.containsKey(Login)){ - Log.i(TAG,"Returned descriptor is"+LunaLocalData.get(Login)); + Log.i(TAG,"Returned descriptor is "+LunaLocalData.get(Login)); return LunaLocalData.get(Login); } - Log.i(TAG,"NO SUCH LOGIN!!!"); + Log.i(TAG,"NO SUCH LOGIN!!!"+Login); return null; } @@ -258,9 +260,11 @@ public class Storage { public void updateOfflineData(){ SharedPreferences sharedpref = context.getSharedPreferences("Offline",Context.MODE_PRIVATE); + try{ if(sharedpref != null){ String jsonString = sharedpref.getString("My_map",(new JSONObject()).toString()); + Log.i(TAG,"Inside updateOfflineData "+jsonString); JSONObject jsonObject = new JSONObject(jsonString); Iterator keyStr = jsonObject.keys(); while(keyStr.hasNext()){ diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/JsonPlaceHolderApi.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/JsonPlaceHolderApi.java index 70b6fa1..471705f 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/JsonPlaceHolderApi.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/JsonPlaceHolderApi.java @@ -6,18 +6,22 @@ import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.FieldMap; import retrofit2.http.FormUrlEncoded; +import retrofit2.http.Headers; import retrofit2.http.POST; import ru.visionlab.femdemo.models.RegistrationNew; import ru.visionlab.femdemo.models.Users; public interface JsonPlaceHolderApi { - @FormUrlEncoded + // @FormUrlEncoded @POST("services/app/Employee/RegisterEmployee") - //Call createpost(@Body RegistrationNew registrationNew); - Call createpost(@FieldMap Map fields); + Call createpost(@Body RegistrationNew registrationNew); + //Call createpost(@FieldMap Map fields); - @FormUrlEncoded - @POST("posts") - Call login(@FieldMap Map fields); + //@FormUrlEncoded + @Headers("Content-Type:application/json") + @POST("TokenAuth/LogIn") + //Call login(@Body Map fields); + Call login(@Body Users users); + //Call login(@FieldMap Map fields); } diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/RegisterApiImplLocal.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/RegisterApiImplLocal.java index 634afb2..3f0067c 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/RegisterApiImplLocal.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/api/RegisterApiImplLocal.java @@ -1,10 +1,13 @@ package ru.visionlab.femdemo.api; import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Bitmap; import android.util.Base64; import android.util.Log; +import cn.pedant.SweetAlert.SweetAlertDialog; import ru.visionlab.femdemo.Core.PhotoProcessor; import ru.visionlab.femdemo.Storage; import ru.visionlab.femdemo.register.RegistrationModel; @@ -41,17 +44,36 @@ public class RegisterApiImplLocal implements RegisterApiInterface { @Override public void registerPerson() { - Log.i(TAG,"Login is"+registrationModel.login); - // photoProcessor.calcFaceDescriptorFromBestFrame(); - byte[] bestFrameDescriptorByteArray = photoProcessor.getFaceDescriptorByteArray(); + Log.i("Route", "registerPerson registerapiimplocal"); + //Log.i(TAG,"Login is"+registrationModel.login); - if (bestFrameDescriptorByteArray == null || bestFrameDescriptorByteArray.length == 0) { - onFail(new DescriptorNotExtractedException("FAILED to register: could not extract descriptor ")); + if(registrationModel == null){ + new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE) + .setTitleText("Face not recognised") + .setConfirmText("Back to login") + .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { + @Override + public void onClick(SweetAlertDialog sDialog) { + sDialog.dismissWithAnimation(); + + + } + }) + .setContentText("OK").show(); } else{ - String descriptorEncrypted = Base64.encodeToString(bestFrameDescriptorByteArray, Base64.DEFAULT); - onSuccess(descriptorEncrypted); + // photoProcessor.calcFaceDescriptorFromBestFrame(); + byte[] bestFrameDescriptorByteArray = photoProcessor.getFaceDescriptorByteArray(); + + if (bestFrameDescriptorByteArray == null || bestFrameDescriptorByteArray.length == 0) { + onFail(new DescriptorNotExtractedException("FAILED to register: could not extract descriptor ")); + } + else{ + String descriptorEncrypted = Base64.encodeToString(bestFrameDescriptorByteArray, Base64.DEFAULT); + onSuccess(descriptorEncrypted); + } } + } private void onFail(Throwable throwable) { @@ -59,9 +81,16 @@ public class RegisterApiImplLocal implements RegisterApiInterface { } private void onSuccess(String descriptor) { + Log.i("Route", "onSuccess"); Log.i(TAG,"Desctiptor has been saved : descr = "+descriptor); System.out.println("Value of login after registration " + registrationModel.login); + SharedPreferences sharedPreferences = context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString("login",registrationModel.login); + editor.putString("Descriptor",descriptor); + editor.commit(); Storage.getInstance().addToStorageLunaLocal(registrationModel.login, descriptor); + listener.onRegistrationSuccess(); } } diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/authentication/AuthenticationActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/authentication/AuthenticationActivity.java index d157def..abd8351 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/authentication/AuthenticationActivity.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/authentication/AuthenticationActivity.java @@ -37,6 +37,7 @@ import butterknife.ButterKnife; import butterknife.OnClick; import retrofit2.adapter.rxjava.HttpException; import ru.visionlab.femdemo.App; +import ru.visionlab.femdemo.CheckInActivity; import ru.visionlab.femdemo.Config; import ru.visionlab.femdemo.Core.PhotoProcessor; import ru.visionlab.femdemo.BuildConfig; @@ -397,10 +398,12 @@ public class AuthenticationActivity extends ToolbarActivity implements PinFragme } private void onFaceAuthSuccess() { + System.out.println("Success after face recognition"); if (preferences.getFingerAuth()) { onFingerClick(finger); } else { showSuccess(); + } } diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/base/PhotoFragment.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/base/PhotoFragment.java index 383f25f..b3aaf1e 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/base/PhotoFragment.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/base/PhotoFragment.java @@ -274,7 +274,7 @@ public class PhotoFragment extends BaseFragment implements Camera.PreviewCallbac @Override public void onError() { - System.out.println("On photo success2"); + System.out.println("On photo failure"); } }); diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/di/NetworkModule.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/di/NetworkModule.java index c9bee3a..44492d2 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/di/NetworkModule.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/di/NetworkModule.java @@ -76,6 +76,8 @@ public class NetworkModule { // Install the all-trusting trust manager final SSLContext sslContext; try { + + sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // Create an ssl socket factory with our all-trusting manager diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivity.java index f4c0e5c..87114a8 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivity.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivity.java @@ -2,7 +2,9 @@ package ru.visionlab.femdemo.login; import android.Manifest; import android.app.Activity; +import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.hardware.Camera; import android.os.Bundle; @@ -75,9 +77,11 @@ public class LoginActivity extends BaseActivity { LinearLayout register; String user = ""; Button login_new; - Button reg_new; + // Button reg_new; LinearLayoutCompat lay_licence_verify; + TextView reg_new; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -89,6 +93,12 @@ public class LoginActivity extends BaseActivity { lay_licence_verify = findViewById(R.id.lay_licence_verify); + SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE); + String login = sharedPreferences.getString("login",""); + String Descriptor = sharedPreferences.getString("Descriptor",""); + + System.out.println("Value of login and Descriptor " + login+" "+Descriptor ); + login_new = findViewById(R.id.login_new); login_new.setOnClickListener(new View.OnClickListener() { diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivityNew.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivityNew.java index 10f5bde..09c0ef5 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivityNew.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/login/LoginActivityNew.java @@ -1,16 +1,43 @@ package ru.visionlab.femdemo.login; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.location.Location; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.ImageView; import android.widget.Toast; +import com.android.volley.AuthFailureError; +import com.android.volley.NetworkResponse; +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.ServerError; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.HttpHeaderParser; +import com.android.volley.toolbox.JsonObjectRequest; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.tasks.OnSuccessListener; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; @@ -22,6 +49,7 @@ import retrofit2.converter.gson.GsonConverterFactory; import ru.visionlab.constant.Url; import ru.visionlab.femdemo.CheckInActivity; import ru.visionlab.femdemo.R; +import ru.visionlab.femdemo.Storage; import ru.visionlab.femdemo.api.CallApiService; import ru.visionlab.femdemo.api.JsonPlaceHolderApi; import ru.visionlab.femdemo.authentication.AuthenticationActivity; @@ -32,6 +60,9 @@ import ru.visionlab.femdemo.register.RegisterActivityNew; public class LoginActivityNew extends AppCompatActivity { + public static final String MyPREFERENCES = "MyPrefs" ; + public static final String ID = "id"; + Button btnSignin; ImageButton back; @@ -45,6 +76,13 @@ public class LoginActivityNew extends AppCompatActivity { String tenancyName =""; + private static final int LOCATION_PERMISSION_REQUEST_CODE = 1; + private FusedLocationProviderClient fusedLocationClient; + + ImageView faceImage; + + SharedPreferences sharedpreferences; + String empIdShared=""; @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,6 +91,22 @@ public class LoginActivityNew extends AppCompatActivity { edt_empId = findViewById(R.id.edt_empId); edt_pass = findViewById(R.id.edt_pass); + + sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE); + + SharedPreferences shared = getSharedPreferences("MyPrefs", MODE_PRIVATE); + String login = shared.getString("login", ""); + String Descriptor = shared.getString("Descriptor", ""); + + System.out.println("value of login and Descriptor in login new " + login + " " + Descriptor); + + if(Descriptor != null){ + Storage.getInstance().addToStorageLunaLocal(login,Descriptor); + } + + if(login == null || login.equals("")){ + Toast.makeText(LoginActivityNew.this,"Please register before logging in ",Toast.LENGTH_SHORT).show(); + } createRetrofit(); empId = edt_empId.getText().toString().trim(); @@ -63,20 +117,56 @@ public class LoginActivityNew extends AppCompatActivity { btnSignin = findViewById(R.id.btnSignin); - btnSignin.setOnClickListener(new View.OnClickListener() { + if(!login.equals("")){ + btnSignin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + /*if (ContextCompat.checkSelfPermission(LoginActivityNew.this, android.Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) { + // Permission granted, so request location updates + requestLocationUpdates(); + } else { + // Permission not granted, request it + ActivityCompat.requestPermissions(LoginActivityNew.this, + new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, + LOCATION_PERMISSION_REQUEST_CODE); + }*/ + isAllFieldsChecked = CheckAllFields(); if(isAllFieldsChecked) { - // login(); - Intent intent = new Intent(LoginActivityNew.this, RegisterActivity.class); + // login(); + System.out.println("After login activity new "); + /*Intent intent = new Intent(LoginActivityNew.this, RegisterActivity.class); intent.putExtra("FromLoginPage",true); - startActivity(intent); + startActivity(intent);*/ + //login(); + //loginVolley(); + loginVolleyNil(); + //loginRetro(); } } }); + } + else{ + Toast.makeText(LoginActivityNew.this,"Please register before logging in ",Toast.LENGTH_SHORT).show(); + } + + + faceImage = findViewById(R.id.faceImage); + + if(!login.equals("")){ + faceImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(LoginActivityNew.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",true); + startActivity(intent); + } + }); + } + back = findViewById(R.id.back); back.setOnClickListener(new View.OnClickListener() { @@ -99,6 +189,89 @@ public class LoginActivityNew extends AppCompatActivity { jsonPlaceHolderApi=retrofit.create(JsonPlaceHolderApi.class); } + private void requestLocationUpdates() { + if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return; + } + fusedLocationClient = new FusedLocationProviderClient(getApplicationContext()); + fusedLocationClient.getLastLocation() + .addOnSuccessListener(this, new OnSuccessListener() { + @Override + public void onSuccess(Location location) { + if (location != null) { + double latitude = location.getLatitude(); + double longitude = location.getLongitude(); + + // Do something with the latitude and longitude + String message = "Latitude: " + latitude + "\nLongitude: " + longitude; + System.out.println("My current location: "+ message); + Toast.makeText(LoginActivityNew.this, message, Toast.LENGTH_SHORT).show(); + Location target = new Location(""); + target.setLatitude(latitude); + target.setLongitude(longitude); + + Location current = new Location(""); + current.setLatitude(20.5109958); + current.setLongitude(88.4009709); + + float distance = current.distanceTo(target); + System.out.println("Distance: "+distance); + if(distance<500){ + showFailedDialog(); + } + else{ + showSuccessDialog(); + + // Toast.makeText(CheckInActivity.this, "Attendance ready to be captured", Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(LoginActivityNew.this, "Location not available", Toast.LENGTH_SHORT).show(); + } + } + }); + + + } + + private void showSuccessDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Success"); + builder.setMessage("Attendance ready to be captured."); + builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(LoginActivityNew.this, RegisterActivity.class); + startActivity(intent); + // dialog.dismiss(); // Close the dialog. + } + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + } + private void showFailedDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Failed"); + builder.setMessage("You are out of range!Please get back to location"); + builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Perform any necessary action when the user clicks the "OK" button. + dialog.dismiss(); // Close the dialog. + } + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + } + private boolean CheckAllFields() { if (edt_empId.length() == 0) { @@ -118,11 +291,26 @@ public class LoginActivityNew extends AppCompatActivity { Map fields=new HashMap<>(); fields.put("employeeId",edt_empId.getText().toString()); fields.put("password",edt_pass.getText().toString()); - fields.put("tenancyName","facebio"); + fields.put("tenancyName","Testing"); /*Users users = new Users(empId,pass,tenancyName);*/ - CallApiService.getClient().login(fields); - Call call=jsonPlaceHolderApi.login(fields); + /*CallApiService.getClient().login(fields); + Call call=jsonPlaceHolderApi.login(fields);*/ + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl("http://huaiglobal.com/api/") + // as we are sending data in json format so + // we have to add Gson converter factory + .addConverterFactory(GsonConverterFactory.create()) + // at last we are building our retrofit builder. + .build(); + // below line is to create an instance for our retrofit api class. + jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class); + + Users users = new Users(edt_empId.getText().toString(),edt_pass.getText().toString(),"Testing"); + System.out.println("Login credentials: " + edt_empId.getText().toString() + " "+ edt_pass.getText().toString() + " "+"Testing"); + Call call = jsonPlaceHolderApi.login(users); + //Call call = jsonPlaceHolderApi.login(fields); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { @@ -137,6 +325,56 @@ public class LoginActivityNew extends AppCompatActivity { } else{ Toast.makeText(LoginActivityNew.this, "Error "+String.valueOf(response.code()), Toast.LENGTH_SHORT).show(); + System.out.println("Error: " + response.message()); + } + + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(LoginActivityNew.this, ""+t.getMessage(), Toast.LENGTH_SHORT).show(); + Log.e("error=",t.getMessage().toString()); + } + }); + } + public void loginRetro(){ + Map fields=new HashMap<>(); + fields.put("username","demouser1"); + fields.put("password","123"); + fields.put("imei","string"); + + /*Users users = new Users(empId,pass,tenancyName);*/ + /*CallApiService.getClient().login(fields); + Call call=jsonPlaceHolderApi.login(fields);*/ + + Retrofit retrofit = new Retrofit.Builder() + .baseUrl("http://43.242.212.92:7001/api/lgt/Login") + // as we are sending data in json format so + // we have to add Gson converter factory + .addConverterFactory(GsonConverterFactory.create()) + // at last we are building our retrofit builder. + .build(); + // below line is to create an instance for our retrofit api class. + jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class); + + Users users = new Users("demouser1","123","string"); + System.out.println("Login credentials: " + edt_empId.getText().toString() + " "+ edt_pass.getText().toString() + " "+"Testing"); + Call call = jsonPlaceHolderApi.login(users); + //Call call = jsonPlaceHolderApi.login(fields); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.isSuccessful()) + { + response.code(); + Log.e("login response code=", String.valueOf(response.code())); + Toast.makeText(LoginActivityNew.this, "Logging in ", Toast.LENGTH_SHORT).show(); + + + } + else{ + Toast.makeText(LoginActivityNew.this, "Error "+String.valueOf(response.code()), Toast.LENGTH_SHORT).show(); + System.out.println("Error: " + response.message()); } } @@ -148,4 +386,149 @@ public class LoginActivityNew extends AppCompatActivity { } }); } + public void loginVolley(){ + String url = "http://huaiglobal.com/api/TokenAuth/LogIn"; // Replace with your API endpoint URL + + RequestQueue queue = Volley.newRequestQueue(LoginActivityNew.this); + StringRequest request = new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + + // on below line we are displaying a success toast message. + Toast.makeText(LoginActivityNew.this, "Data added to API", Toast.LENGTH_SHORT).show(); + + } + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + // method to handle errors. + + + NetworkResponse response = error.networkResponse; + if (error instanceof ServerError && response != null) { + try { + String res = new String(response.data, + HttpHeaderParser.parseCharset(response.headers, "utf-8")); + // Now you can use any deserializer to make sense of data + JSONObject obj = new JSONObject(res); + System.out.println("Error message: "+ obj); + } catch (UnsupportedEncodingException e1) { + // Couldn't properly decode data to string + e1.printStackTrace(); + } catch (JSONException e2) { + // returned data is not JSONObject? + e2.printStackTrace(); + } + } + + Toast.makeText(LoginActivityNew.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + } + }) { + @Override + protected Map getParams() { + // below line we are creating a map for + // storing our values in key and value pair. + Map params = new HashMap(); + + // on below line we are passing our key + // and value pair to our parameters. + params.put("userNameOrEmailAddress", edt_empId.getText().toString()); + params.put("password", edt_pass.getText().toString()); + params.put("tenancyName", "Testing"); + + + + + + // at last we are + // returning our params. + return params; + } + @Override + public Map getHeaders() throws AuthFailureError { + HashMap headers = new HashMap(); + headers.put("Content-Type", "application/json; charset=utf-8"); + return headers; + } + /*@Override + public Map getHeaders() throws AuthFailureError { + Map params = new HashMap(); + params.put("Authorization", "bearer "+"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjUiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiOiJkYXNzYW5kaXBAc2VudGllbnRnZWVrcy5jb20iLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6IjdFR1lVNFRBU1BUS05BREIzVEtHM0ZQNzdFQ1AzVjNBIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW4iLCJodHRwOi8vd3d3LmFzcG5ldGJvaWxlcnBsYXRlLmNvbS9pZGVudGl0eS9jbGFpbXMvdGVuYW50SWQiOiI0Iiwic3ViIjoiNSIsImp0aSI6IjYwOTFhMTgwLTkzMWItNGYwMS05ZWVjLTM3OTNkYmExMjkxYiIsImlhdCI6MTY5Mzg5OTk1NCwidG9rZW5fdmFsaWRpdHlfa2V5IjoiMzM3ZjAzMmEtN2I3NS00MTkzLWFhY2QtYjA3OWEyYjYxMjI0IiwidXNlcl9pZGVudGlmaWVyIjoiNUA0IiwidG9rZW5fdHlwZSI6IjAiLCJyZWZyZXNoX3Rva2VuX3ZhbGlkaXR5X2tleSI6Ijg1MTlmMjU3LWE3NmEtNDViOS05MDQ0LTU4ZTk0ZThhZTEwZSIsIm5iZiI6MTY5Mzg5OTk1NCwiZXhwIjoxNjkzOTg2MzU0LCJpc3MiOiJtdWx0aSIsImF1ZCI6Im11bHRpIn0.ImuWLPg85b7fN1nWzr1Es1L9j6xm7DrK4L_UxApzkqM"); + return params; + }*/ + }; + + queue.add(request); + } + + public void loginVolleyNil(){ + final ProgressDialog loading = ProgressDialog.show(LoginActivityNew.this, "Authenticating", "Please wait while logging", false, false); + String url= "http://43.242.212.92:7001/api/lgt/Login"; + StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + Log.d("data-=>",response); + String _employeeid = response.toString(); + System.out.println("Value of _employeeid " +_employeeid ); + /*try { + JSONObject jsonObject=new JSONObject(response); + empIdShared = jsonObject.getString("_employeeid"); + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(ID, empIdShared); + editor.commit(); + } catch (JSONException e) { + throw new RuntimeException(e); + }*/ + loading.dismiss(); + Toast.makeText(LoginActivityNew.this, "Data added to API", Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(LoginActivityNew.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",true); + startActivity(intent); + + } + /*JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new com.android.volley.Response.Listener() { + @Override + public void onResponse(JSONObject response) { + // inside the on response method. + // we are hiding our progress bar. + + try { + + String _employeeid = response.getString("_employeeid"); + String _employeename = response.getString("_employeename"); + + + + } catch (JSONException e) { + // if we do not extract data from json object properly. + // below line of code is use to handle json exception + e.printStackTrace(); + } + }*/ + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { +// Log.d("error-=>",error.getMessage()); + Toast.makeText(LoginActivityNew.this, "Fail to get response = " + error.getMessage(), Toast.LENGTH_SHORT).show(); + System.out.println("Error message: "+ error.getMessage()); + + + } + }) + { + @Override + protected Map getParams() throws AuthFailureError { + HashMapmap=new HashMap<>(); + map.put("username","demouser1"); + map.put("password","123"); + map.put("imei","string"); + + return map; + } + }; + Volley.newRequestQueue(LoginActivityNew.this).add(stringRequest); + } } \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivity.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivity.java index 206d149..40a351d 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivity.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivity.java @@ -2,7 +2,9 @@ package ru.visionlab.femdemo.register; import android.Manifest; import android.annotation.SuppressLint; +import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Bitmap; import android.media.MediaScannerConnection; import android.net.Uri; @@ -37,7 +39,9 @@ import java.util.List; import javax.inject.Inject; import butterknife.BindView; +import cn.pedant.SweetAlert.SweetAlertDialog; import ru.PreferenceManager.PreferenceManager; +import ru.visionlab.femdemo.CheckInActivity; import ru.visionlab.femdemo.Config; import ru.visionlab.femdemo.Core.PhotoProcessor; import ru.visionlab.femdemo.App; @@ -103,7 +107,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen Bitmap photo2=null; Button save,retry; String encodedImage=""; - boolean fromLoginPage; + boolean fromLoginPage,FromNewCheck,checkinButton; private PhotoFragment fragment; String login; private long verifEndTime; @@ -113,6 +117,8 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen private boolean goingSomewhere = false; + String valueFromApiCheckIn; + @SuppressLint("MissingInflatedId") @@ -124,15 +130,25 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen //ButterKnife.bind(this); setToolbar(); + + SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE); + String login = sharedPreferences.getString("login",""); + String Descriptor = sharedPreferences.getString("Descriptor",""); + + System.out.println("Value of login and Descriptor " + preferences.getUsername()+" "); Intent intent = getIntent(); fromLoginPage = intent.getBooleanExtra("FromLoginPage",true); - System.out.println("Value of FromLoginPage "+fromLoginPage); + checkinButton = intent.getBooleanExtra("checkinButton",false); + valueFromApiCheckIn = intent.getStringExtra("valueFromApiCheckIn"); + System.out.println("Value of FromLoginPage "+fromLoginPage + checkinButton + " "+ valueFromApiCheckIn); if(fromLoginPage){ showPhotoScreen(); } else { showRegisterScreen(); } + FromNewCheck = intent.getBooleanExtra("FromLoginPage",false); + System.out.println("Value of FromNewCheck "+FromNewCheck); /*back_img.setOnClickListener(new View.OnClickListener() { @@ -249,6 +265,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen } private void showRegisterScreen() { + Log.i("Route", "showRegisterScreen"); final RegisterFragment fragment = RegisterFragment.newInstance(); fragment.setListener(this); getSupportFragmentManager() @@ -280,9 +297,12 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen @Override public void onSignUpClick(RegistrationModel registrationModel) { + Log.i("Route", "onSignUpClick"); if((!BuildConfig.IS_OFFLINE_VERSION) && preferences.getLuna2()) { thread = new Thread(() -> { + Storage.getInstance().updateDatabase(preferences.getLuna2Server(), preferences.getEncodedUserData(), api, preferences.getServerChanged()); + Log.i("Route", "updateDatabase"); }); thread.start(); } @@ -292,6 +312,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen } private void showPhotoScreen() { + Log.i("Route", "showPhotoScreen"); fragment = PhotoFragment.newInstance(); fragment.setPhotoProcessor(photoProcessor); fragment.setListener(this); @@ -308,6 +329,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen } private void showPhotoReadyScreen(Bitmap bitmap) { + Log.i("Route", "showPhotoReadyScreen"); final SavePhotoFragment fragment = SavePhotoFragment.newInstance(); fragment.setPhoto(bitmap); fragment.setListener(this); @@ -321,6 +343,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen @Override public void onBestFrameReady(Bitmap bitmap) { + Log.i("Route", "onBestFrameReady"); this.bitmap = bitmap; if(fromLoginPage){ verifyPhoto(bitmap); @@ -329,6 +352,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen } private void verifyPhoto(Bitmap bitmap){ + Log.i("Route", "verifyPhoto fromLoginPage"); fragment.showWaitState(); login=preferences.getUsername(); System.out.println("Value of login while verification " + login); @@ -340,6 +364,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen } VerifyApiInterface verifyApi; if (BuildConfig.IS_OFFLINE_VERSION) { + Log.i("Route", "VerifyApiInterface"); verifyApi = new VerifyApiImplLunaLocal(this, photoProcessor, login, this); } else { //if (preferences.getLuna2()) { Log.i("LUNA2 ", preferences.getLuna2Server()); @@ -399,6 +424,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen } private void registerPerson() { + Log.i("Route", "registerPerson"); RegisterApiInterface registerApi; try { if (thread != null) { @@ -410,6 +436,7 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen if (BuildConfig.IS_OFFLINE_VERSION) { registerApi = new RegisterApiImplLocal(this, registrationModel, photoProcessor, this, bitmap); + Log.i("Route", "registerPerson registerApi"); } else { registerApi = new RegisterApiImplLuna2(this, preferences.getLuna2Server(), registrationModel, api, locationHelper, this, bitmap, preferences.getEncodedUserData()); } @@ -555,18 +582,66 @@ public class RegisterActivity extends ToolbarActivity implements RegisterFragmen }*/ } private void showSuccess() { - final Intent intent = new Intent(this, AuthSuccessActivity.class); + + final Intent intent = new Intent(RegisterActivity.this, CheckInActivity.class); intent.putExtra(AuthSuccessActivity.LOGIN, login); + System.out.println("login value "+ login); + + if (BuildConfig.IS_OFFLINE_VERSION) { - intent.putExtra(AuthSuccessActivity.TIME, (int)(((double) (verifEndTime - verifStartTime)) / 1e6)); + intent.putExtra(AuthSuccessActivity.TIME, (int) (((double) (verifEndTime - verifStartTime)) / 1e6)); + intent.putExtra("FromRegister", true); + intent.putExtra("checkinButtonFromRegister", true); + intent.putExtra("valueFromApiCheckIn", valueFromApiCheckIn); + intent.putExtra("UserName", login); } startActivity(intent); + finish(); + + /*if (checkinButton) { + final Intent intent = new Intent(RegisterActivity.this, CheckInActivity.class); + intent.putExtra(AuthSuccessActivity.LOGIN, login); + + + if (BuildConfig.IS_OFFLINE_VERSION) { + intent.putExtra(AuthSuccessActivity.TIME, (int) (((double) (verifEndTime - verifStartTime)) / 1e6)); + intent.putExtra("FromRegister", true); + intent.putExtra("checkinButtonFromRegister", true); + intent.putExtra("valueFromApiCheckIn", valueFromApiCheckIn); + } + + startActivity(intent); + + finish(); + } + else{ + final Intent intent = new Intent(RegisterActivity.this, CheckInActivity.class); + intent.putExtra(AuthSuccessActivity.LOGIN, login); + + + if (BuildConfig.IS_OFFLINE_VERSION) { + intent.putExtra(AuthSuccessActivity.TIME, (int) (((double) (verifEndTime - verifStartTime)) / 1e6)); + intent.putExtra("FromRegister", false); + intent.putExtra("checkinButtonFromRegister", false); + intent.putExtra("valueFromApiCheckIn", valueFromApiCheckIn); + } + + startActivity(intent); + + finish(); + } +*/ + + + + } private void onFaceAuthFail(AuthenticationActivity.AuthFailReason reason) { + System.out.println("Root fail"); if (faceFailCount < 4) { final FaceNotRecognizedFragment fragment = FaceNotRecognizedFragment.newInstance(); fragment.setListener(this); diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivityNew.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivityNew.java index 49c2ee0..3d5a905 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivityNew.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterActivityNew.java @@ -9,8 +9,20 @@ import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.TextView; import android.widget.Toast; +import com.android.volley.AuthFailureError; +import com.android.volley.DefaultRetryPolicy; +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.BasicNetwork; +import com.android.volley.toolbox.DiskBasedCache; +import com.android.volley.toolbox.HurlStack; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + import org.json.JSONException; import org.json.JSONObject; @@ -42,7 +54,10 @@ public class RegisterActivityNew extends AppCompatActivity { JsonPlaceHolderApi jsonPlaceHolderApi; - Button verifynproceed; + Button verifynproceed,face; + TextView skip; + + @Override protected void onCreate(Bundle savedInstanceState) { @@ -57,19 +72,41 @@ public class RegisterActivityNew extends AppCompatActivity { verifynproceed = findViewById(R.id.verifynproceed); + verifynproceed.setEnabled(true); verifynproceed.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - isAllFieldsChecked = CheckAllFields(); + + Intent intent = new Intent(RegisterActivityNew.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",false); + startActivity(intent); + /*isAllFieldsChecked = CheckAllFields(); if(isAllFieldsChecked) { + Intent intent = new Intent(RegisterActivityNew.this, RegisterActivity.class); intent.putExtra("FromLoginPage",false); startActivity(intent); //saveInfo(); - } + //savaData(); + }*/ + } + }); + + + + skip = findViewById(R.id.skip); + skip.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + Intent intent = new Intent(RegisterActivityNew.this, RegisterActivity.class); + intent.putExtra("FromLoginPage",false); + startActivity(intent); + } }); + back_img = findViewById(R.id.back_img); back_img.setOnClickListener(new View.OnClickListener() { @Override @@ -80,12 +117,12 @@ public class RegisterActivityNew extends AppCompatActivity { }); } public void createRetrofit(){ - Retrofit retrofit=new Retrofit.Builder() + /*Retrofit retrofit=new Retrofit.Builder() .baseUrl("http://huaiglobal.com/api/") .addConverterFactory(GsonConverterFactory.create()) .build(); - jsonPlaceHolderApi=retrofit.create(JsonPlaceHolderApi.class); + jsonPlaceHolderApi=retrofit.create(JsonPlaceHolderApi.class);*/ } @@ -114,25 +151,34 @@ public class RegisterActivityNew extends AppCompatActivity { fields.put("employeeId",edt_emp.getText().toString()); fields.put("otp",edt_otp.getText().toString()); - /* RegistrationNew registrationNew = new RegistrationNew(edt_comp.getText().toString(),edt_emp.getText().toString(),edt_otp.getText().toString()); - System.out.println("Value of registrationNew " );*/ - CallApiService.getClient().createpost(fields); - Call call=jsonPlaceHolderApi.createpost(fields); + + Retrofit retrofit=new Retrofit.Builder() + .baseUrl("http://huaiglobal.com/api/services/app/Account/RegisterLunaEmployee") + .addConverterFactory(GsonConverterFactory.create()) + .build(); + + jsonPlaceHolderApi=retrofit.create(JsonPlaceHolderApi.class); + + RegistrationNew registrationNew = new RegistrationNew(edt_comp.getText().toString(),edt_emp.getText().toString(),edt_otp.getText().toString()); + System.out.println("Value of registrationNew " ); + //CallApiService.getClient().createpost(fields); + Call call=jsonPlaceHolderApi.createpost(registrationNew); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { if(response.isSuccessful()) { Log.e("register code=", String.valueOf(response.code())); - Toast.makeText(RegisterActivityNew.this, "User Added succesfully", Toast.LENGTH_SHORT).show(); - Intent intent = new Intent(RegisterActivityNew.this, RegisterFragment.class); - startActivity(intent); + Toast.makeText(RegisterActivityNew.this, "User Added successfully", Toast.LENGTH_SHORT).show(); + /*Intent intent = new Intent(RegisterActivityNew.this, RegisterFragment.class); + startActivity(intent);*/ } else{ Log.e("else part register code=", String.valueOf(response.code())); - Intent intent = new Intent(RegisterActivityNew.this, RegisterFragment.class); - startActivity(intent); + /*Intent intent = new Intent(getApplicationContext(), RegisterFragment.class); + startActivity(intent);*/ + System.out.println("Response code: "+response.code()); Toast.makeText(RegisterActivityNew.this, "Current user did not login to the application!", Toast.LENGTH_SHORT).show(); @@ -146,4 +192,63 @@ public class RegisterActivityNew extends AppCompatActivity { } }); } + public void savaData(){ + System.out.println("Inside save info"); + String url = "http://huaiglobal.com/api/services/app/Account/RegisterLunaEmployee"; // Replace with your API endpoint URL + + RequestQueue queue = Volley.newRequestQueue(RegisterActivityNew.this); + StringRequest request = new StringRequest(Request.Method.POST, url, new com.android.volley.Response.Listener() { + @Override + public void onResponse(String response) { + + // on below line we are displaying a success toast message. + Toast.makeText(RegisterActivityNew.this, "Data added to API", Toast.LENGTH_SHORT).show(); + + } + }, new com.android.volley.Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + // method to handle errors. + Toast.makeText(RegisterActivityNew.this, "Fail to get response = " + error, Toast.LENGTH_SHORT).show(); + System.out.println("Error: " + error); + /*Intent intent = new Intent(RegisterActivityNew.this, RegisterFragment.class); + startActivity(intent);*/ + } + }) { + @Override + protected Map getParams() { + // below line we are creating a map for + // storing our values in key and value pair. + Map params = new HashMap(); + + // on below line we are passing our key + // and value pair to our parameters. + params.put("companyCode", edt_comp.getText().toString()); + params.put("employeeCode", edt_emp.getText().toString()); + params.put("otp", edt_otp.getText().toString()); + System.out.println("Data input: "+ edt_comp.getText().toString() + " " +edt_emp.getText().toString() +" "+ edt_otp.getText().toString()); + + + // at last we are + // returning our params. + return params; + } + /*@Override + public Map getHeaders() throws AuthFailureError { + Map params = new HashMap(); + params.put("Authorization", "bearer "+"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjUiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiOiJkYXNzYW5kaXBAc2VudGllbnRnZWVrcy5jb20iLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6IjdFR1lVNFRBU1BUS05BREIzVEtHM0ZQNzdFQ1AzVjNBIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiQWRtaW4iLCJodHRwOi8vd3d3LmFzcG5ldGJvaWxlcnBsYXRlLmNvbS9pZGVudGl0eS9jbGFpbXMvdGVuYW50SWQiOiI0Iiwic3ViIjoiNSIsImp0aSI6IjYwOTFhMTgwLTkzMWItNGYwMS05ZWVjLTM3OTNkYmExMjkxYiIsImlhdCI6MTY5Mzg5OTk1NCwidG9rZW5fdmFsaWRpdHlfa2V5IjoiMzM3ZjAzMmEtN2I3NS00MTkzLWFhY2QtYjA3OWEyYjYxMjI0IiwidXNlcl9pZGVudGlmaWVyIjoiNUA0IiwidG9rZW5fdHlwZSI6IjAiLCJyZWZyZXNoX3Rva2VuX3ZhbGlkaXR5X2tleSI6Ijg1MTlmMjU3LWE3NmEtNDViOS05MDQ0LTU4ZTk0ZThhZTEwZSIsIm5iZiI6MTY5Mzg5OTk1NCwiZXhwIjoxNjkzOTg2MzU0LCJpc3MiOiJtdWx0aSIsImF1ZCI6Im11bHRpIn0.ImuWLPg85b7fN1nWzr1Es1L9j6xm7DrK4L_UxApzkqM"); + return params; + }*/ + + @Override + public Map getHeaders() throws AuthFailureError { + HashMap headers = new HashMap(); + headers.put("Content-Type", "application/json; charset=utf-8"); + return headers; + } + }; + + queue.add(request); + + } } \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterFragment.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterFragment.java index 66adeaf..180a31c 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterFragment.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/RegisterFragment.java @@ -8,6 +8,7 @@ import android.text.Editable; import android.text.InputType; import android.text.TextUtils; import android.text.method.PasswordTransformationMethod; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -57,6 +58,11 @@ public class RegisterFragment extends BaseFragment { TextInputLayout phoneWrapper; Listener listener; + @BindView(R.id.pass) + EditText pass; + + String password=""; + public RegisterFragment() { } @@ -115,6 +121,14 @@ public class RegisterFragment extends BaseFragment { @OnClick(R.id.signUp) public void onClick() { + Log.i("Route", "signUp"); + password = pass.getText().toString(); + if(password.equals("")){ + signUp.setEnabled(false); + } + + + Utils.hideKeyboardRoutine(getContext(), getView()); if (listener != null && validateFields(true, true)) { RegistrationModel registrationModel = new RegistrationModel(); @@ -132,6 +146,7 @@ public class RegisterFragment extends BaseFragment { result = validateEmail(changeFocus, showError); result = validateLogin(showError) && result; + signUp.setEnabled(result); return result; diff --git a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/SavePhotoFragment.java b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/SavePhotoFragment.java index 71ff66f..a55b434 100644 --- a/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/SavePhotoFragment.java +++ b/examples/example_bestshot/example/app/src/main/java/ru/visionlab/femdemo/register/SavePhotoFragment.java @@ -6,6 +6,8 @@ import android.graphics.PorterDuff; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; + +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -81,6 +83,7 @@ public class SavePhotoFragment extends BaseFragment { @OnClick({R.id.save}) public void onClick() { + Log.i("Route", "save onClick"); save.setEnabled(false); progressBar.setVisibility(View.VISIBLE); if (listener != null) { diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/approval.png b/examples/example_bestshot/example/app/src/main/res/drawable/approval.png new file mode 100644 index 0000000000000000000000000000000000000000..81f9b19e574e3f6bc762162ba17a770b9628eb00 GIT binary patch literal 20329 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 M5Bjj~@8_id4Z3f@{Qv*} literal 0 HcmV?d00001 diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/attendance_icon.png b/examples/example_bestshot/example/app/src/main/res/drawable/attendance_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..529c357069ca5d66e5dc08dac2563b9373ca0433 GIT binary patch literal 25642 zcmeEuWl)w|xagvhMri~@RFFnQIu#29q&pSq?);EY2@63Qq&uZM4O$wcq&q)4?t0z( zoVkC_xifd>&fFj8o7sc&uJx|xSx?uy-zX_OASR$A000m_dU#J60PI5KKYU#HWQDn; z8~&knlGSulu{CvaHF9_kq@URuKfm(G+UUh|<>yAv-0gon7X!egl$zB?#;=FpEU#rB&k&UT@|8&* zzGve1Qv3!{WC&M&WB-J<&xz|LwFa%EJcK}fZDiQ$>~9Sa$?@y-`M zDErX;^ID##(X^fk`#yDvwvQp&|MUAF3j7ZR{)YnppHhHgljJ(E z$hV&`_E=NFL@D3)3|Vqcu8r(I#8(o<v1GKSTyl1 z?OH#k#ni>?;J(!ZPiw{Tjgvc{uz+EzX&;Zvoa}q&)LN2#A0j1T3@ToNtst`(%Rw3? zKQVxkiXjy2UH0FD(mamv9#eZwq`>i+?~0qhCCa3 zIR4gaT(dz*HyOKutm89!el|F#K<;y`>)qp-#mnn3dLuoe-uGr+&B?Dq-;l*Ni?X4$wE<;&LnTa3!@Rxyi6|o3 z8or4_^x)U^BhvJo{Ca8UjE1z&dinUkS%z&en8;1%?`f-=C$V8r6-EkPakM;?&96M{a$0+^QO1A)lG6Wp zk5X#*=9dKCewn-QR;+L^@0_r9|0A9%HJc0yhoW?Tll^5*XW~Js4F^E+U1ZoPGPazi zd!gBeAKaNW7KZa)7Vaua-?SJ<3#Lxq0#v{-xAk}KYftFQ$rHO9K0Q#xSH5Ad5gw>6az$&Y%%hhnzZ_femy~nlbXgWfA z4S+tbd1KiJKGMC1k_8?OflwUFOR8&QDya$Ky@WKJX1~ezzue2P5u|F+fs2H1@^fSy z3j(0r$MKjZQ^mcZ+_<}+bJ^!=MKdo1=hGaSg6ILimmXDt<0&^e#-Qd;k=;2uc!?I8WwSNF@S7n#CtFHHWvLhV_hha>&gGAM8cC?lAEqY(-~fl|pjl>;Y&^>t1qks)9eBPvlL1s|jQd8AQ)j2^ zyuL(Y)ubIx`tbF~Ahl!7pYNDmyY9hsT1H($m&DHa?hJLpnin?6Mu#bS>yqF2p7#0F zq3X}_etl8AEyb%H-Q(WszMXfHpFG{Ynw@)D@cLF59s?Dgx>)o~9HHdb1*xie7FYGX zz}mAu--q1{?n$+EzYh7%I+dXbT$RIpu2_p-m_P30nzn&%5|l)5{kBzLv?&-9SLUs? zV#Y2mBW-hCx?@#aTFe8rpC=d_*UdjoQbZ6t?BEVi!1*OgT%m`P(UCU%2uJ7M6C zOq4Oye$OshdI>j6))sc10JR5_^&H;NkPtva#ZEP@Ghn2J~QhJ&aNY&nZjdu9K zDn-56VBvAk(Bnd(VUa7L>&j z>eX*&lmVJ0>YiLToBM0=tSAlx7T$VY*Q-8V|D}-jmOIy|&KKv#J3v_DUYY3@t~^K| zv3W8>N`3kXx&*0<`WOv`oO@J#X(RfcD)YKo!!ifIRNkdoN;tf@X&~=(lGsu0l=6xs zJ)A3mx3*Y;sV2E)J;#m3>5ea(8MeC4sHFis0^|-TdwL5w*YicqJ(xW9FgNI^uUOsw zEl1BN5~Todrq7bdL^j#VF}2q}eg_{kY_6IYG`nw%|0FETuQ(EUhi&&1lXEKhrj#)c^W*@R({W`$eCQ;{53E<4SeUc$qgFtM%Yl?A;j*(Do7#g3O%z z%Ry?Q;oLb!1CA24v}Ozn@^(jiA?D8lntF-t6^_{tM6^F zIv`rcc;^!i$YjBw0!nz~>6~AO-gzO#d_iBgsVqWW>$fqj)5~xu3Aw5*{dZAF2uUO3LNjS#l%a`zf zPVbD(H}mzl3S64<`(CIo(|C05 ztLM~`q}wDtKM(~-^aGS4OqX4B!e%KN7o$cid~OH~)@Gc}IIl6)!#~l#d?ydYx%ZB( z>g{KEPJY9qQinXI)dO_Dy-i#S)GG*GF0xErr)t&=S#$Qib-(~J-$Tl=>F_&?=Eta= z2K8PqwQjHK`qsHoooqMMpNX!Yu(q{Q`Murd8$!0SI})K#K`AM5*sPJgJ{q%;m)1{Q z94Xd{fhtBgRD4@Swoy&8aMXUL?Q3QEbvxzOM1jG|c%4)3Jp9r>Gs>Q7y9aIBk6&_v zq-O}nhv~BDbvr+!>F-IEo~DPzTlhBIT;9_W1Ee!6ogyqPOHHt&jK96r!9fY9AAn#MHvSd)JyL zFi_0U*#S$w&sB|Tj#2eyPTFe~S!33%o3%ybg}-?%AJ{U$@Gkdx1RlV>-hc^kOL>Ux zs|_>c7R#P2O^8k;(yf@PmR~*PwLDB%ztep8T>{-6*}<^7NMhBvW(Ye8Ac6r9pn$Ol zVeLChs*=3D33O~#-u>0z)xlm5YuXrP9`B?i0Wjgc7rgAh^CcTWRC@BXqXp!V!$0VpdG$ezn# zdmh(_Z&n0{Z~X}nTVDH}pKJ21JN1}JOd@wJun6tsx$I&RuVfAk1(59nEmzhBT=itB zyIBlsguRd3%P$nPDT$eG4Kr95%-b>6S5E9$lrLj~9B48C^(9uK`wIiBN%c}rTf5~1 zE(&!fxe;W~S{+vxwG&K0!z{u%>WfBAG1Vr1Smn_eP6|J(La~X*z0c!)gypVP>w|2#HDk*7pe7JX`C_bXL7=px@Vw3lx6t_2 zhS2xKahIY;iyvjEF$G20t+w!99HPF&vXY^4VaU+{M9={924oR%R+7 z&jm>#pK*WLrjtFj{y8sh+1+W@@v3NrA^iX?te6dP+ju2>pn{m1KJzbT_=P)VPvY|o z%ZQ5Ai{kBw@1C1v9`{~r!9-=jkP@}TpI9}9S0d|HYB%{rf%chMatIG*FGe{<*L4II zB?9Yn#q^}X>?JA*Zxz;>mqsC*>@v9+iZ>~YF&Zc!lN+2y^k#!373hAuuiQ{exqYfa zkkW1oWH>?8MW|j;+@d8sHP+$bxLNW}hqC39;A)G52s4luLe73i<1_xflDEudS^4LVKfbhY#@tVMhu>h@Y=LxS>q11l8gfT0*7Y1=Iw zi8DWbGu_a%a`%R046*SZkFD|_$3XG1!2A5@H7iKT@?6%Q&d*7kd7=8g=putAR-Amr zd#CG|4Z{d)pDnuT2}Ha!FFtJxi*H=VxvgA&i4f4Rz?;$7+Ve};4XGJeHIMpss}DTm zY;`Q363fN+ie<+GGk2l<%~-POY4kR3@BUent=3FZhv9vryXLVPF=&HfJZMvN(iZms7+1=watc;L1XIc z1;@sP-P){bVrr0yIKa?%K5hbni#%kGFB9~Kd!uPp?W!q50~edvH-En!`ji&{cySSW zNeoixuhp&yicYIF8V&KPU#(%Uh~TZFMUY0{fK=Hc)4Pflr~&ERN9b$+V$^epO6?gt zQDKB#K{kd|Eu?GGS@PXyuDy!E3ZI7A57u}lO&^M?yg087Ec=T2ECRT3c~u#ku3K~qf+SbeG9+cPcyCNq$g}dHeoRq ziH_$gji!4$D z8qvi4fND|OF_^}%EHz=GMj_*+PCGI>)^li-^fprkq8{TIu!^b?fn}I=1A&^Mu3BDP z)o&*pQ-A)bc46vic1~ad3&d@qFJ_S3ao`TM_8;4RrPAEr2a%nDxdlLf^zN%UpUBI` z!MR7R?&og5vnG&Z0hCCQd-k3>FS{7#v6soTb_ywVtc&JzI2_glV@QcZ#Y&QJnbkM5 z6D7J)Hr|#M5WTL(2Qu*>!}}i$b~==JW91(c3~tJ_Z!}qa9f}LaXjnuz#5k`!zq#ib zV(o|7RkAbqL{?#=A0gZoNH~x0qY^ZN<2XS|Shg(l--&lhFMv;fku3E7E;!!MsxMb= zS|9o6nhY}(t0+jy`vo6vEv!;hEa7rr#jT{KnXl7p1%_V{aq{Sl3!z(i5&YW@D~F8? ze+8aT4qaNq;&W%$C~us*KGWl$PGf?t0~A=WQRFa_Zdep3;T|p4PcwW?w?g17unsd~ z8U{pw)t#I>=5;f%2!je5?lh%az^(B9hF^xDadUzC+TVq$FF8NfvKLdVpw*y56Ue^9T4D?lj*Q^zSb z8waE?LtJ~K>9;!tcu|-bMZ)klR}sCAH|>&*wPp%X?(EWynZKhK?Rg04DuqU_E24$< z+u2b1u*_QPv!}UADM<48`^tToat?K7Qhdsl!W%S&P?r(=6R_WLx2^~mSJjRLMyPzq zCGYdETph#vaxv^g;aiZ!zo#Z2&&7oh*}Yn(zz;=G8$jq}cDtBcd!I4lWiWh7|DR8- z+AGZz@TgSNr3`;7ae++47u+|wvyj}0TXFX}0d||hRcur+0{!0pPho0!hiqk~4`C}M zqJ^evgdiJHon-+BZU;nFV~0|gcdjLN2jIiZxA1+7>>``{zGpF5M7Y;ZTbS#ONa>kSv-MCGhoS% z0RR#qNf8SS#`@v_;0>2EzqE<4!mI-+p1`drZ6t&Ou;%%{y$XO-9y~NDDDrLMQ)~bh zEAL%Eg$N%GNUm@iW@@huDB*${LG14-Snwu8%Kst?PzlfvP+|ZJSdRjrwe%AJ*@&lz z5ixx)+OH*d0VIha7))Haj`GmfKdih8q=*qX9tAfs`ul#U6tH80euO+0KY7hF_vKXo zph_-2sbS%2Npl5WI(1q$I4X(O{FXtsj@+cpCH8hCIeg#x!^;M zZwT55pL@TLzI6K2&%usEX}`@1`VohEKPAGk*OH?kheGw4``kk1=NLa6K>1gv;<_py zKEPL9n9b5~2#E&0Hrib8Ec`(nD-pY$RpHR+#3$POSilk?=yC_CL&?fD88(BJ z)t}n>L&vIQ;3tBzMaz?Qsd&1K?$P`B&vi_cF2`#=QNu=UBLKa^_C_TS!q7SF_}4`% z_lC5v`%Bm_fH|n(Qip?1CY~LaIoZa^<~s#OEz2KcN(pm6g{7i_x3{MTliQA>Z;S45 z^A{#PI~^Kc?MO369LA8o(=%c+i#7RqBMhmVh+oK;(ZQQ(bKlUbk1m_6D01W{{9OqmDv`EZ5VZMQKJT z?qJnbX$EseRf4vAj_o3{07Z^CKw%gLT07n)0w4#mM);J&AE6$pAbw)b4ADy>B!s!2 zYVIZqz%%#;kP5n#p|6GwX#NH*tELB(vM9ddnr)BuG%jcnr{OVD!s@ktTz33K{SDhc zyI<`c;ep`4zzN9LD$y2#6M!R zQw&|pCZe^M<%FrDv#@5qG`LKLBlJLw)%I8Q>MN$p_(e%)kvpWiJy1QaBNFDWFstjd z{i=*yW}HFP$27CR6C}|fgk`nl=v6)o!x_NVF!Pk*Maqef;7jc)9+{e;SD5F${l(_&KLfxOvoD0c!-^DB6 z%*?`M(9D4L`zPYH92mN4rETK%o^oY=!DRR-2VwqIf=Y$2Lk?YmcuZ%07Sf$9Oa2fc zg-n`%VYDwdiEO8iKTs0HQMh28)=@|Y*pLF%oajgAeNR)_*Ej+tpO_4}5TqU;&qGLZ zbGt%Y9}qjf61hpn&ZGj-f+a(cT@>Y6VihIYf47Dzh5uIHN9Y~hk=up&S5i-$PxWQv z2-wZOSzXUjw}rI{guw!T=3Q@HEn70=ZMN{DExE-0-BRuvk4{j=MM zIfh4?1u;hCY(PssdMwn*sPVNy?z`tqnPde^m)LQ^93n`i#i9axm%SdB8e(4+llbI& zHFM1$C}AL{tw?!tE$Gs)UTnK_BS{+)L;6FzH4`?90I?z3J zi6U5n-0Kw{(cclKPVh!EiH^nC9IhFt39vOL@Q4ox3o)zIA1}XP#{&a@qn59umie_l z;tPN3J@(F1E1zhj8%zr2IPl&h*QH#oJL=mzs``l`_giffe4akq%&8%UQy(P<^6?%dDh(4gn9i8d2JZ~9MF;mTo?ha=;jj`7EMqk(H@!J#0 zgqiAJFZ`Khtu&=}aL(r?8KFA$^gzC(yYYKPy~pG095D7mh@vD~vW7O^Fe!^Kw|-2x zKc4Dgm!N0hc9p?nxBp5aoer+a`am%|W`h~Rm!mh#y^{~e-8DD5POrslZic{a5ic!* zui}fbmAU?Lg{UX5acoC-(lUPeik=Mldu4AD01KqhfTk4e&FBNngR33YzXn$(a$d^k zMY*H1&X4NxyvHvTfFx7o99yhF&B=qDdO4)-Szl+bjuTx+-I=8!l0i&z;BiSG#yPbr zFk;xF8ne`Z`PHSNNDX}r@$@c;vqR5NGy?819*iPiHN|U6dY&fsjcA88c$ zQR02>ub4xpGCkGYO*MXpz9064+Auy2tDPyG5Ud3F=H@#b*=c-m}O!%M#BLj#s|S8;(58%Xja7>s!Mqd zj$W1funXAs8k&-}u~T8{r3T|)t?DE4AvgICaKQ54%z4eOOSY)=r+I*UHoh5Qhr4K| zG2r!qMC6??7VUo%N2r+KAzK>t5C=AiEYs5dWAQAqc>T9xZML#}Dh!S0^*tU!%lo$$ zfVn=oW3%1aXuRDr*m&u1Jn$7v=-Oa=8?+e=QZ-#FBfI5CfL)S@n1fKH#1vYeOTY6n zo}HH}avO_t9Lho)0v_ou5Off{EV8@ii#q0mj%^F^qCeg{JNo>2B~lo5847-uv+4Ey z?dvd7`gd`}@A-St@RWufVST1{Xv6*{h2cgw7m^p%-{ez9y=L|HL6xRz!|NeHr1znL zSZXp>zULVQ%OClzQ)b3v;*ozHT?q(=>_dXXXIek277wDYVikT-Ct2vW=dWP^Hv;~?;S>w~ zbAMo~Q1Db~gX4Y_eB~L!_F1i;m5YUa__TL%nsVk+VWfQ{2zg>go(B>MaGl3QZpt#SnhDnq{e1i1NSq?irZ(4RB}Osu@n zdqzTKk~+2Ij}Y{qGt6%;Tph!wrAGES{YBfNbO;KIHOsTh!xH$Q4@oP+SCpV^h4EJD zBz2KUoLH@={XG_ma%O)n%M^vZudkWsA;Qgxl1j_sWP3i)Aim2z_X-0&8Ewybqa*&uX_&IT9_ z*vOq`pIBD+xvv_Y&@M@|M907*LxV=kX=TL%NnLiq}nk~#Pd{e^*K|A&kgE@ukB+reKctk%IlNrMmx`0I~>-2Cs; zVYvMNk_t^^mR=eG1tt1F;oH3K zF>B6Z7bJ6kXp%Rr%e_R(4pI0>FX)0;?hjqq3a$Ap44;K&+`qN(6KS#mAkhC1ji0YC zFB4%tKDuxG&qL~-hv?;s;43Ds7oR;DyXjZ0QY%v2@g0Ii(M8Fj$JuF^Wm0PQSf{&E z3&v{~jK>u!Zm+`W4RGH~!dX;*nbGRgnklBv83qY@nc_d+O8u z8YB1QRL*>E?sL$V+&Jv4Jz-X;`u*Yf4ZnuYI4Nx&hurH4q4Yo-;@6kVJsTDRbGfT#rhhs($Vt(>9g^a>J}eMY=29I$mX-pM(r) zz)7}B&!!R>hCG1bQ@E`EVaR6(_yCr%oKO{Qb-Q-FWZS`tPM<8|zM;#OyCC!VONlmkz%% zvFALiD*m@3O&YdWCFp!N=RR${wAEOZ%Q2G+W`L1(Wr*EuY~qooN2#WUJT`W(kE2aS zdk>tRDr>@D47Pd`r&=_?-;}`I@m?gZs&QspSdyB-?}3V6-|1D|lW`t#iBFO`IMV9N z;txpo&Q99TVqgM-c+ka`Fkfu-{q&29_c>T9L^J|4$c-uE6rH}1aop}Bt19|=#y>RP z-tAR>X`QHt!S&0xn=f;k7f!vzB)+M@Y=-gGJMn|lFOrOuI9lzsbS-5=*L|J;DQ7Cx zntC{fOj&8wKeD2%*-LSC75Vs+#QrMpVOxfT#6vc_FJzXPtdt5W?*&?>*g4Z|+y<%| zW-i5RILb1<`u%0iKb!6Q<64j1>SFCP5iFDilD5%>^)tBC@<)7?E##4TiEkCeHIrN?<<) zCiTZu9$}4im%=fPCBd@E`24D~pbw`;Eca*)HQf+W=$WY<%8AN*p4rdC-B2*`uoc!D<;l1Am67ThoCQO>w zd4uzFylr}jO=csxH>)|V2qVG{x72HW=`h9#?$ zW~yV@jtr+K`MbYV40w*ra{@KVlkc$(PTX3iE&aXOsAEBEDr-hLe(!1D#i}=vqn3(Q zuzyv*9@v~?lprL;$;Y|^Wpcg0_+@^s8zWD;O_Xz!!8=fR2S%TovG=np#@Js*-g;$3 zde;fJ^+y1C4F!eZQF%s)ZFBII=f3PW*+RQ=hxIGgkLd50b@DD#>)qw+%TDcK*R>i{ zn{1d?BeE{onL5c_A!YJ4d!OV?wpFuE>SM4sbOTTzQE6jGMsQW$)rW7aZJgK2JVY(= zi@5I$pX%~yaK6mFAMN`V-^4gy)9WO{cjrvGsX4RvoxzFpf(f<;R)210YyVnRm1fi} zB{xb8Lnr;P_N;d-i$9mUfBuTV0XUFMR}5Ix`mF`>ccQyAq+e6+p&37qWS{9mPJ4{Z z*%EamRxWFlFlJ;vsHY-Vg#&9t+4wnKrJuO#^q|D$JWy`5r>>8#UA)wu6H`}RY^H6bhV(USsC8^+Y?w1=+;65pwrzZbY4sq9)krQB9Z zuFt@w{mq`Vpv$+b?ZP``CN3CNG#NqpPO)8u5^y60SL(rs<5StYQmK;fz2SW6H`6h- zr{tKBk04{dwevK8g4l;ddQgWe?PQ9*rK}_HcI)&&U_y0KEpJtEkk|6en7F{#+Jx&)Jd5bKP5&T`vFw!+ zTU2+*HeO08r=j1HG;V}sjYX8s7FdAvXh4WEAACqj^gQvC z-)eJl8ySbqyldX{*4u9$FJf}@b4!V^-YuM->FW_h4{k1d^@gFFzcFPebL5;0@f_vQ zqs(Dr!H`Zs1!oM~BxI_6SX*<|x0+ zi84pik8KQE3p|6viJn}7`{V~LkxlA>1`Z|r_UknZqjO7n@jB%9;>9)`KX)BgAB(%ntrZrIowId{ClQ+< zy4{eJ$SAE8r{t!2ee$aQrSrtv2IPld?iAdCYe7iSf#1JC0H$#>g!A=$JHpZVwcImFQ9qXC+W*qTV%V>%Vg|( zp6)&BYDRDI!?41(+vj}m+tl`9pwrQSq@pd;nNPWlCHCl}_c&6`Fu8~tjon#!!zjtW zFEN}a^3+-_EK}ZnO|&|wGWuPbd$qD~HN~A?-DNJ?IEG!%D>0=H`dr#LFn{Bh1T9{0 zWm&uS9W&_*l!e=!-(yNFf9mrT@lSs^eMeGt*XV}L;J(60f9vG_lJw-|FKV|fsVCGe zTiOX(hQq>0wN2?z>5$hw6fA`KoR@M7F1oOF*bHWTp|j*hXI~T~Il{PFbNZX58{f|I z8GK3SM}8o<4fB1}jp1ky%IhW1eR?Xi>P^~*R&NZ0yLVi>A7b9XcSOWbm8UmK%fdg zhL9RC6`e7pbGWH`-%dd9@o1V|(P7ttbhhHaqpWJ%(dTv|EnR`OKId6B-*qmw6JTV< zK_auSajmrJ+6jys3mb8AaAwhQd{yT89#gPba68sR&b<6H`qX|hVWF=h-TJIZ{sTED zSLpM=>Z1a{s}66MO-7tantsuRnnL%(o9u9wW0!ZyU(jC5fm$;a=943|28!3!t_9)e zU9H(Z<*U6<_U!q9W+WvhFXHFhtZmt|9(i)U3ck_LVUx(0Q?s$#ZLrFn$X-Op(Wg-B zBUP|((0)-(oiy!ZcHXV*d`nrt9&UfJ{RX5qNP{n`O2=RdaaGyKRdr7^5fl!%$DF_ z&H+sj3fr0}`{CHfnN`8#ed}Yjl6m^|BcUJVR)6l*lZdJ96*tkpi9J}s(Q-^VOMFmq zyus++M&kclH9$jaqvGOX7*4}?sADu~BdSd#{!e8u4qSVxhUw4dzNET#uY$hae8_ra zI^+rS^$ks$2u;sUc8~(+BMeoI&EW}m(YtRXG!i{$Y307K$#TXAn+}Fwd^Xa8D!!Mp zFSxhCJ>!`Y;W40TT|yug4dwC^7iNxkR(b4bgYgAbY>i05TLe!?i?KCAAA1?pcpn@$ z?|lnS`$}%ia4Q9TLPRP$$fn<>^2$vA*DG>%twJruO^{KadquhFYBu=b9%;BoD@gyA znX7d6#rBM|?rE&&Xbg6}-HNImxpz*V`w8-CJ|FnFnM|fMtDDH0?BjjZBfy}6qc5mi zEgu`l{p*BnzHf}}c*Tr-?UYx}$`sQQI&$zhX2r938bLXE$<=Cn+SC8%JvU0`!S~ZP z0U8DhwP&!%3yY(4W-|~FHnt85~S{mTju5qUCuo~SKK=oe3^GpUT<}n zSDR#k&iG}WSX+JkqUV||lf-+4n$1<-0nH<03?(?Ef=YHt*Pk1ZN?x{TZhjXni^2_Q zC_~5VHFFk(ky&b-Qvw@A8_7LIXO^TVXxdX5-L?(Ox8X$G=Dc4<6{QwdFhOo+%SB@h zI~67Y9573vrh&C~yTbHzes{{zH`?a3pTU&e@a4(6IBBYy<%WXqdA)($`F5-?_tBoB zQyY^@+oV&QLF^M?a}R~n(0MO0=lr9G93ElFjWvUVzKyhZ+|{k}nDR+(LVTX*d+WG( z=T2Kp!FA$Z3!fLq*zx5EkCo!N(-PCK z*2W`aYegAOU;~5C2K2M(fwp8@-6D@0)`xqf)pB?kQ6K3;o|mU8+Kvtqmz+ZH54eg&C_n+n5g)kp)k*k1)t5~lz=ox)#_!;^ALCr=j$40tF!olMzUQL5sy?8!b zDhzz~LhzmFvi^Aai+a;F;B{bXGQu@JzkYroSpV>IHxGq(^jQ^kP}m$6@#k5DP+^)#RozB z0zlJ7#;h)8b*Ke-Eq@&@?T(JndWO_UyWvRD;t~}}^wN%r%;3du`F37yaDutAe1>N5 zR`XR`GJOoCbT}0`>~u{gml{rD8fL?QCS7s$_Q6cQ=g0VvO#;+Y8r~M|KBiZlR~mMq zf0h62=5VTg-Xuv4zXD0QZTOm!)I{PJEf+sNF9XE5Z!Yaj*4GB%^sg9nZ0BXb!f*Im zV2GAgWTpTfF?-CV0(b@X&^&vN)wbPdw@b`pqp=KUCHBAb`>P(e*;LVYGX9+*mVae7 zT35Xo)>6eK+Ho0}@J)S0Yts1^o)a`+mjsX*Zd2Nf*4eDQ-L-W+i-t$k2(q@@JUU?2|p~@(jwH7r&Z{K8Ms;=kxmv(!N0M zf>1IaKYwpQT*%{Hhq&-$tr0+F=V^PodTjixUSc|*r*@ybC^skQ+~zCb3Bq9ynm0N* zdd)IRYBGn%YsGVX4z_ry>pi=%mVW<8S%N`TjjdLnB;HxaDuz5&H5sOSx{T;8Yv{fa zI%#1gxy&bs4d-3tzTz?-&+iDrq1okiFU!F6F8J3<2mp(lO*wc8Vw$_wfsC_2$u|<7 z5-B5xH|pPu9H}(aLuw^@6LbIa+ToqSV4Wdad)-icI^ICXLX{W z3AnAi8lz*k@H-BFm8Wj z)C8Rr)RU4Op5%2)if4{T@srixaxr-AeHQjN9xW&^K7mGHR`}#nd{H_-Nvtr+^r;_C zk9-lf@ttlz%RyU(m9kY{6Cj^UOe(29yBY7^{RQ;DBH%>L|Hv+o_^>cl$x50&S-0j= zg4@ud4UL~3G!;%;9a&cwl+`o=aWW=hlDkVroE+Ye_4pTiQJ}({T}W`-X)+o?FBl$V zdQ;UK-4Ko^O1)DaBLHsb$8A6r*hq6^eMcdjk==x8hEEAE@v-`d-Q~Hq{c$KQmZ8P( z!ycAw$cazL0f+WKpL$bLZ~WEW2cO4{+dx!8Y;2eNMoPQH2gLBsd55rbqJos*)h>&w zbS>wIG9BIjz}f?N`H~4ZVydWx%DZ9&P)91rhNs@neLxOP3HoeCf)&#PO?Vc>PvX1G zq6JVM$OfV@l`htn>;e$w0*S+>9EdjisWnX`tj6_NoBpmY*<@Rb%TQxHnb>0Di=x;G9Gug#vdofY@GGv}p= zEhPXCL`QmR-4!#}|9fv#-AhuJI-54I3_D3mw&ePA7Mz~nA`7CqfabOA!ao>_3Zmhr z>!1|2K{LyBJI6HgYB`WV%?hL8B2G-@t9VnQqy*$tfiYToN4>Ze2y=*n)ZKV?Hxr_Q z2(R~C)$6x&lSls5FpYjMt`by_w=h{1iYmLVw=%VBFQoP;pkyf zf`j;}UitG^(U_>qfBd?G2l(Ad%R|Zj_UO_4L$n+_mxUZR?!Y3jaHrKz?}@Mfv9_a> z;9sTq(KeA!2fPm-$H$04NFo^tyN&oQ{)w2iEL<$unQ;6`s&;n5yJuS(u-TxGI^9X* z`E>vqmI5+A>keoj+YJd+c^7;#vHwo%E??I;=V-^nFyzH?Wr^cA0caS8X1*JC=hbM| zM4sE>M3PU~mVsp$6Dlz|x|0NFv>~TVNz~rl_fJ|gB}`&O?)$;=aH``5WHWClCZ%R& zP6`GM>|{%McgzW!Jvj@p0aJ95T<6a|>@3AW!o&IdBt}z}uK2g=gs_ZghSQZn-$C_v z&K1r3c_GP7`?6vfoVU%@^0m!cFa!6I%aT?mtY^bX76%HUjIQ)JwO=3bi@771 z$UJG1hhXiMbqVG!Uq50nt2%|z8~5*mb|rTZ6v;7pIK)PwnS4%Lf};fIjipK*xR`35 zoO1x0H*?VH--h4HC23bC%v(&6fRv|GmqlNc{T=?yRL>{iga8el;2;DCL>JMJfnqE; z9%(hQts^IHi=_m=B9%8pXo?{cIFzrA<6-FCW`&^&TZ>BZx{CIMyK?~GZf>0{jA}ttiQ&=C4tiV#TD}EP zV9D8)`~)l^W{5Psm7oJkmxPZEJ7aGCt&?Ym=isUP#eV=O48*TyE!h5@s?2-~d0=;j zdj-yoONHefk2 ze=m6c4;Uqr1YE2JH(jBf$bXKJ64>pAjZb$N(YcdY#{MgoTW@aylt+b^5A((s>wknA z!W+nsYiBUjyQTAY+O1#HkF^Ojpd7fFh*+T=`m1K&(b)Ujl?Jg;?uuXp8jX#Lftab@ zz2piq-|Xkl+B_Ng_jNd%x|R%W$LK$p_uYa6eb9^`k5_-N+`vehN4VF}&t8aS)DG1R zMwdz^3u5HBs1H?c^IYMe2ViodEM`Xo3mftuf(AgKYFKOYuL)>N6T{OhXv`{~#-w?k-30B2yON*({>$aq~fO^q(dd_z_4Y#1V8BkHR#EByTzE*xD&VhY5z zD~NVWQ=h3r)}(ygk?y_DkE4VrjI+bqJ-78)a(*1ZqLkD$-32n3qWJ!P?2x_hHGwrL;ne_RP8ylG2a5IDi@GAV zgCH9UW~P4i_tq`?V;90AUc9XOQYx@kNTU-LoRc|FY=5hhU=@Vo$Nj> zya4wR29d6*+P#qp(6r|x0lEgat#wmNrB|@M3)!i7hzC59CkMI{4wjQh z-CeHN{=13im9p&*8D@KXM(QP2eYY+mOx}S%aR;NWF2uh!*e^}1waa7nhd@&J7~h;e zxnc`xRk9S(n0N+VOtIO2|c2*NfUpJJ*M>D z7iaWht=3_KQffJzl;wlfDYb9CnWuiwMy^P$LFO&n+P?4-Ca$1Yh9v~Ctq7YaIO%jH zJ3sjkdrT>5@BWtCixcTzg$zmLP!BroGJQXIdqokRY8u-^6EK3ERFwS9M3tKK&=6KP z*$YNZDUy)U$If1byWEbiuTx2$zSB`N!RQehX^vXl61tbNM^=5>cJWlslrl*e+30Xn z&-%7#PhhzPCx}T;&CYRIR^#6gOaYy60^2P8us^3wL}C%|dv+0&pg0IH@^NkzoyAQF zFaS07wuWxNgVzF^;jQ^{u)66mPLn0K8u{Cm7p*zxr*&`>dKs8x~D4AWq@Tk@vms5LZ&ViOs#u7|-xM zOQyv!%=J)f>~`+Do4CR4$fO*gewV8hFG(NSKBIhY?5#+bOvhn!Wn#Fz`gnJ&SO&B) zM-sL<>}d|_zj9;-Xn30_v8{gh#rvgOyP}blbw$4Au+$rRkJG3-l8|I1Rs5537}4KP zT5hO_qGfVzGnf;l5`ECE>%~o)gUqmEPc&{Zd0Jhqrg5EYxDf5iZN(c@q<~$08;!QKVGfa$OSk*YdRLg<&>b^tEb-05HGI(d5>Y zaom%)QYhviu6%R>bV5fRrSLRxU^#R=ervaoNgj4JOs9w2$Dh9}YBqdi{KnAgaq;9T zraTPe8~#^2SN;gq{{D}#hSFwU1)`X7ll$U zGb?J8PR_?BwuUsf=?tX{UHaGgPY)$3bmUZ8h5Yd#x1%lQ8jSGL`;~&tKn4U#`uq|X zte>Mgv~WSwPPJn;7Jw1}=VPBOsnGtTEwnF@LjLU=)Xz5*ju>)fE@p-zMY+CR4xt`} zywfG3e_mYqG+5dR*ZV6!&SQ}E{@K`^CRu)SiWh&V?m^?~YEbC<>h>p6Xh`oyuWC>N zz<%a{FY}h3@A>UJ%jj@VWavz`pY_B~=*xOWO|({Ehn&U0xu`?3*5#LE9p? zTYC#_yvc}tM5uP3As&pCR3%omp~wdRytYJMdWR&vLK-OLQ% zOzzmb=s-N6``7N^Dzic<@%Wv#fn5t5F~^ai6En}`Yz<54UVlzP(!N{MH}-8$k3{lG z_g@W1K#$p!tJvy{dpyI{*h4Z8mx6t9On)+kRbk;EcfwY!~l6^P416M zYj6>H*6{TNH7S%-|4w1c38b*esl2r3MEvZ0Voz5=ECLnU1@;TM z@)t|T?C=#~omimA(m{H6FzYP5ET_i&5nB55KMH>57$tTSeUvH@jEs&& zqXtb&gn>`)y>TP2=y3qP)oY0L+{L}N&gWK;JD+L$w}64|0uNf+Mkcl+R0-;H2uf+0Y~g^{_KX!XE;J5Uld{G1a8ZkwX?UUfkMFzz><_Clc2` z#GJyoh_|e~?IOP|qs^(#rE)9lB8C16Sm{u^T>9}kdfVFa44-yB`~PyD@#|~vdwPE3 z#9J03p4{GF`7h6sw#U=DLYl*B`trlUpbk(i2=We~Gq&yc=hJLB0_h1gIWUaM)iF2A z)dlRnw$}!IGo8=-%#Rlb-q^&zN19vYl>R(zPGF$>RF)IIEIGaH9`j{+`9OTb>FLayx0?q>Ig66BTIdS z)%Nwq*|=i!w$-QLrEOZ5rK{46?;YmKV%Oy=_bvAf(k3upWNZVu+ zS1wE>eqKz>9JQ=IWrKR+#NOeouUvbO)<^%yE$J;MC;OpwpAeW~vIKvX9R*2zP5E6@ zSRz=aD`ItGp$XP}1?*>qa}xy~jam+t_A>UUT2vON{rzGRiuI?1gbahi)IkI#?&xT#4NYno;H!` zqKkkE*d&iz0;4O2XQ|@lIQ^!4R~lg@AtvLZqQfV9RK9RSrKfdJfE8_j^}=Cyoqt5+ zIb&t;DnG5U((}8$Wy3lq()XYO&^d~CyZ1&bhhyjNEVt!GVN8kIm2F^CAMP3sHDZLgO(3~%!(l*53cBEvP}`*Sc0vJDeO-0Z@G_x|Dip+#oMB~@ zSylqKh6VoksvD5%`7mS`@Rn6Ebi>9RXh{cntlH|k#rCLlm1JB)i+3|UQU7)HJsq>(3fctMFu?6NTbz_V&SIV@bhAcd_@j*wn*j^C;Waw5hV$A z*n&gb4J7NWo?yBuFxWBW2)Ukv-8J?qGedY*R(pU#Jy+gRZjFUShw$Rn2T6k`&))a zuG$)#JiFE8xeX-C*oh>*j|wAf?k?s^Va^9D47yh#hbcDAiks(J7L7=YPFx8;@vLSzkUnGh%hE7mbJ9GX)M;#ab!DC zZht1}_9ij-7mdI8H@12$L8xw!6+*?K$mO6A1R7*_gv^#EYTn|wkPM=lOFzwd`Q{>L zceAlbC@UrnhJl;_$~j7tVJWVgeFiqBR-U_4UtH!mKSA{az^Eo=Akfd`0KZE3Hsd-?x3Gzn=9;zwD@DD>jLWnrwBPz zrmuC4lYu%oB+snWMdWyqUxC);Lv)y5L6}6{YPMIbKkr-Ww4bd&b+C$^x}`4Pz&tpO z3kOR58NYpRaRcZS6&17TF_6Dr=w}&(J$?9WJEr;n9+Lb(M=`!=L7bs?2+S)w@@X!y z5pMESzB&Bdo~Ya$?Axy>&a$OCgN)+V>MjUE`i^BVr7<$k&n>;K`hkEA0E~7(E z5D0NQ37ZoEp+M>eU?qIzIkq!J%vslkIU^ccp^eKz8$pj~6N8n>UW+@30ZCvZ9D;jVhT%v!1Z)TIZSmYRGw0kD?0%iZ!IgEQCE*Zs$NMhd;6)tqS$)g<)axxx@_TGUv-4TLL zu>dxyM?C%IL(fCDx`9PmBL53l$xkf6lR&4E`G^yzT{%k1@f%>gF!`esQdhJ90P8u$ zrr?J{KbwD-o6p2jxWmy)JnNMP?j-vq>qV6S*hvJ7zmR># z;_;9}jIQoDc}nt>cu>1V4c35Ny~8dbxljrk zN<@Xxpy*FmkD1Xk?4=(j1q^zMba2kj<*wv!sUpccdU&!Y^_jBYVs+KT`mss@0QVn4 z>3Iv&@5*>|9l2CK)r~X(RZ?PR)g#M|J;RrNMf61|8Dk~z`Y9^Fk5xG{8{7Z`<$MgX zi=LhFfDeui7Cy-$~eR&B2Gt~@y zxO^s&Hw+`dgu$S| zO*}@^&J0*it*fw9XUJ!O12C-gKud4hg%i!PU^E}w?>jo7@5&RCI3Z<24Mq~5v(Q=V z0xq%0xKvmc?ESXrUy9WM?U&OP>BlMyc%ZB#x@V-uq>1S@Av3U-%;rr(A3bIIuySlU zfqv4B(~_rYb4)tQR7Gg8*}#ay#IMqjX8=>q4kdNFb~rr~tXm&~jo|Qhl h{6Doo_d1JP403aLgSmIWKbZZJ|L9%6Le#Yj{~v + + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/bg_btn_with_stroke_red.xml b/examples/example_bestshot/example/app/src/main/res/drawable/bg_btn_with_stroke_red.xml new file mode 100644 index 0000000..58c8395 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/bg_btn_with_stroke_red.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/bg_button_sos.xml b/examples/example_bestshot/example/app/src/main/res/drawable/bg_button_sos.xml new file mode 100644 index 0000000..8c4670d --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/bg_button_sos.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/bg_button_time.xml b/examples/example_bestshot/example/app/src/main/res/drawable/bg_button_time.xml new file mode 100644 index 0000000..d56ab3a --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/bg_button_time.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/bg_linear_grey.xml b/examples/example_bestshot/example/app/src/main/res/drawable/bg_linear_grey.xml new file mode 100644 index 0000000..1261c6a --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/bg_linear_grey.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/calender.png b/examples/example_bestshot/example/app/src/main/res/drawable/calender.png new file mode 100644 index 0000000000000000000000000000000000000000..df79c48c29d57a94ed607091ff708956a722b747 GIT binary patch literal 9179 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 Mr8lq2Us{I#54=tfRsaA1 literal 0 HcmV?d00001 diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/calender2.xml b/examples/example_bestshot/example/app/src/main/res/drawable/calender2.xml new file mode 100644 index 0000000..4ec8c56 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/calender2.xml @@ -0,0 +1,5 @@ + + + diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/cross.png b/examples/example_bestshot/example/app/src/main/res/drawable/cross.png new file mode 100644 index 0000000000000000000000000000000000000000..290802f8e6b6a98b26e2c35fb31998c989e4b267 GIT binary patch literal 426 zcmV;b0agBqP)+uOS{uoEkUxB-C70t8^Kw$?6(+wDsm1I~FBLV5rT1WN=jE$1I#OhN>P zvD~wEcCFM`r^0&}ey+lB&d%5>il+Ehb`yjc7g4le7Yvi0DVcmu2TGX$=Z~%@VttF_ zgsRhbjX`;M+_uZx4r?6GDdw2TN+|<}W&xp-sxKgpQt(Ca1S z(v5TvgUzPTIL{BhU&nv;`w@~?ZF!>t^`EdFjpEcF_BpPF9Vdv>!)DVf#m)T5rzl}Ua&gIPTylyMr8Q + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/down_arrow.xml b/examples/example_bestshot/example/app/src/main/res/drawable/down_arrow.xml new file mode 100644 index 0000000..210ee4c --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/down_arrow.xml @@ -0,0 +1,5 @@ + + + diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/edittext_border.xml b/examples/example_bestshot/example/app/src/main/res/drawable/edittext_border.xml new file mode 100644 index 0000000..19f4b33 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/edittext_border.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/emergency.png b/examples/example_bestshot/example/app/src/main/res/drawable/emergency.png new file mode 100644 index 0000000000000000000000000000000000000000..2625162f37153a623d4dad11920759b0a59de7c1 GIT binary patch literal 16225 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 literal 0 HcmV?d00001 diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/report.png b/examples/example_bestshot/example/app/src/main/res/drawable/report.png new file mode 100644 index 0000000000000000000000000000000000000000..e6663cb8dd13bbdfd15d156592f61b5842b266aa GIT binary patch literal 9684 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≠w=aJsGk~wMu9c8yvtwLhH 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 literal 0 HcmV?d00001 diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/tick.png b/examples/example_bestshot/example/app/src/main/res/drawable/tick.png new file mode 100644 index 0000000000000000000000000000000000000000..4f2b7bbd600ae76e5a01b9c06c4a5bf21bbf4b62 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp@K+MCz1|)ZGH@^v_I14-?iy0WWg+Z8+Vb&Z8pde#$ zkh>GZx^prwfgF}}M_)$E)e-c@N{5_s7jv*C{wUZbH4;k>d28$dy_=-VBg#Ez+ zp$QEwo;Oq;G&mnDVBoW2fBIeTZfi{5-s%bEK;aL8bSF_}Wr{0@<+xd4N&>sw*u6{1-oD!M<#&L0@ literal 0 HcmV?d00001 diff --git a/examples/example_bestshot/example/app/src/main/res/drawable/time.xml b/examples/example_bestshot/example/app/src/main/res/drawable/time.xml new file mode 100644 index 0000000..523d30b --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/drawable/time.xml @@ -0,0 +1,6 @@ + + + + diff --git a/examples/example_bestshot/example/app/src/main/res/layout/activity_approval_list.xml b/examples/example_bestshot/example/app/src/main/res/layout/activity_approval_list.xml new file mode 100644 index 0000000..3522dc5 --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/layout/activity_approval_list.xml @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/example_bestshot/example/app/src/main/res/layout/activity_check_in_new.xml b/examples/example_bestshot/example/app/src/main/res/layout/activity_check_in_new.xml new file mode 100644 index 0000000..55bdf6a --- /dev/null +++ b/examples/example_bestshot/example/app/src/main/res/layout/activity_check_in_new.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +