refactoring code

This commit is contained in:
yb 2022-07-01 01:09:23 +02:00
parent 2ab9d0c59d
commit df864606a2
40 changed files with 713 additions and 91 deletions

View File

@ -24,7 +24,7 @@ android {
multiDexEnabled true
resValue "string", "default_account_iccid", properties.getProperty("default.account.iccid", "")
resValue "string", "default_webserver_url", properties.getProperty("default.webserver.url", "http://10.0.0.1:8080")
resValue "string", "default_webserver_url", properties.getProperty("default.webserver.url", "http://10.0.2.2:8081")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@ -12,6 +12,7 @@ import org.junit.Assert;
import java.io.IOException;
import java.net.SocketTimeoutException;
import eu.csc.ODPAppVehOwnServer.models.JWTTokenResponse;
import eu.csc.vehown.data.model.LoggedInUser;
import lombok.var;
@ -22,6 +23,16 @@ public class VehOwnApiClientFactoryTest extends TestCase {
VehOwnApiClientFactory.setUrl(InstrumentationRegistry.getInstrumentation().getTargetContext());
}
public void testLoggin() {
try {
JWTTokenResponse accessToken = VehOwnApiClientFactory.getAccessToken("test@test.test", "yannyann1");
assertNotNull(accessToken);
System.out.println(accessToken.toString());
} catch (IOException e) {
e.printStackTrace();
assertNull(e);
}
}
public void testFetchUserProfil() {
Exception e = null;
try {

View File

@ -26,15 +26,20 @@ uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android
android:theme="@style/Theme.VehicleOwner"
android:usesCleartextTraffic="true"
tools:targetApi="n">
<activity android:name=".ui.content.ActivityLocalContentNavigation"></activity>
<activity android:name=".ui.base.ActivityBaseDetailContent"></activity>
<activity android:name=".ui.content.ActivityLocalContentNavigation" />
<activity
android:name=".ui.content.LocalContentNavigationActivity"
android:label="@string/title_activity_local_content_navigation"
android:theme="@style/Theme.VehicleOwner.NoActionBar"></activity>
android:theme="@style/Theme.VehicleOwner.NoActionBar" />
<activity
android:name=".ui.base.BaseRegistrationActivity"
android:exported="true"
android:label="@string/title_activity_base_registration" />
android:label="@string/title_activity_base_registration">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.main.MainActivity" />
</activity>
<activity
android:name=".ui.md.ItemDetailHostActivity"
android:exported="true"
@ -47,7 +52,7 @@ uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android
android:label="@string/title_activity_customer_registration" />
<activity
android:name=".ui.svi.DashboardActivity"
android:theme="@style/Theme.VehicleOwner.NoActionBar"></activity>
android:theme="@style/Theme.VehicleOwner.NoActionBar" />
<activity
android:name=".ui.main.MainActivity"
android:label="@string/app_name"
@ -92,7 +97,11 @@ uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android
android:theme="@style/Theme.VehicleOwner.NoActionBar" />
<activity
android:name=".ui.login.LoginActivity"
android:label="@string/app_name" />
android:label="@string/app_name">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.main.MainActivity" />
</activity>
<activity
android:name=".ui.settings.SettingsActivity"
android:label="@string/title_activity_settings" />

View File

@ -44,13 +44,13 @@ public class ServerVehicleApiClient implements IVehOwnAppClient {
}
@Override
public Call<List<VehicleBrandDto>> listVehicleBrands() throws IOException {
return null;
public Call<List<VehicleBrandDto>> listVehicleBrands(){
return clientService.listBrands();
}
@Override
public Call<List<PropulsionTypeDto>> listPropulsionTypes() throws IOException {
return null;
public Call<List<PropulsionTypeDto>> listPropulsionTypes() {
return clientService.listPropulsionTypes();
}
@Override

View File

@ -146,10 +146,18 @@ public class VehOwnApiClientFactory {
call.timeout().deadline(300, TimeUnit.MILLISECONDS);
var response = call.execute();
if(response.isSuccessful())
if(response.isSuccessful() && response.body() != null)
{
var body = response.body();
result.setFirstname(response.body().getFirstname());
result.setLastname(response.body().getLastname());
result.setLogin(response.body().getEmail());
result.setDisplayName(response.body().getEmail());
result.setPassword(password);
result.setStreet(body.getStreet());
//result.setLanguage(body.getLanguage());
result.setPassword(password);
//ToDo //result.setCity(body.get);
}
}

View File

@ -65,7 +65,7 @@ public class VehOwnAppClientDummy implements IVehOwnAppClient {
loggedInUser = new LoggedInUser();
loggedInUser.setPassword("yannyann1");
loggedInUser.setLogin("test@csc-online.eu");
loggedInUser.setLogin("test@test.test");
loggedInUser.setLanguage("en");
}

View File

@ -0,0 +1,17 @@
package eu.csc.vehown.ui.base;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import eu.csc.vehown.R;
import eu.csc.vehown.ui.fragments.details.FragmentDetailVehicle;
import static eu.csc.vehown.ui.svi.SVIVehicleItemDetailFragment.ARG_ITEM_ID;
public abstract class AbstractAppCompatActivity extends AppCompatActivity {
protected void switchFragment(int flContent, Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(flContent, fragment)
.commitNow();
}
}

View File

@ -0,0 +1,64 @@
package eu.csc.vehown.ui.base;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import eu.csc.vehown.R;
import eu.csc.vehown.ui.fragments.details.FragmentDetailDevice;
import eu.csc.vehown.ui.fragments.details.FragmentDetailVehicle;
import eu.csc.vehown.ui.md.ItemDetailFragment;
import eu.csc.vehown.ui.register.RegisterVehicleActivity;
import eu.csc.vehown.ui.register.ShowVehiclesAndDevicesFragment;
import static eu.csc.vehown.ui.fragments.details.AbstractDetailFragment.ARG_ITEM_ID;
public class ActivityBaseDetailContent extends AbstractAppCompatActivity {
private static final String ARG_ITEM_TYPE = "ty";
private static final int ARG_ITEM_TYPE_VEHICLE = 1;
private static final int ARG_ITEM_TYPE_DEVICE = 2;
public static Intent getVehicleDetailInstance(FragmentActivity activity, String vin) {
Intent intent = new Intent(activity, ActivityBaseDetailContent.class);
intent.putExtra(ARG_ITEM_ID, vin);
intent.putExtra(ARG_ITEM_TYPE, ARG_ITEM_TYPE_VEHICLE);
return intent;
}
public static Intent getDeviceDetailInstance(FragmentActivity activity, String identifier) {
Intent intent = new Intent(activity, ActivityBaseDetailContent.class);
intent.putExtra(ARG_ITEM_ID, identifier);
intent.putExtra(ARG_ITEM_TYPE, ARG_ITEM_TYPE_DEVICE);
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_detail_content);
if (getIntent() != null) {
int typeId = getIntent().getIntExtra(ARG_ITEM_TYPE, 0);
String id = getIntent().getStringExtra(ARG_ITEM_ID);
switch (typeId) {
case ARG_ITEM_TYPE_VEHICLE:
Log.d("DATA", getIntent().getStringExtra(ARG_ITEM_ID));
switchFragment(R.id.flContent, FragmentDetailVehicle.newInstance(id));
break;
case ARG_ITEM_TYPE_DEVICE:
switchFragment(R.id.flContent, FragmentDetailDevice.newInstance(id));
break;
}
} else {
}
}
}

View File

@ -47,7 +47,9 @@ public class LoginRepository {
private void setLoggedInUser(LoggedInUser user) {
this.user = user;
localStorage.setLoggedInUser(user);
localStorage.storeCustomer(user);
localStorage.setIsLoggedIn(true);
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
}

View File

@ -0,0 +1,7 @@
package eu.csc.vehown.ui.fragments.details;
import androidx.fragment.app.Fragment;
public abstract class AbstractDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
}

View File

@ -0,0 +1,57 @@
package eu.csc.vehown.ui.fragments.details;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import eu.csc.vehown.R;
import eu.csc.vehown.databinding.FragmentDetailDeviceFragmentBinding;
import eu.csc.vehown.databinding.FragmentDetailVehicleFragmentBinding;
public class FragmentDetailDevice extends AbstractDetailFragment {
private FragmentDetailDeviceViewModel mViewModel;
private FragmentDetailDeviceFragmentBinding binding;
public static FragmentDetailDevice newInstance() {
return new FragmentDetailDevice();
}
public static FragmentDetailDevice newInstance(String deviceId) {
FragmentDetailDevice f = new FragmentDetailDevice();
Bundle args = new Bundle();
args.putString(ARG_ITEM_ID, deviceId);
f.setArguments(args);
return f;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentDetailDeviceFragmentBinding.inflate(inflater, container, false);
View rootView = binding.getRoot();
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(FragmentDetailDeviceViewModel.class);
// TODO: Use the ViewModel
}
}

View File

@ -0,0 +1,7 @@
package eu.csc.vehown.ui.fragments.details;
import androidx.lifecycle.ViewModel;
public class FragmentDetailDeviceViewModel extends ViewModel {
// TODO: Implement the ViewModel
}

View File

@ -0,0 +1,65 @@
package eu.csc.vehown.ui.fragments.details;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import eu.csc.vehown.R;
import eu.csc.vehown.databinding.FragmentDetailVehicleFragmentBinding;
import eu.csc.vehown.databinding.FragmentLoginBinding;
import eu.csc.vehown.ui.md.ItemDetailFragment;
import static eu.csc.vehown.ui.fragments.details.AbstractDetailFragment.ARG_ITEM_ID;
public class FragmentDetailVehicle extends Fragment {
private FragmentDetailVehicleViewModel mViewModel;
private FragmentDetailVehicleFragmentBinding binding;
public static FragmentDetailVehicle newInstance(String vin) {
FragmentDetailVehicle f = new FragmentDetailVehicle();
Bundle args = new Bundle();
args.putString(ARG_ITEM_ID, vin);
f.setArguments(args);
return f;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentDetailVehicleFragmentBinding.inflate(inflater, container, false);
View rootView = binding.getRoot();
Bundle args = getArguments();
String vin = args.getString(ARG_ITEM_ID, "NO_VIN");
Log.d("FR", vin);
EditText tv = binding.editVIN;
binding.tvVIN.setText(vin);
binding.editVIN.setText(vin);
binding.editLicensePlate.setText(vin);
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(FragmentDetailVehicleViewModel.class);
Bundle args = getArguments();
String vin = args.getString(ARG_ITEM_ID, "NO_VIN");
binding.editLicensePlate.setText(vin);
Log.d("FR", vin);
// TODO: Use the ViewModel
}
}

View File

@ -0,0 +1,7 @@
package eu.csc.vehown.ui.fragments.details;
import androidx.lifecycle.ViewModel;
public class FragmentDetailVehicleViewModel extends ViewModel {
// TODO: Implement the ViewModel
}

View File

@ -10,6 +10,7 @@ import androidx.fragment.app.Fragment;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@ -33,6 +34,7 @@ import eu.csc.vehown.ui.viewmodels.AppViewModelFactory;
public class LoginFragment extends Fragment {
private static final String TAG = LoginFragment.class.getSimpleName();
private LoginViewModel loginViewModel;
private FragmentLoginBinding binding;
@ -62,6 +64,7 @@ public class LoginFragment extends Fragment {
final EditText usernameEditText = binding.edEmail;
final EditText passwordEditText = binding.edPassword;
final Button loginButton = binding.btnLogin;
final Button logoutButton = binding.btnLogout;
final CheckBox cbRemember = binding.cbRemember;
final ProgressBar loadingProgressBar = binding.pbLoading;
@ -89,6 +92,7 @@ public class LoginFragment extends Fragment {
}
loadingProgressBar.setVisibility(View.GONE);
if (loginResult.getError() != null) {
Log.d(LoginFragment.class.getSimpleName(), loginResult.getException().toString());
showLoginFailed(loginResult.getError());
}
if (loginResult.getSuccess() != null) {
@ -136,6 +140,18 @@ public class LoginFragment extends Fragment {
passwordEditText.getText().toString());
}
});
if(localStorageClient.getIsLoggedIn() && localStorageClient.getLoggedInUser() != null && localStorageClient.getLoggedInUser().getPassword() != null){
Log.d(TAG, "IS LOGGED IN");
binding.btnLogout.setEnabled(true);
usernameEditText.setText(localStorageClient.getLoggedInUser().getEmail());
passwordEditText.setText(localStorageClient.getLoggedInUser().getPassword());
}else{
Log.d(TAG, "IS NOT LOGGED IN");
usernameEditText.setText("test@test.test");
passwordEditText.setText("yannyann1");
}
}
private void updateUiWithUser(LoggedInUserView model) {

View File

@ -7,19 +7,22 @@ import android.util.Patterns;
import eu.csc.vehown.R;
import eu.csc.vehown.data.model.LoggedInUser;
import eu.csc.vehown.persist.sharedPreferences.LocalStorageClient;
import eu.csc.vehown.ui.fragments.data.LoginRepository;
import eu.csc.vehown.ui.models.LoggedInUserView;
import eu.csc.vehown.ui.models.LoginFormState;
import eu.csc.vehown.ui.models.LoginResult;
import eu.csc.vehown.ui.models.Result;
import eu.csc.vehown.ui.viewmodels.AbstractBaseViewModel;
public class LoginViewModel extends ViewModel {
public class LoginViewModel extends AbstractBaseViewModel {
private MutableLiveData<LoginFormState> loginFormState = new MutableLiveData<>();
private MutableLiveData<LoginResult> loginResult = new MutableLiveData<>();
private LoginRepository loginRepository;
public LoginViewModel(LoginRepository loginRepository) {
public LoginViewModel(LocalStorageClient localStorageClient, LoginRepository loginRepository) {
super(localStorageClient);
this.loginRepository = loginRepository;
}
@ -33,17 +36,24 @@ public class LoginViewModel extends ViewModel {
public void login(String username, String password) {
// can be launched in a separate asynchronous job
Result<LoggedInUser> result = loginRepository.login(username, password);
executorService.submit(new Runnable() {
@Override
public void run() {
Result<LoggedInUser> result = loginRepository.login(username, password);
if (result instanceof Result.Success) {
LoggedInUser data = ((Result.Success<LoggedInUser>) result).getData();
loginResult.setValue(new LoginResult(new LoggedInUserView(data.getDisplayName())));
if (result instanceof Result.Success) {
LoggedInUser data = ((Result.Success<LoggedInUser>) result).getData();
loginResult.postValue(new LoginResult(new LoggedInUserView(data.getDisplayName())));
loginRepository.fetchRemoteContent();
loginRepository.fetchRemoteContent();
} else {
loginResult.postValue(new LoginResult(R.string.login_failed, ((Result.Error)result).getError()));
}
}
});
} else {
loginResult.setValue(new LoginResult(R.string.login_failed));
}
}
public void loginDataChanged(String username, String password) {
@ -56,20 +66,6 @@ public class LoginViewModel extends ViewModel {
}
}
// A placeholder username validation check
private boolean isUserNameValid(String username) {
if (username == null) {
return false;
}
if (username.contains("@")) {
return Patterns.EMAIL_ADDRESS.matcher(username).matches();
} else {
return !username.trim().isEmpty();
}
}
// A placeholder password validation check
private boolean isPasswordValid(String password) {
return password != null && password.trim().length() > 5;
}
}

View File

@ -12,6 +12,7 @@ import android.view.MenuItem;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentTransaction;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
@ -31,9 +32,11 @@ import eu.csc.vehown.ugp.WifiConnectedReceiver;
import eu.csc.vehown.ui.base.BaseRegistrationActivity;
import eu.csc.vehown.ui.content.ActivityLocalContentNavigation;
import eu.csc.vehown.ui.login.LoginActivity;
import eu.csc.vehown.ui.main.dboard.DashboardFragment;
import eu.csc.vehown.ui.md.ItemDetailHostActivity;
import eu.csc.vehown.ui.register.RegisterCustomerActivity;
import eu.csc.vehown.ui.register.RegisterVehicleActivity;
import eu.csc.vehown.ui.registration.customer.FragmentCustomerRegistration;
import eu.csc.vehown.ui.registration.ui.login.CustomerRegistrationActivity;
import eu.csc.vehown.ui.settings.SettingsActivity;
import eu.csc.vehown.ui.svi.DashboardActivity;
@ -125,6 +128,7 @@ public class MainActivity extends AppCompatActivity {
public void menuItemOnClicked(MenuItem item) {
Log.d("MainA", ""+ item.getItemId()+ item.getTitle());
Intent intent = null;
switch (item.getItemId()) {
case R.id.nav_login:
@ -147,6 +151,9 @@ public class MainActivity extends AppCompatActivity {
intent.putExtra(ItemDetailHostActivity.TYPE_ID, ItemDetailHostActivity.TYPE_ID_VEHICLE);
break;
case R.id.nav_dashboard:
Log.d("MainA", "showDashboard");
//showDashboard();
intent = new Intent(this, DashboardActivity.class);
break;
case R.id.nav_register_user:
@ -180,6 +187,14 @@ public class MainActivity extends AppCompatActivity {
}
}
private void showDashboard() {
DashboardFragment fragment = new DashboardFragment();
fragment.setArguments(new Bundle());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.commit();
}
private Intent showLogin() {
return new Intent(this, LoginActivity.class);
}

View File

@ -71,7 +71,13 @@ public class ItemDetailFragment extends Fragment {
// to load content from a content provider.
String id = getArguments().getString(ARG_ITEM_ID);
var oV =SharedPreferencesFactory.getInstance(this.getContext()).findVehicleByVin(id);
mItem = new PlaceholderContent.PlaceholderItem(oV.get().getVin(), oV.get().toString(), oV.get().toString()) ;
if(oV.isPresent()){
mItem = new PlaceholderContent.PlaceholderItem(oV.get().getVin(), oV.get().toString(), oV.get().toString()) ;
}
else{
mItem = PlaceholderContent.PlaceholderItem.getEmpty();
}
//mItem = SharedPreferencesFactory.getInstance(this.getContext()).findVehicleByVin(getArguments().getString(ARG_ITEM_ID));
}
@ -95,8 +101,8 @@ public class ItemDetailFragment extends Fragment {
//Intent intent = RegisterVehicleActivity.editCurrentItem(v.getContext(), mItem.id);
var intent = RegisterVehicleActivity.editCurrentItem(getActivity(), mItem.id);
UIUtils.startActitivity(getActivity(), intent);
startActivity(intent);
//UIUtils.startActitivity(getActivity(), intent);
}
});

View File

@ -6,6 +6,7 @@ import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;
@ -15,8 +16,10 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import eu.csc.vehown.R;
import eu.csc.vehown.databinding.FragmentItemListBinding;
@ -84,7 +87,7 @@ public class ItemListFragment extends Fragment {
ViewCompat.addOnUnhandledKeyEventListener(view, unhandledKeyEventListenerCompat);
RecyclerView recyclerView = binding.itemList;
Button btnItemListAdd = binding.btnItemListAdd;
// Leaving this not using view binding as it relies on if the view is visible the current
// layout configuration (layout, layout-sw600dp)
View itemDetailFragmentContainer = view.findViewById(R.id.item_detail_nav_container);
@ -124,9 +127,10 @@ public class ItemListFragment extends Fragment {
//String e = getArguments().getString(TYPE_ID, null);
String type = getActivity().getIntent().getExtras().getString(TYPE_ID);
ItemDetailHostActivity.LIST_TYPES listTypes = null;
switch (type){
switch (type) {
case TYPE_ID_VEHICLE:
listTypes = ItemDetailHostActivity.LIST_TYPES.VEHICLES;
listTypes = ItemDetailHostActivity.LIST_TYPES.VEHICLES;
break;
case TYPE_ID_DEVICE:
@ -139,12 +143,9 @@ listTypes = ItemDetailHostActivity.LIST_TYPES.VEHICLES;
}
Log.d("ItemDetailHostActivity", "onCreate: " + "");
setupRecyclerView(recyclerView, onClickListener, onContextClickListener, listTypes);
}
@ -157,15 +158,15 @@ listTypes = ItemDetailHostActivity.LIST_TYPES.VEHICLES;
List<PlaceholderContent.PlaceholderItem> items = new ArrayList<>();
fillItems(items, listTypes);
if(listTypes == ItemDetailHostActivity.LIST_TYPES.VEHICLES){
if (listTypes == ItemDetailHostActivity.LIST_TYPES.VEHICLES) {
items.add(new PlaceholderContent.PlaceholderItem("A", "VE", "DETAILS"));
}
if(listTypes == ItemDetailHostActivity.LIST_TYPES.DEVICES){
if (listTypes == ItemDetailHostActivity.LIST_TYPES.DEVICES) {
items.add(new PlaceholderContent.PlaceholderItem("A", "DE", "DETAILS"));
}
// fillItems(items);
// fillItems(items);
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(
items,
@ -177,7 +178,7 @@ listTypes = ItemDetailHostActivity.LIST_TYPES.VEHICLES;
private void fillItems(List<PlaceholderContent.PlaceholderItem> items,
ItemDetailHostActivity.LIST_TYPES listTypes) {
switch (listTypes){
switch (listTypes) {
case VEHICLES:
break;
@ -185,8 +186,8 @@ listTypes = ItemDetailHostActivity.LIST_TYPES.VEHICLES;
break;
}
for (var vehicle: SharedPreferencesFactory.getInstance(getContext()).loadVehicles()
) {
for (var vehicle : SharedPreferencesFactory.getInstance(getContext()).loadVehicles()
) {
items.add(new PlaceholderContent.PlaceholderItem(vehicle.getVin(), vehicle.getModel(), vehicle.toString()));
}
}

View File

@ -50,9 +50,14 @@ public class PlaceholderContent {
this.item = item;
}
public static PlaceholderItem getEmpty() {
return new PlaceholderItem("null", "null", "null");
}
@Override
public String toString() {
return content;
}
}
}

View File

@ -2,10 +2,15 @@ package eu.csc.vehown.ui.models;
import androidx.annotation.Nullable;
import lombok.Getter;
/**
* Authentication result : success (user details) or error message.
*/
public class LoginResult {
@Getter
private Exception exception;
@Nullable
private LoggedInUserView success;
@Nullable
@ -15,6 +20,11 @@ public class LoginResult {
this.error = error;
}
public LoginResult(@Nullable Integer error, Exception ex) {
this.error = error;
this.exception = ex;
}
public LoginResult(@Nullable LoggedInUserView success) {
this.success = success;
}

View File

@ -5,13 +5,17 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import eu.csc.vehown.IVehOwnConsts;
import eu.csc.vehown.R;
import eu.csc.vehown.data.model.*;
@ -37,6 +41,7 @@ public class RegisterVehicleActivity extends AppCompatActivity implements IVehOw
private Handler handler;
private Runnable timer;
private List<View> mandatoryFields;
private static final String TAG = RegisterVehicleActivity.class.getSimpleName();
public static Intent editCurrentItem(Context context, String id) {
@ -45,6 +50,12 @@ public class RegisterVehicleActivity extends AppCompatActivity implements IVehOw
return intent;
}
public static Intent createNew(Context context) {
Intent intent = new Intent(context, RegisterVehicleActivity.class);
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -57,6 +68,8 @@ public class RegisterVehicleActivity extends AppCompatActivity implements IVehOw
if (intent.hasExtra(ItemDetailFragment.ARG_ITEM_ID)) {
id = intent.getStringExtra(ItemDetailFragment.ARG_ITEM_ID);
}
Log.d(TAG, "PASSED ID: " + id);
//sharedPref = SharedPreferencesFactory.getInstance(getApplicationContext());
binding = ActivityRegisterVehicleBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@ -130,17 +143,20 @@ public class RegisterVehicleActivity extends AppCompatActivity implements IVehOw
}
});
List<Vehicle> vehicles = model.getRepository().getStoredUserVehicles();
if (id != null) {
List<Vehicle> vehicles = model.getRepository().getStoredUserVehicles();
if (vehicles.size() > 0) {
if (id == null) {
model.getCurrentVehicle().postValue(vehicles.get(0));
} else {
String finalId = id;
model.getCurrentVehicle().postValue(vehicles.stream().filter(x -> x.getVin().equals(finalId)).findFirst().get());
if (vehicles.size() > 0) {
if (id == null) {
model.getCurrentVehicle().postValue(vehicles.get(0));
} else {
String finalId = id;
model.getCurrentVehicle().postValue(vehicles.stream().filter(x -> x.getVin().equals(finalId)).findFirst().get());
}
}
}
binding.btnStore.setOnClickListener(v -> {
@ -149,6 +165,7 @@ public class RegisterVehicleActivity extends AppCompatActivity implements IVehOw
});
binding.btnUnDo.setOnClickListener(v -> {
model.deleteVehicles();
model.deleteVehicle(getVehicle());
});
@ -236,10 +253,6 @@ public class RegisterVehicleActivity extends AppCompatActivity implements IVehOw
}
private void delayHidingKeyboard(final int delay) {
handler.removeCallbacks(timer);
handler.postDelayed(timer, delay);

View File

@ -153,4 +153,8 @@ public class RegistrationViewModel extends ViewModel {
getRepository().deleteCustomerVehicle(vehicle);
Helper.infoToast(context, "success");
}
public void deleteVehicles() {
getRepository().deleteCustomerVehicles();
}
}

View File

@ -3,11 +3,13 @@ package eu.csc.vehown.ui.register;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
@ -15,11 +17,13 @@ import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;
import eu.csc.vehown.R;
import eu.csc.vehown.data.model.Vehicle;
import eu.csc.vehown.databinding.FragmentShowVehiclesAndDevicesBinding;
import eu.csc.vehown.persist.sharedPreferences.LocalStorageClient;
import eu.csc.vehown.persist.sharedPreferences.SharedPreferencesFactory;
import eu.csc.vehown.ui.base.ActivityBaseDetailContent;
import eu.csc.vehown.ui.viewmodels.AppViewModelFactory;
import java.util.ArrayList;
@ -27,11 +31,11 @@ import java.util.List;
public class ShowVehiclesAndDevicesFragment extends Fragment {
// private LocalStorageClient sharedPref;
private FragmentShowVehiclesAndDevicesBinding binding;
private RegistrationViewModel model;
private ActivityResultLauncher<Intent> launcherEditVehicle, launcherEditDevice;
private VehicleAdapter vehicleAdapter;
// private LocalStorageClient sharedPref;
private FragmentShowVehiclesAndDevicesBinding binding;
private RegistrationViewModel model;
private ActivityResultLauncher<Intent> launcherEditVehicle, launcherEditDevice;
private VehicleAdapter vehicleAdapter;
//TODO private DeviceAdapter deviceAdapter;
@Override
@ -61,7 +65,7 @@ public class ShowVehiclesAndDevicesFragment extends Fragment {
//toolbar.setTitle(R.string.show_vehicles_and_devices);
model = new ViewModelProvider(this, new AppViewModelFactory(getActivity())).get(RegistrationViewModel.class);
vehicleAdapter = new VehicleAdapter();
vehicleAdapter = new VehicleAdapter(model.getStoredUserVehicles());
binding.listVehicles.setAdapter(vehicleAdapter);
//TODO deviceAdapter = new DeviceAdapter();
@ -71,11 +75,11 @@ public class ShowVehiclesAndDevicesFragment extends Fragment {
public class VehicleAdapter extends RecyclerView.Adapter<VehicleAdapter.ViewHolder> {
private final List<Vehicle> listVehicles;
private final List<Vehicle> listVehicles = new ArrayList<>();
VehicleAdapter() {
listVehicles = new ArrayList<>(model.getStoredUserVehicles());
VehicleAdapter(List<Vehicle> items) {
listVehicles.add(null);
listVehicles.addAll(items);
}
@ -84,7 +88,8 @@ public class ShowVehiclesAndDevicesFragment extends Fragment {
notifyDataSetChanged();
}
@Override @NonNull
@Override
@NonNull
public VehicleAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_vehicle, parent, false);
return new VehicleAdapter.ViewHolder(view);
@ -122,7 +127,16 @@ public class ShowVehiclesAndDevicesFragment extends Fragment {
}
private void callVehicleActivity(Vehicle vehicle, int position) {
Intent intent = new Intent(getActivity(), RegisterVehicleActivity.class);
Log.d(ShowVehiclesAndDevicesFragment.class.getSimpleName(), "" + vehicle);
Intent intent = null;
if (vehicle != null) {
intent = ActivityBaseDetailContent.getVehicleDetailInstance(getActivity(), vehicle.getVin());
// intent = RegisterVehicleActivity.editCurrentItem(getActivity(), vehicle.getVin());
} else {
intent = RegisterVehicleActivity.createNew(getActivity());
}
//TODO intent.putExtra(VIN, vehicle.getVin());
//TODO intent.putExtra(POSITION, position);
launcherEditVehicle.launch(intent);

View File

@ -61,11 +61,23 @@ public class CustomerContentDataSource {
profile.getEmail(),
profile.getEmail());
fakeUser.setStreet(profile.getStreet());
fakeUser.setFirstname(profile.getFirstname());
fakeUser.setLastname(profile.getLastname());
fakeUser.setPassword(password);
fakeUser.setLogin(profile.getLogin());
fakeUser.setLanguage(profile.getLanguage());
//fakeUser.setStreet(profile.getStreet());
return new Result.Success<>(fakeUser);
} catch (IOException ioException) {
ioException.printStackTrace();
return new Result.Error(new Exception("Error logging in ", ioException));
}catch (Exception ex){
ex.printStackTrace();
return new Result.Error(new Exception("Error logging in ", ex));
}
}

View File

@ -77,4 +77,8 @@ public class CustomerVehicleRegistrationRepository {
public void deleteCustomerVehicle(Vehicle vehicle) {
localStorageClient.deleteVehicle(vehicle);
}
public void deleteCustomerVehicles() {
localStorageClient.deleteVehicles();
}
}

View File

@ -35,4 +35,10 @@ public abstract class AbstractBaseViewModel extends ViewModel {
protected boolean isPasswordValid(String password, String repeat) {
return password != null && password.trim().length() > 5 && password.equals(repeat);
}
// A placeholder password validation check
protected boolean isPasswordValid(String password) {
return password != null && password.trim().length() > 5;
}
}

View File

@ -43,7 +43,8 @@ public class AppViewModelFactory implements ViewModelProvider.Factory {
if (modelClass.isAssignableFrom(LoginViewModel.class)) {
return (T) new LoginViewModel(LoginRepository.getInstance(new CustomerContentDataSource(), localStorage));
return (T) new LoginViewModel(localStorage,
LoginRepository.getInstance(new CustomerContentDataSource(), localStorage));
}
if (modelClass.isAssignableFrom(CustomerRegistrationViewModel.class)) {

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.base.ActivityBaseDetailContent">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DialogBase" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,6 +6,14 @@
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="48dp"
/>
<fragment
android:id="@+id/nav_host_fragment"

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.fragments.details.FragmentDetailDevice">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello" />
</FrameLayout>

View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.fragments.details.FragmentDetailVehicle">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
>
<TextView
android:id="@+id/tvBrand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/fontS"
android:text="@string/vehicle_brand"
/>
<EditText
android:id="@+id/edBrand"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tvBrand"
android:inputType="none"
/>
<TextView
android:id="@+id/tvModel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/edBrand"
android:layout_marginTop="10dp"
android:textSize="@dimen/fontS"
android:text="@string/vehicle_model"
/>
<Spinner
android:id="@+id/spModel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvModel"
android:spinnerMode="dialog"
android:clickable="false"
/>
<TextView
android:id="@+id/tvPowertrain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/spModel"
android:layout_marginTop="10dp"
android:textSize="@dimen/fontS"
android:text="@string/powertrain"
android:labelFor="@id/editPowertrain"
/>
<EditText
android:id="@+id/editPowertrain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvPowertrain"
android:layout_marginTop="5dp"
android:inputType="text"
android:autofillHints="Powertrain"
android:ems="15"/>
<TextView
android:id="@+id/tvVariant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/editPowertrain"
android:layout_marginTop="5dp"
android:textSize="@dimen/fontS"
android:text="@string/variant"
android:labelFor="@id/editVariant"
/>
<EditText
android:id="@+id/editVariant"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvVariant"
android:inputType="text"
android:autofillHints="Variant"
android:ems="15"/>
<TextView
android:id="@+id/tvVIN"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/editVariant"
android:layout_marginTop="5dp"
android:textSize="@dimen/fontS"
android:text="@string/vin"
android:labelFor="@id/editVIN"
/>
<EditText
android:id="@+id/editVIN"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvVIN"
android:inputType="text"
android:autofillHints="VIN"
android:ems="15"/>
<TextView
android:id="@+id/tvLicensePlate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/editVIN"
android:layout_marginTop="5dp"
android:textSize="@dimen/fontS"
android:text="@string/license_plate"
android:labelFor="@id/editLicensePlate"
/>
<EditText
android:id="@+id/editLicensePlate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvLicensePlate"
android:inputType="text"
android:autofillHints="License Plate"
android:ems="15"/>
<TextView
android:id="@+id/tvPropulsion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/editLicensePlate"
android:layout_marginTop="5dp"
android:textSize="@dimen/fontS"
android:text="@string/propulsion_type"
/>
<Spinner
android:id="@+id/spPropulsion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvPropulsion"
android:spinnerMode="dialog"
/>
<TextView
android:id="@+id/tvRegistrationDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/spPropulsion"
android:layout_marginTop="5dp"
android:textSize="@dimen/fontS"
android:text="@string/registration_date"
/>
<DatePicker
android:id="@+id/datePickerRegistration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvRegistrationDate"
android:calendarViewShown="false"
android:datePickerMode="spinner"/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_marginTop="20dp"
android:layout_below="@id/datePickerRegistration"/>
</RelativeLayout>
</FrameLayout>

View File

@ -10,6 +10,16 @@
android:layout_marginStart="@dimen/container_horizontal_margin"
android:layout_marginEnd="@dimen/container_horizontal_margin">
<Button
android:id="@+id/btnItemListAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/item_list"
android:name="eu.csc.vehown.ui.md.ItemListFragment"
@ -17,7 +27,11 @@
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
android:layout_marginTop="50dp"
app:layout_constraintTop_toBottomOf="@+id/btnItemListAdd"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layoutManager="LinearLayoutManager"
tools:context="eu.csc.vehown.ui.md.ItemDetailHostActivity"
tools:listitem="@layout/item_list_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -59,23 +59,35 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edPassword" />
<Button
android:id="@+id/btnLogin"
android:layout_width="wrap_content"
<LinearLayout
android:id="@+id/llLocalButtons"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="48dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="48dp"
android:layout_marginBottom="64dp"
android:enabled="false"
android:text="@string/action_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="horizontal"
android:layout_marginTop="30dp"
android:layout_width="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/barrier2"
app:layout_constraintVertical_bias="0.2" />
android:layout_gravity="start"
>
<Button
android:id="@+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_login"
android:enabled="false"/>
<Button
android:id="@+id/btnLogout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@string/btn_logout"
android:enabled="false"/>
</LinearLayout>
<ProgressBar
android:id="@+id/pbLoading"

View File

@ -184,6 +184,8 @@
<string name="hint_choose_propulsion_type">Propulsion Type</string>
<string name="btn_no_text">NO_TEXT</string>
<string name="attachment_api_url">RestApi Url</string>
<string name="btn_login">Login</string>
<string name="btn_logout">Logout</string>
<!--string-array name="languages">
<item>english</item>

View File

@ -3,6 +3,7 @@
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.10.101.40</domain>
<domain includeSubdomains="true">10.10.101.30</domain>
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">10.0.0.1</domain>
<domain includeSubdomains="true">192.168.188.54</domain>
</domain-config>

View File

@ -4,12 +4,14 @@ package eu.csc.vehown.data.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
@Getter
@Setter
@NoArgsConstructor
@ToString
public class LoggedInUser implements Serializable, ICustomer {
private String login;

View File

@ -43,6 +43,11 @@ public class Vehicle implements Serializable {
}
public boolean equalsIdentification(Vehicle vehicle) {
if(vin == null)
return false;
if(licensePlate == null)
return false;
return vin.equals(vehicle.vin) || licensePlate.equals(vehicle.licensePlate);
}
}

View File

@ -13,6 +13,7 @@ public interface LocalStorageClient extends IVehOwnData {
LoggedInUser getLoggedInUser();
boolean getIsLoggedIn();
void setIsLoggedIn(boolean value);
String getApiToken();
@ -48,6 +49,8 @@ public interface LocalStorageClient extends IVehOwnData {
void serializeContent(String key, Object value);
<T> T deSerializeContent(String key, T defValue, Class<T> clazz);
void deleteVehicles();
//region ServerData

View File

@ -2,6 +2,7 @@ package eu.csc.vehown.persist.sharedPreferences;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -34,6 +35,7 @@ public class LocalStorageClientImpl implements LocalStorageClient {
// private static final String KEY_LOGGEDINUSERNAME = "prefs_loggedin_username";
private File tokenDir;
private File eventsDir;
private String TAG = LocalStorageClientImpl.class.getSimpleName();
public static LocalStorageClientImpl getInstance(Context context) {
return new LocalStorageClientImpl(context);
@ -71,6 +73,7 @@ public class LocalStorageClientImpl implements LocalStorageClient {
return sharedPreferences.getBoolean(KEY_IS_LOGGED_IN, false);
}
@Override
public String getApiToken() {
if (getIsLoggedIn()) {
@ -216,11 +219,17 @@ public class LocalStorageClientImpl implements LocalStorageClient {
return (T) gson.fromJson(value, clazz);
}
@Override
public void deleteVehicles() {
getEditor().putString(PREF_VEHICLES, null).apply();
}
private SharedPreferences.Editor getEditor() {
return sharedPreferences.edit();
}
public void setLoggedIn(boolean value) {
@Override
public void setIsLoggedIn(boolean value) {
SharedPreferences.Editor editor = getEditor();
editor.putBoolean(KEY_IS_LOGGED_IN, value);
@ -233,6 +242,8 @@ public class LocalStorageClientImpl implements LocalStorageClient {
public void setLoggedInUser(LoggedInUser loggedInUser) {
Log.d(TAG, "Storing User:");
Log.d(TAG, loggedInUser.toString());
String content = getJsonString(loggedInUser);
SharedPreferences.Editor editor = getEditor();
@ -243,7 +254,7 @@ public class LocalStorageClientImpl implements LocalStorageClient {
public void doLogout() {
this.setLoggedIn(false);
this.setIsLoggedIn(false);
this.setLoggedInUser(LoggedInUser.getEmptyUser());
}
@ -252,6 +263,7 @@ public class LocalStorageClientImpl implements LocalStorageClient {
String loggedInUser = sharedPreferences.getString(KEY_LOGGEDINUSER, null);
Log.d(TAG, loggedInUser);
if (loggedInUser == null) {
return null;
}