commit 087c3e991c311f747be37cd8aa1d66813d7caad4 Author: hmalik144 Date: Mon Jan 7 23:16:00 2019 +1100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd45b12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.iml +.gradle +/local.properties +/.idea/caches/build_file_checksums.ser +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml new file mode 100644 index 0000000..2a9c5e0 --- /dev/null +++ b/.idea/assetWizardSettings.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..30aa626 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7ac24c7 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b0c7b20 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..7b30fd2 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "h_mal.appttude.com.driver" + minSdkVersion 24 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support:design:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.android.support:cardview-v7:26.1.0' + implementation 'com.android.support:support-v4:28.0.0' + implementation 'com.google.firebase:firebase-core:16.0.1' + implementation 'com.google.firebase:firebase-auth:16.0.1' + implementation 'com.google.firebase:firebase-storage:16.0.1' + implementation 'com.google.firebase:firebase-database:16.0.1' + implementation 'com.squareup.picasso:picasso:2.71828' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} + +apply plugin: 'com.google.gms.google-services' diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..14913b0 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "311398117829", + "firebase_url": "https://driver-8f4a1.firebaseio.com", + "project_id": "driver-8f4a1", + "storage_bucket": "driver-8f4a1.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:311398117829:android:cd8a17ae21224023", + "android_client_info": { + "package_name": "h_mal.appttude.com.driver" + } + }, + "oauth_client": [ + { + "client_id": "311398117829-ma5nflm7hviakaq16o2r0pubce6ar4rn.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDGShfTzdvwsoYOqtb5pwcnxPxec9u9f8Y" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/h_mal/appttude/com/driver/ExampleInstrumentedTest.java b/app/src/androidTest/java/h_mal/appttude/com/driver/ExampleInstrumentedTest.java new file mode 100644 index 0000000..fd25303 --- /dev/null +++ b/app/src/androidTest/java/h_mal/appttude/com/driver/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package h_mal.appttude.com.driver; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("h_mal.appttude.com.driver", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..99da1a0 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/driver/DateDialog.java b/app/src/main/java/h_mal/appttude/com/driver/DateDialog.java new file mode 100644 index 0000000..488b5c6 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/DateDialog.java @@ -0,0 +1,121 @@ +package h_mal.appttude.com.driver; + +import android.app.DatePickerDialog; +import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.util.Log; +import android.widget.DatePicker; +import android.widget.EditText; +import android.widget.TextView; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class DateDialog extends DatePickerDialog { + + int mYear; + int mMonth; + int mDay; + + EditText editText; + + public DateDialog(@NonNull Context context) { + super(context); + } + + public DateDialog(@NonNull Context context, int themeResId) { + super(context, themeResId); + } + + public DateDialog(@NonNull Context context, + @Nullable DatePickerDialog.OnDateSetListener listener, + int year, int month, int dayOfMonth) { + super(context, listener, year, month, dayOfMonth); + + + } + + public DateDialog(@NonNull Context context, int themeResId, @Nullable DatePickerDialog.OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth) { + super(context, themeResId, listener, year, monthOfYear, dayOfMonth); + + + } + + @Override + public void setTitle(CharSequence title) { + super.setTitle(title); + } + + @Override + public void setOnDateSetListener(@Nullable DatePickerDialog.OnDateSetListener listener) { + super.setOnDateSetListener(dateSetListener); + } + + public void init(EditText editText){ + this.editText = editText; + + String dateString = editText.getText().toString(); + + Date javaDate = null; + + if(TextUtils.isEmpty(dateString)){ + Calendar calendar = Calendar.getInstance(); + mYear = calendar.get(Calendar.YEAR); + mMonth = calendar.get(Calendar.MONTH); + mDay = calendar.get(Calendar.DAY_OF_MONTH); + }else { + try { + SimpleDateFormat sdfrmt = new SimpleDateFormat("dd-MM-yyyy"); + sdfrmt.setLenient(false); + javaDate = sdfrmt.parse(dateString); + } catch (ParseException e) { + e.printStackTrace(); + }finally { + if (javaDate != null) { + mYear = Integer.parseInt(dateString.substring(6, 9)); + mMonth = Integer.parseInt(dateString.substring(4, 5)); + mDay = Integer.parseInt(dateString.substring(1, 2)); + }else { + Calendar calendar = Calendar.getInstance(); + mYear = calendar.get(Calendar.YEAR); + mMonth = calendar.get(Calendar.MONTH); + mDay = calendar.get(Calendar.DAY_OF_MONTH); + } + } + + } + + Log.i(this.getClass().getSimpleName(), "init: year =" + mYear + + "month = " + mMonth + + "day = " + mDay); + + + updateDate(mYear,mMonth,mDay); + + setOnDateSetListener(null); + + this.setTitle(getContext().getString(R.string.set_date)); + this.show(); + } + + DatePickerDialog.OnDateSetListener dateSetListener = new OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { + mYear = year; + mMonth = month + 1; + mDay = dayOfMonth; + + editText.setText(String.format("%02d", mDay) + "-" + + String.format("%02d", (mMonth)) +"-" + + mYear + ); + + } + }; + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/DriverLicenseFragment.java b/app/src/main/java/h_mal/appttude/com/driver/DriverLicenseFragment.java new file mode 100644 index 0000000..f737679 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/DriverLicenseFragment.java @@ -0,0 +1,222 @@ +package h_mal.appttude.com.driver; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.ValueEventListener; +import com.squareup.picasso.Picasso; + +import h_mal.appttude.com.driver.Objects.DriversLicenseObject; +import h_mal.appttude.com.driver.Objects.PrivateHireObject; + +import static h_mal.appttude.com.driver.FirebaseClass.DRIVERS_LICENSE_FIREBASE; +import static h_mal.appttude.com.driver.FirebaseClass.DRIVER_FIREBASE; +import static h_mal.appttude.com.driver.FirebaseClass.PRIVATE_HIRE_FIREBASE; +import static h_mal.appttude.com.driver.FirebaseClass.USER_FIREBASE; +import static h_mal.appttude.com.driver.ImageSelectorDialog.CAMERA_REQUEST; +import static h_mal.appttude.com.driver.ImageSelectorDialog.MY_CAMERA_PERMISSION_CODE; +import static h_mal.appttude.com.driver.MainActivity.auth; +import static h_mal.appttude.com.driver.MainActivity.fragmentManager; +import static h_mal.appttude.com.driver.MainActivity.getDateStamp; +import static h_mal.appttude.com.driver.MainActivity.mDatabase; + +public class DriverLicenseFragment extends Fragment { + + private String TAG = this.getClass().getSimpleName(); + + private ImageView imageView; + + EditText licenseNo; + EditText expiry; + + public Uri filePath; + public Uri picUri; + + String li_numberString; + String li_exprString; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_driver_license, container, false); + + imageView = view.findViewById(R.id.driversli_img); + + DatabaseReference reference = mDatabase.child(USER_FIREBASE).child(auth.getCurrentUser().getUid()) + .child(DRIVER_FIREBASE).child(DRIVERS_LICENSE_FIREBASE); + + reference.addListenerForSingleValueEvent(valueEventListener); + + TextView uploadLic = view.findViewById(R.id.upload_lic); + + licenseNo = view.findViewById(R.id.lic_no); + expiry = view.findViewById(R.id.lic_expiry); + + expiry.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + DateDialog dateDialog = new DateDialog(getContext()); + dateDialog.init(expiry); + } + }); + + Button submit = view.findViewById(R.id.submit); + submit.setOnClickListener(submitOnClickListener); + + uploadLic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ImageSelectorDialog imageSelectorDialog = new ImageSelectorDialog(getContext()); + imageSelectorDialog.setImageName("drivers_license"); + imageSelectorDialog.show(); + } + }); + + return view; + } + + View.OnClickListener submitOnClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + li_numberString = licenseNo.getText().toString().trim(); + li_exprString = expiry.getText().toString().trim(); + + if (!TextUtils.isEmpty(li_numberString) && + !TextUtils.isEmpty(li_exprString)){ + if (filePath != null){ + Log.i(TAG, "onClick: new Image uploaded"); + new FirebaseClass(getContext(),filePath,new FirebaseClass.Response(){ + @Override + public void processFinish(Uri output) { + Log.i(TAG, "processFinish: "); + if (output != null){ + picUri = output; + publishObject(); + fragmentManager.popBackStack(); + } + + } + }).uploadImage(DRIVERS_LICENSE_FIREBASE,DRIVERS_LICENSE_FIREBASE + getDateStamp()); + }else{ + Log.i(TAG, "onClick: pushing with same image"); + publishObject(); + } + + }else { + if (TextUtils.isEmpty(li_numberString)){ + licenseNo.setError("Field required"); + } + if (TextUtils.isEmpty(li_exprString)){ + expiry.setError("Field required"); + } + if (picUri == null){ + Toast.makeText(getContext(), getString(R.string.image_required), Toast.LENGTH_SHORT).show(); + } + } + + } + + }; + + ValueEventListener valueEventListener = new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot dataSnapshot) { + DriversLicenseObject driversLicenseObject = null; + try{ + driversLicenseObject = dataSnapshot.getValue(DriversLicenseObject.class); + }catch (Exception e){ + Log.e(TAG, "onDataChange: ", e); + }finally { + if (driversLicenseObject != null){ + picUri = Uri.parse(driversLicenseObject.getLicenseImageString()); + li_numberString = driversLicenseObject.getLicenseNumber(); + li_exprString = driversLicenseObject.getLicenseExpiry(); + + licenseNo.setText(li_numberString); + expiry.setText(li_exprString); + Picasso.get() + .load(picUri) + .placeholder(R.mipmap.ic_launcher_round) + .into(imageView); + } + } + } + + @Override + public void onCancelled(@NonNull DatabaseError databaseError) { + + } + }; + + private void publishObject(){ + + DriversLicenseObject driversLicenseObject = new DriversLicenseObject(picUri.toString(),li_numberString,li_exprString); + + mDatabase.child(USER_FIREBASE).child(auth.getCurrentUser().getUid()).child(DRIVER_FIREBASE).child(DRIVERS_LICENSE_FIREBASE) + .setValue(driversLicenseObject).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + + Log.i(TAG, "onComplete: publish = " + task.isSuccessful()); + } + }); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == MY_CAMERA_PERMISSION_CODE) { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Toast.makeText(getContext(), "camera permission granted", Toast.LENGTH_LONG).show(); + Intent cameraIntent = new + Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); + startActivityForResult(cameraIntent, CAMERA_REQUEST); + } else { + Toast.makeText(getContext(), "camera permission denied", Toast.LENGTH_LONG).show(); + } + + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + new ImageSelectorResults(new ImageSelectorResults.FilepathResponse() { + @Override + public void processFinish(Uri output) { + filePath = output; + } + }).Results(getActivity(),requestCode, resultCode, data, + filePath,imageView); + + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/FindAddressFragment.java b/app/src/main/java/h_mal/appttude/com/driver/FindAddressFragment.java new file mode 100644 index 0000000..bfc8a42 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/FindAddressFragment.java @@ -0,0 +1,56 @@ +package h_mal.appttude.com.driver; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class FindAddressFragment extends Fragment { + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_find_address, container, false); + + TextView findAddress = view.findViewById(R.id.findaddress); + Button sumbit = view.findViewById(R.id.submit); + + LinearLayout linearLayout = view.findViewById(R.id.lin_lay); + + EditText address = view.findViewById(R.id.address); + EditText postcode = view.findViewById(R.id.postcode); + + findAddress.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ImageSelectorDialog dialogAddress = new ImageSelectorDialog(getContext()); + dialogAddress.show(); + } + }); + + sumbit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); + + + return view; + } + + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/FirebaseClass.java b/app/src/main/java/h_mal/appttude/com/driver/FirebaseClass.java new file mode 100644 index 0000000..82f436f --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/FirebaseClass.java @@ -0,0 +1,100 @@ +package h_mal.appttude.com.driver; + +import android.app.ProgressDialog; +import android.content.Context; +import android.net.Uri; +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.util.Log; +import android.widget.Toast; + +import com.google.android.gms.tasks.Continuation; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.storage.OnProgressListener; +import com.google.firebase.storage.StorageReference; +import com.google.firebase.storage.UploadTask; + +import static h_mal.appttude.com.driver.MainActivity.auth; +import static h_mal.appttude.com.driver.MainActivity.storageReference; + +public class FirebaseClass { + + public static final String USER_FIREBASE = "user"; + public static final String DRIVER_FIREBASE = "driver_profile"; + public static final String DRIVER_DETAILS_FIREBASE = "driver_details"; + public static final String PRIVATE_HIRE_FIREBASE = "private_hire"; + public static final String DRIVERS_LICENSE_FIREBASE = "driver_license"; + + public static final String VEHICLE_FIREBASE = "vehicle_profile"; + public static final String MOT_FIREBASE = "mot_details"; + public static final String VEHICLE_DETAILS_FIREBASE = "vehicle_details"; + public static final String INSURANCE_FIREBASE = "insurance_details"; + public static final String LOG_BOOK_FIREBASE = "log_book"; + + Context context; + Uri filePath; + + public interface Response { + void processFinish(Uri output); + } + + public Response delegate; + + public FirebaseClass(Context context, Uri filePath, Response delegate) { + this.context = context; + this.filePath = filePath; + this.delegate = delegate; + } + + public void uploadImage(String path, String name) { + + if(filePath != null) + { + final ProgressDialog progressDialog = new ProgressDialog(context); + progressDialog.setTitle("Uploading..."); + progressDialog.show(); + + final StorageReference ref = storageReference.child("images/"+ auth.getCurrentUser().getUid() + "/" + path + + "/" + name); + + UploadTask uploadTask = ref.putFile(filePath); + + uploadTask.addOnProgressListener(new OnProgressListener() { + @Override + public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { + double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot + .getTotalByteCount()); + progressDialog.setMessage("Uploaded "+(int)progress+"%"); + } + }).continueWithTask(new Continuation>() { + @Override + public Task then(@NonNull Task task) throws Exception { + if (!task.isSuccessful()) { + throw task.getException(); + } + + // Continue with the task to get the download URL + return ref.getDownloadUrl(); + } + }).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + delegate.processFinish(task.getResult()); + progressDialog.dismiss(); + Toast.makeText(context, "Uploaded Successfully", Toast.LENGTH_SHORT).show(); + Log.i(context.getClass().getSimpleName(), "onComplete: uploaded Successful uri: " + task.getResult()); + } else { + delegate.processFinish(null); + progressDialog.dismiss(); + Toast.makeText(context, "Failed to upload", Toast.LENGTH_SHORT).show(); + Log.i(context.getClass().getSimpleName(), "onComplete: failed to get url"); + } + } + }); + + } + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/ImageSelectorDialog.java b/app/src/main/java/h_mal/appttude/com/driver/ImageSelectorDialog.java new file mode 100644 index 0000000..7c35667 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/ImageSelectorDialog.java @@ -0,0 +1,150 @@ +package h_mal.appttude.com.driver; + +import android.Manifest; +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.Fragment; +import android.support.v4.content.FileProvider; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.Toast; + +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static android.support.v4.app.ActivityCompat.requestPermissions; +import static android.support.v4.app.ActivityCompat.startActivityForResult; +import static android.support.v4.content.PermissionChecker.checkSelfPermission; +import static h_mal.appttude.com.driver.MainActivity.fragmentManager; +import static h_mal.appttude.com.driver.MainActivity.verifyStoragePermissions; + +public class ImageSelectorDialog extends Dialog{ + + private String TAG = this.getClass().getSimpleName(); + public static final int PICK_IMAGE_REQUEST = 71; + public static final int CAMERA_REQUEST = 1888; + public static final int MY_CAMERA_PERMISSION_CODE = 100; + + private String saveFileName; + public static Uri photoURI; + + Fragment fragment; + + public ImageSelectorDialog(@NonNull Context context) { + super(context); + + this.saveFileName = "default_name"; + } + + public ImageSelectorDialog(@NonNull Context context, int themeResId) { + super(context, themeResId); + this.saveFileName = "default_name"; + } + + protected ImageSelectorDialog(@NonNull Context context, boolean cancelable, @Nullable DialogInterface.OnCancelListener cancelListener) { + super(context, cancelable, cancelListener); + this.saveFileName = "default_name"; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.address_dialog); + + //check if we have we have storage rights + int permission = ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE); + + if (permission != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(getContext(), "Storage permissions not granted", Toast.LENGTH_SHORT).show(); + }else { + + fragment = fragmentManager.getFragments().get(0); + + Button upload = findViewById(R.id.upload); + Button takePic = findViewById(R.id.take_pic); + + upload.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + chooseImage(); + dismiss(); + } + }); + + takePic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if ( + checkSelfPermission(fragment.getActivity(), Manifest.permission.CAMERA) + != PackageManager.PERMISSION_GRANTED) { + requestPermissions(fragment.getActivity(), new String[]{Manifest.permission.CAMERA}, + MY_CAMERA_PERMISSION_CODE); + } else { + Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); + File file = createFile(); + photoURI = Uri.fromFile(file); + Uri imageUri = FileProvider.getUriForFile( + getContext(), + "h_mal.appttude.com.driver", + file); + cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); + fragment.startActivityForResult(cameraIntent, CAMERA_REQUEST); + + } + + dismiss(); + } + }); + } + + } + + public void setImageName(String saveFileName){ + this.saveFileName = saveFileName; + } + + private File createFile(){ + //create directory + File root = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES); + //create file + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmm"); + String currentDateandTime = sdf.format(new Date()); + String fname = saveFileName+ currentDateandTime; + File image = new File(root,fname); + + return image; + + } + + private void chooseImage() { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + + fragment.startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST); + + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/ImageSelectorResults.java b/app/src/main/java/h_mal/appttude/com/driver/ImageSelectorResults.java new file mode 100644 index 0000000..0ebe476 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/ImageSelectorResults.java @@ -0,0 +1,125 @@ +package h_mal.appttude.com.driver; + +import android.Manifest; +import android.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Picture; +import android.net.Uri; +import android.os.Environment; +import android.provider.MediaStore; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import h_mal.appttude.com.driver.Objects.PrivateHireObject; + +import static android.app.Activity.RESULT_OK; +import static android.os.Environment.DIRECTORY_PICTURES; +import static h_mal.appttude.com.driver.ImageSelectorDialog.CAMERA_REQUEST; +import static h_mal.appttude.com.driver.ImageSelectorDialog.PICK_IMAGE_REQUEST; +import static h_mal.appttude.com.driver.ImageSelectorDialog.photoURI; +import static h_mal.appttude.com.driver.MainActivity.getDateStamp; + +public class ImageSelectorResults { + + Activity activity; + + public interface FilepathResponse { + void processFinish(Uri output); + } + + public FilepathResponse delegate; + + public ImageSelectorResults(FilepathResponse delegate) { + this.delegate = delegate; + } + + public void Results(Activity activity, int requestCode, int resultCode, Intent data, Uri filePath, + ImageView imageView){ + + this.activity = activity; + + if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK + && data != null && data.getData() != null ) + { + filePath = data.getData(); + Bitmap bitmap = null; + try { + bitmap = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), filePath); + if (imageView.getVisibility() != View.VISIBLE) { + imageView.setVisibility(View.VISIBLE); + } + imageView.setImageBitmap(bitmap); + } + catch (IOException e) + { + e.printStackTrace(); + } + finally { + if (bitmap != null){ +// + } + } + } + + if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) { + //check if we have we have storage rights + int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); + + if (permission != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(activity, "Storage permissions not granted", Toast.LENGTH_SHORT).show(); + return; + }else { + + try { + File f = Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES); + String fname = "driver"+ getDateStamp() + ".jpg"; + File image = new File(f,fname); + FileOutputStream fileOutputStream = new FileOutputStream(image); + + filePath = photoURI; + + Bitmap bitmap = MediaStore.Images.Media + .getBitmap(activity.getContentResolver(), photoURI); + + imageView.setImageBitmap(bitmap); + + bitmap.compress(Bitmap.CompressFormat.JPEG, 90,fileOutputStream); + fileOutputStream.flush(); + fileOutputStream.close(); + galleryAddPic(); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + } + + delegate.processFinish(filePath); + Log.i(getClass().getSimpleName(), "Results: " + filePath); + } + + private void galleryAddPic() { + Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + File f = new File(photoURI.getPath()); + Uri contentUri = Uri.fromFile(f); + mediaScanIntent.setData(contentUri); + activity.sendBroadcast(mediaScanIntent); + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/InsuranceFragment.java b/app/src/main/java/h_mal/appttude/com/driver/InsuranceFragment.java new file mode 100644 index 0000000..0fd5139 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/InsuranceFragment.java @@ -0,0 +1,43 @@ +package h_mal.appttude.com.driver; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + + +public class InsuranceFragment extends Fragment { + + private String TAG = this.getClass().getSimpleName(); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_insurance, container, false); + + TextView uploadInsurance = view.findViewById(R.id.uploadInsurance); + + + + uploadInsurance.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); + + return view; + } + +} \ No newline at end of file diff --git a/app/src/main/java/h_mal/appttude/com/driver/LoginActivity.java b/app/src/main/java/h_mal/appttude/com/driver/LoginActivity.java new file mode 100644 index 0000000..75481c1 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/LoginActivity.java @@ -0,0 +1,230 @@ +package h_mal.appttude.com.driver; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.annotation.TargetApi; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.support.annotation.NonNull; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.app.LoaderManager.LoaderCallbacks; + +import android.content.CursorLoader; +import android.content.Loader; +import android.database.Cursor; +import android.net.Uri; +import android.os.AsyncTask; + +import android.os.Build; +import android.os.Bundle; +import android.provider.ContactsContract; +import android.text.TextUtils; +import android.view.KeyEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.inputmethod.EditorInfo; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; + +import java.util.ArrayList; +import java.util.List; + +import static android.Manifest.permission.READ_CONTACTS; + +/** + * A login screen that offers login via email/password. + */ +public class LoginActivity extends AppCompatActivity{ + + private FirebaseAuth auth; + + private static final String[] DUMMY_CREDENTIALS = new String[]{ + "driver@example.com:hello", "bar@example.com:world" + }; + + // UI references. + private EditText mEmailView; + private EditText mPasswordView; + private View mProgressView; + private View mLoginView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + + auth = FirebaseAuth.getInstance(); + // Set up the login form. + mEmailView = findViewById(R.id.email); + + mPasswordView = (EditText) findViewById(R.id.password); + mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { + if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) { + attemptLogin(); + return true; + } + return false; + } + }); + + + Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button); + mEmailSignInButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + attemptLogin(); + } + }); + + mProgressView = findViewById(R.id.login_progress); + mLoginView = findViewById(R.id.email_login_form); + + TextView register = findViewById(R.id.register); + register.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(getApplication(),RegisterActivity.class); + startActivity(intent); + } + }); + } + + + + + /** + * Attempts to sign in or register the account specified by the login form. + * If there are form errors (invalid email, missing fields, etc.), the + * errors are presented and no actual login attempt is made. + */ + private void attemptLogin() { + if (auth == null) { + Toast.makeText(this, "Login invalid", Toast.LENGTH_SHORT).show(); + return; + } + + // Reset errors. + mEmailView.setError(null); + mPasswordView.setError(null); + + // Store values at the time of the login attempt. + String email = mEmailView.getText().toString(); + String password = mPasswordView.getText().toString(); + + boolean cancel = false; + View focusView = null; + + // Check for a valid password, if the user entered one. + if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) { + mPasswordView.setError(getString(R.string.error_invalid_password)); + focusView = mPasswordView; + cancel = true; + } + + // Check for a valid email address. + if (TextUtils.isEmpty(email)) { + mEmailView.setError(getString(R.string.error_field_required)); + focusView = mEmailView; + cancel = true; + } else if (!isEmailValid(email)) { + mEmailView.setError(getString(R.string.error_invalid_email)); + focusView = mEmailView; + cancel = true; + } + + if (cancel) { + // There was an error; don't attempt login and focus the first + // form field with an error. + focusView.requestFocus(); + } else { + // Show a progress spinner, and kick off a background task to + // perform the user login attempt. + + showProgress(true); + auth.signInWithEmailAndPassword(email,password) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + showProgress(false); + + Intent intent = new Intent(LoginActivity.this,MainActivity.class); + startActivity(intent); + finish(); + + } + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Toast.makeText(LoginActivity.this, getString(R.string.login_failed), Toast.LENGTH_SHORT).show(); + showProgress(false); + } + }); + + + + } + } + + private boolean isEmailValid(String email) { + //TODO: Replace this with your own logic + return email.contains("@"); + } + + private boolean isPasswordValid(String password) { + //TODO: Replace this with your own logic + return password.length() > 6; + } + + /** + * Shows the progress UI and hides the login form. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) + private void showProgress(final boolean show) { + // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow + // for very easy animations. If available, use these APIs to fade-in + // the progress spinner. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { + int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); + + mLoginView.setVisibility(show ? View.GONE : View.VISIBLE); + mLoginView.animate().setDuration(shortAnimTime).alpha( + show ? 0 : 1).setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mLoginView.setVisibility(show ? View.GONE : View.VISIBLE); + } + }); + + mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); + mProgressView.animate().setDuration(shortAnimTime).alpha( + show ? 1 : 0).setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); + } + }); + } else { + // The ViewPropertyAnimator APIs are not available, so simply show + // and hide the relevant UI components. + mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); + mLoginView.setVisibility(show ? View.GONE : View.VISIBLE); + } + } + + +} + diff --git a/app/src/main/java/h_mal/appttude/com/driver/MainActivity.java b/app/src/main/java/h_mal/appttude/com/driver/MainActivity.java new file mode 100644 index 0000000..736454c --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/MainActivity.java @@ -0,0 +1,205 @@ +package h_mal.appttude.com.driver; + +import android.Manifest; +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.app.AlertDialog; +import android.util.Log; +import android.view.View; +import android.support.design.widget.NavigationView; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; +import com.squareup.picasso.Picasso; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class MainActivity extends AppCompatActivity + implements NavigationView.OnNavigationItemSelectedListener { + + private static String TAG = MainActivity.class.getSimpleName(); + + public static FragmentManager fragmentManager; + public static FirebaseAuth auth; + public static FirebaseStorage storage; + public static StorageReference storageReference; + public static DatabaseReference mDatabase; + + public static NavigationView navigationView; + + private static final int REQUEST_EXTERNAL_STORAGE = 1; + private static String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + auth = FirebaseAuth.getInstance(); + storage = FirebaseStorage.getInstance(); + storageReference = storage.getReference(); + mDatabase = FirebaseDatabase.getInstance().getReference(); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + drawer.addDrawerListener(toggle); + toggle.syncState(); + + navigationView = (NavigationView) findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + + fragmentManager = getSupportFragmentManager(); + executeFragment(new homeFragment()); + + setupDrawer(); + + } + + public static void executeFragment(Fragment f){ + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + fragmentTransaction.replace(R.id.container,f).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).addToBackStack(f.getClass().getSimpleName()).commit(); + } + + public static void setupDrawer(){ + View header = navigationView.getHeaderView(0); + + TextView driverEmail = header.findViewById(R.id.driver_email); + TextView driverName = header.findViewById(R.id.driver_name); + ImageView driverImage = header.findViewById(R.id.profileImage); + + if (auth != null){ + FirebaseUser user = auth.getCurrentUser(); + if (user.getEmail() != null){ + driverEmail.setText(user.getEmail()); + } + if (user.getDisplayName() != null){ + driverName.setText(user.getDisplayName()); + } + + Log.i(TAG, "setupDrawer: "+ storageReference.child("images/"+auth.getCurrentUser().getEmail()+"/profile_pic").getDownloadUrl()); + + Picasso.get() + .load(user.getPhotoUrl()) + .placeholder(R.mipmap.ic_launcher_round) + .into(driverImage); + } + + + } + + @Override + public void onBackPressed() { + DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + if (fragmentManager.getBackStackEntryCount() > 1) { + fragmentManager.popBackStack(); + }else{ + new AlertDialog.Builder(this,R.style.Theme_AppCompat_Dialog_Alert) + .setTitle("Leave?") + .setMessage("Are you sure you want to exit?") + .setNegativeButton(android.R.string.no, null) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface arg0, int arg1) { + finish(); + System.exit(0); + } + }).create().show(); + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("StatementWithEmptyBody") + @Override + public boolean onNavigationItemSelected(MenuItem item) { + // Handle navigation view item clicks here. + int id = item.getItemId(); + + if (id == R.id.nav_camera) { + // Handle the camera action + executeFragment(new profileFragment()); + } else if (id == R.id.nav_gallery) { + executeFragment(new driverProfileFragment()); + } else if (id == R.id.nav_slideshow) { + executeFragment(new VehicleSetupFragment()); + } + + DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); + drawer.closeDrawer(GravityCompat.START); + return true; + } + + public static void verifyStoragePermissions(Activity activity) { + // Check if we have write permission + int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); + + if (permission != PackageManager.PERMISSION_GRANTED) { + // We don't have permission so prompt the user + ActivityCompat.requestPermissions( + activity, + PERMISSIONS_STORAGE, + REQUEST_EXTERNAL_STORAGE + ); + } + } + + public static String getDateStamp(){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmm"); + return sdf.format(new Date()); + } +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/MotFragment.java b/app/src/main/java/h_mal/appttude/com/driver/MotFragment.java new file mode 100644 index 0000000..efeff74 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/MotFragment.java @@ -0,0 +1,43 @@ +package h_mal.appttude.com.driver; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + + +public class MotFragment extends Fragment { + + private String TAG = this.getClass().getSimpleName(); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_mot, container, false); + + TextView uploadMot = view.findViewById(R.id.uploadmot); + + + + uploadMot.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + } + }); + + return view; + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/Objects/DriverProfileObject.java b/app/src/main/java/h_mal/appttude/com/driver/Objects/DriverProfileObject.java new file mode 100644 index 0000000..d2b0b36 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/Objects/DriverProfileObject.java @@ -0,0 +1,55 @@ +package h_mal.appttude.com.driver.Objects; + +public class DriverProfileObject { + + public String driverPic; + public String forenames; + public String address; + public String postcode; + public String dob; + public String ni; + public String dateFirst; + + public DriverProfileObject() { + } + + public DriverProfileObject(String driverPic, String forenames, String address, + String postcode, String dob, String ni, String dateFirst) { + this.driverPic = driverPic; + this.forenames = forenames; + this.address = address; + this.postcode = postcode; + this.dob = dob; + this.ni = ni; + this.dateFirst = dateFirst; + } + + public String getDriverPic() { + return driverPic; + } + + public String getForenames() { + return forenames; + } + + public String getAddress() { + return address; + } + + public String getPostcode() { + return postcode; + } + + public String getDob() { + return dob; + } + + public String getNi() { + return ni; + } + + public String getDateFirst() { + return dateFirst; + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/Objects/DriversLicenseObject.java b/app/src/main/java/h_mal/appttude/com/driver/Objects/DriversLicenseObject.java new file mode 100644 index 0000000..70478d0 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/Objects/DriversLicenseObject.java @@ -0,0 +1,29 @@ +package h_mal.appttude.com.driver.Objects; + +public class DriversLicenseObject { + + public String licenseImageString; + public String licenseNumber; + public String licenseExpiry; + + public DriversLicenseObject() { + } + + public DriversLicenseObject(String licenseImageString, String licenseNumber, String licenseExpiry) { + this.licenseImageString = licenseImageString; + this.licenseNumber = licenseNumber; + this.licenseExpiry = licenseExpiry; + } + + public String getLicenseImageString() { + return licenseImageString; + } + + public String getLicenseNumber() { + return licenseNumber; + } + + public String getLicenseExpiry() { + return licenseExpiry; + } +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/Objects/InsuranceObject.java b/app/src/main/java/h_mal/appttude/com/driver/Objects/InsuranceObject.java new file mode 100644 index 0000000..64f0eb3 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/Objects/InsuranceObject.java @@ -0,0 +1,4 @@ +package h_mal.appttude.com.driver.Objects; + +class InsuranceObject { +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/Objects/LogbookObject.java b/app/src/main/java/h_mal/appttude/com/driver/Objects/LogbookObject.java new file mode 100644 index 0000000..b1722f1 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/Objects/LogbookObject.java @@ -0,0 +1,4 @@ +package h_mal.appttude.com.driver.Objects; + +class LogbookObject { +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/Objects/MotObject.java b/app/src/main/java/h_mal/appttude/com/driver/Objects/MotObject.java new file mode 100644 index 0000000..a4f9ce2 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/Objects/MotObject.java @@ -0,0 +1,4 @@ +package h_mal.appttude.com.driver.Objects; + +public class MotObject { +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/Objects/PrivateHireObject.java b/app/src/main/java/h_mal/appttude/com/driver/Objects/PrivateHireObject.java new file mode 100644 index 0000000..c222ead --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/Objects/PrivateHireObject.java @@ -0,0 +1,29 @@ +package h_mal.appttude.com.driver.Objects; + +public class PrivateHireObject { + + public String phImageString; + public String phNumber; + public String phExpiry; + + public PrivateHireObject() { + } + + public PrivateHireObject(String phImageString, String phNumber, String phExpiry) { + this.phImageString = phImageString; + this.phNumber = phNumber; + this.phExpiry = phExpiry; + } + + public String getPhImageString() { + return phImageString; + } + + public String getPhNumber() { + return phNumber; + } + + public String getPhExpiry() { + return phExpiry; + } +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/Objects/VehicleProfileObject.java b/app/src/main/java/h_mal/appttude/com/driver/Objects/VehicleProfileObject.java new file mode 100644 index 0000000..652a941 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/Objects/VehicleProfileObject.java @@ -0,0 +1,68 @@ +package h_mal.appttude.com.driver.Objects; + +public class VehicleProfileObject { + + public String reg; + public String make; + public String model; + public String colour; + public String keeperName; + public String keeperAddress; + public String keeperPostCode; + public String startDate; + public boolean seized; + public MotObject motObject; + public InsuranceObject insuranceObject; + public LogbookObject logbookObject; + + public VehicleProfileObject() { + } + + public String getReg() { + return reg; + } + + public String getMake() { + return make; + } + + public String getModel() { + return model; + } + + public String getColour() { + return colour; + } + + public String getKeeperName() { + return keeperName; + } + + public String getKeeperAddress() { + return keeperAddress; + } + + public String getKeeperPostCode() { + return keeperPostCode; + } + + public String getStartDate() { + return startDate; + } + + public boolean isSeized() { + return seized; + } + + public MotObject getMotObject() { + return motObject; + } + + public InsuranceObject getInsuranceObject() { + return insuranceObject; + } + + public LogbookObject getLogbookObject() { + return logbookObject; + } +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/PrivateHireLicenseFragment.java b/app/src/main/java/h_mal/appttude/com/driver/PrivateHireLicenseFragment.java new file mode 100644 index 0000000..80ac65f --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/PrivateHireLicenseFragment.java @@ -0,0 +1,222 @@ +package h_mal.appttude.com.driver; + +import android.Manifest; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.ValueEventListener; +import com.squareup.picasso.Picasso; + +import h_mal.appttude.com.driver.Objects.PrivateHireObject; + +import static h_mal.appttude.com.driver.FirebaseClass.*; +import static h_mal.appttude.com.driver.ImageSelectorDialog.CAMERA_REQUEST; +import static h_mal.appttude.com.driver.ImageSelectorDialog.MY_CAMERA_PERMISSION_CODE; +import static h_mal.appttude.com.driver.MainActivity.fragmentManager; +import static h_mal.appttude.com.driver.MainActivity.getDateStamp; +import static h_mal.appttude.com.driver.MainActivity.mDatabase; +import static h_mal.appttude.com.driver.MainActivity.auth; + +public class PrivateHireLicenseFragment extends Fragment { + + private String TAG = this.getClass().getSimpleName(); + + private ImageView imageView; + String fname; + + EditText phNo; + EditText phExpiry; + + public Uri filePath; + + public Uri picUri; + String Ph_numberString; + String Ph_exprString; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_private_hire_license, container, false); + + DatabaseReference reference = mDatabase.child(USER_FIREBASE).child(auth.getCurrentUser().getUid()) + .child(DRIVER_FIREBASE).child(PRIVATE_HIRE_FIREBASE); + + reference.addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot dataSnapshot) { + PrivateHireObject privateHireObject = null; + try{ + privateHireObject = dataSnapshot.getValue(PrivateHireObject.class); + }catch (Exception e){ + Log.e(TAG, "onDataChange: ", e); + }finally { + if (privateHireObject != null){ + picUri = Uri.parse(privateHireObject.getPhImageString()); + Ph_numberString = privateHireObject.getPhNumber(); + Ph_exprString = privateHireObject.getPhExpiry(); + + phNo.setText(Ph_numberString); + phExpiry.setText(Ph_exprString); + Picasso.get() + .load(picUri) + .placeholder(R.mipmap.ic_launcher_round) + .into(imageView); + } + } + + } + + @Override + public void onCancelled(@NonNull DatabaseError databaseError) { + + } + }); + + TextView uploadPH = view.findViewById(R.id.uploadphlic); + imageView = view.findViewById(R.id.imageView2); + + phNo = view.findViewById(R.id.ph_no); + phExpiry = view.findViewById(R.id.ph_expiry); + + phExpiry.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + DateDialog dateDialog = new DateDialog(getContext()); + dateDialog.init(phExpiry); + } + }); + + Button submit = view.findViewById(R.id.submit); + + uploadPH.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ImageSelectorDialog imageSelectorDialog = new ImageSelectorDialog(getContext()); + imageSelectorDialog.setImageName("private_hire"); + imageSelectorDialog.show(); + + } + }); + + submit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Ph_numberString = phNo.getText().toString().trim(); + Ph_exprString = phExpiry.getText().toString().trim(); + + //validation for data then submit + + if (!TextUtils.isEmpty(Ph_numberString) && + !TextUtils.isEmpty(Ph_exprString)){ + if (filePath != null){ + Log.i(TAG, "onClick: new Image uploaded"); + new FirebaseClass(getContext(),filePath,new Response(){ + @Override + public void processFinish(Uri output) { + Log.i(TAG, "processFinish: "); + if (output != null){ + picUri = output; + publishObject(); + fragmentManager.popBackStack(); + } + + } + }).uploadImage(PRIVATE_HIRE_FIREBASE,PRIVATE_HIRE_FIREBASE + getDateStamp()); + }else{ + Log.i(TAG, "onClick: pushing with same image"); + publishObject(); + } + + }else { + if (TextUtils.isEmpty(Ph_numberString)){ + phNo.setError("Field required"); + } + if (TextUtils.isEmpty(Ph_exprString)){ + phExpiry.setError("Field required"); + } + if (picUri == null){ + Toast.makeText(getContext(), getString(R.string.image_required), Toast.LENGTH_SHORT).show(); + } + } + + } + }); + + return view; + } + + private void publishObject(){ + + PrivateHireObject privateHireObject = new PrivateHireObject(picUri.toString(),Ph_numberString,Ph_exprString); + + mDatabase.child(USER_FIREBASE).child(auth.getCurrentUser().getUid()).child(DRIVER_FIREBASE).child(PRIVATE_HIRE_FIREBASE) + .setValue(privateHireObject).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + + Log.i(TAG, "onComplete: publish = " + task.isSuccessful()); + } + }); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (requestCode == MY_CAMERA_PERMISSION_CODE) { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Toast.makeText(getContext(), "camera permission granted", Toast.LENGTH_LONG).show(); + Intent cameraIntent = new + Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); + startActivityForResult(cameraIntent, CAMERA_REQUEST); + } else { + Toast.makeText(getContext(), "camera permission denied", Toast.LENGTH_LONG).show(); + } + + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + new ImageSelectorResults(new ImageSelectorResults.FilepathResponse() { + @Override + public void processFinish(Uri output) { + filePath = output; + } + }).Results(getActivity(),requestCode, resultCode, data, + filePath,imageView); + + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/RegisterActivity.java b/app/src/main/java/h_mal/appttude/com/driver/RegisterActivity.java new file mode 100644 index 0000000..545f391 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/RegisterActivity.java @@ -0,0 +1,89 @@ +package h_mal.appttude.com.driver; + +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; + +public class RegisterActivity extends AppCompatActivity { + + private FirebaseAuth auth; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_register); + + auth = FirebaseAuth.getInstance(); + + final EditText email = findViewById(R.id.email_register); + final EditText passwordTop = findViewById(R.id.password_top); + final EditText passwordBottom = findViewById(R.id.password_bottom); + final ProgressBar progressBar = findViewById(R.id.pb); + Button submit = findViewById(R.id.email_sign_up); + + submit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + String emailText = email.getText().toString().trim(); + String passwordText = passwordTop.getText().toString().trim(); + String passwordTextBottom = passwordBottom.getText().toString().trim(); + + if (TextUtils.isEmpty(emailText)) { + Toast.makeText(getApplicationContext(), "Enter email address!", Toast.LENGTH_SHORT).show(); + email.setError(getString(R.string.error_field_required)); + return; + } + + if (TextUtils.isEmpty(passwordText)) { + Toast.makeText(getApplicationContext(), "Enter password!", Toast.LENGTH_SHORT).show(); + passwordTop.setError(getString(R.string.error_field_required)); + return; + } + + if (TextUtils.isEmpty(passwordTextBottom)) { + Toast.makeText(getApplicationContext(), "Enter password again!", Toast.LENGTH_SHORT).show(); + passwordBottom.setError(getString(R.string.error_field_required)); + return; + } + + if (passwordText.length() < 6) { + passwordTop.setError(getString(R.string.error_invalid_password)); + return; + } + + progressBar.setVisibility(View.VISIBLE); + //create user + auth.createUserWithEmailAndPassword(emailText, passwordText) + .addOnCompleteListener(RegisterActivity.this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Toast.makeText(RegisterActivity.this, "createUserWithEmail:onComplete:" + task.isSuccessful(), Toast.LENGTH_SHORT).show(); + progressBar.setVisibility(View.GONE); + if (!task.isSuccessful()) { + Toast.makeText(RegisterActivity.this, "Authentication failed." + task.getException(), + Toast.LENGTH_SHORT).show(); + } else { + finish(); + } + } + }); + + } + }); + } +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/VehicleSetupFragment.java b/app/src/main/java/h_mal/appttude/com/driver/VehicleSetupFragment.java new file mode 100644 index 0000000..c814f03 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/VehicleSetupFragment.java @@ -0,0 +1,194 @@ +package h_mal.appttude.com.driver; + +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; + +import h_mal.appttude.com.driver.Objects.PrivateHireObject; + +import static h_mal.appttude.com.driver.FirebaseClass.DRIVERS_LICENSE_FIREBASE; +import static h_mal.appttude.com.driver.FirebaseClass.DRIVER_FIREBASE; +import static h_mal.appttude.com.driver.FirebaseClass.PRIVATE_HIRE_FIREBASE; +import static h_mal.appttude.com.driver.FirebaseClass.USER_FIREBASE; +import static h_mal.appttude.com.driver.MainActivity.auth; +import static h_mal.appttude.com.driver.MainActivity.executeFragment; +import static h_mal.appttude.com.driver.MainActivity.fragmentManager; +import static h_mal.appttude.com.driver.MainActivity.getDateStamp; +import static h_mal.appttude.com.driver.MainActivity.mDatabase; + + +public class VehicleSetupFragment extends Fragment { + + private String TAG = this.getClass().getSimpleName(); + + EditText reg; + EditText make; + EditText model; + EditText color; + EditText keeperName; + EditText address; + EditText postcode; + EditText startDate; + CheckBox seized; + TextView mot; + TextView retrievedmot; + TextView insurance; + TextView retrievedIns; + TextView logbook; + TextView logbook_retrieved; + Button Submit; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_vehicle_setup, container, false); + + reg = view.findViewById(R.id.reg); + make = view.findViewById(R.id.make); + model = view.findViewById(R.id.model); + color = view.findViewById(R.id.colour); + keeperName = view.findViewById(R.id.keeper_name); + address = view.findViewById(R.id.address); + postcode = view.findViewById(R.id.postcode); + startDate = view.findViewById(R.id.start_date); + seized = view.findViewById(R.id.seized); + mot = view.findViewById(R.id.mot); + retrievedmot = view.findViewById(R.id.retrievedmot); + insurance = view.findViewById(R.id.insurance); + retrievedIns = view.findViewById(R.id.insurance_retrieved); + logbook = view.findViewById(R.id.log_book); + logbook_retrieved = view.findViewById(R.id.log_book_retrieved); + Submit = view.findViewById(R.id.submit_vehicle); + + initiateViewsFromFb(); + + mot.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + executeFragment(new MotFragment()); + } + }); + + insurance.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + executeFragment(new InsuranceFragment()); + } + }); + + logbook.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + executeFragment(new logbookFragment()); + } + }); + + Submit.setOnClickListener(submitOnClickListener); + + return view; + } + + private void initiateViewsFromFb() { + //todo: retrieve object and set data in fields + } + + View.OnClickListener submitOnClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + //TODO: get strings from views + String regString = reg.getText().toString().trim(); + String makeString = make.getText().toString().trim(); + String modelString = model.getText().toString().trim(); + String colourString = color.getText().toString().trim(); + String keeperNameStrin = keeperName.getText().toString().trim(); + String addressString = address.getText().toString().trim(); + String postcodeString = postcode.getText().toString().trim(); + String driverForename = startDate.getText().toString().trim(); + + //TODO: validate the strings +// if ( !TextUtils.isEmpty(driverForename) && +// !TextUtils.isEmpty(AddressString) && +// !TextUtils.isEmpty(postCodeString) && +// !TextUtils.isEmpty(dobString) && +// !TextUtils.isEmpty(niString) && +// !TextUtils.isEmpty(dateFirstString)){ + +// Log.i(TAG, "onClick: new Image uploaded"); +// new FirebaseClass(getContext(),filePath,new FirebaseClass.Response(){ +// @Override +// public void processFinish(Uri output) { +// Log.i(TAG, "processFinish: "); +// if (output != null){ +// picUri = output; +// writeDriverToDb(); +// fragmentManager.popBackStack(); +// } +// +// } +// }).uploadImage(DRIVERS_LICENSE_FIREBASE,DRIVERS_LICENSE_FIREBASE + getDateStamp()); +// Log.i(TAG, "onClick: pushing with same image"); +// writeDriverToDb(); + + //todo: set error if invalid +// }else { +// if (TextUtils.isEmpty(driverForename)){ +// forenames.setError("Field required"); +// } +// if (TextUtils.isEmpty(AddressString)){ +// address.setError("Field required"); +// } +// if (TextUtils.isEmpty(postCodeString)){ +// postcode.setError("Field required"); +// } +// if (TextUtils.isEmpty(dobString)){ +// dob.setError("Field required"); +// } +// if (TextUtils.isEmpty(niString)){ +// ni.setError("Field required"); +// } +// if (TextUtils.isEmpty(dateFirstString)){ +// dateFirst.setError("Field required"); +// } +// } + + } + + }; + + private void publishObject(){ + //TODO: publish vehicle object +// PrivateHireObject privateHireObject = new PrivateHireObject(picUri.toString(),Ph_numberString,Ph_exprString); +// +// mDatabase.child(USER_FIREBASE).child(auth.getCurrentUser().getUid()).child(DRIVER_FIREBASE).child(PRIVATE_HIRE_FIREBASE) +// .setValue(privateHireObject).addOnCompleteListener(new OnCompleteListener() { +// @Override +// public void onComplete(@NonNull Task task) { +// +// Log.i(TAG, "onComplete: publish = " + task.isSuccessful()); +// } +// }); + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/driverProfileFragment.java b/app/src/main/java/h_mal/appttude/com/driver/driverProfileFragment.java new file mode 100644 index 0000000..c764dde --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/driverProfileFragment.java @@ -0,0 +1,290 @@ +package h_mal.appttude.com.driver; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.ValueEventListener; +import com.squareup.picasso.Picasso; + +import h_mal.appttude.com.driver.Objects.DriverProfileObject; +import h_mal.appttude.com.driver.Objects.DriversLicenseObject; +import h_mal.appttude.com.driver.Objects.PrivateHireObject; + +import static h_mal.appttude.com.driver.FirebaseClass.*; +import static h_mal.appttude.com.driver.MainActivity.auth; +import static h_mal.appttude.com.driver.MainActivity.executeFragment; +import static h_mal.appttude.com.driver.MainActivity.fragmentManager; +import static h_mal.appttude.com.driver.MainActivity.getDateStamp; +import static h_mal.appttude.com.driver.MainActivity.mDatabase; + + +public class driverProfileFragment extends Fragment { + + private String TAG = this.getClass().getSimpleName(); + + ImageView driverPic; + TextView addPic; + EditText forenames; + EditText address; + EditText postcode; + EditText dob; + EditText ni; + TextView privateHire; + TextView retrievedPH; + EditText dateFirst; + TextView driverLi; + TextView retrievedDl; + Button submit_driver; + + Uri filePath; + Uri picUri; + + DatabaseReference driverProfileReference; + + PrivateHireObject privateHireObject; + DriverProfileObject driverProfileObject; + DriversLicenseObject driversLicenseObject; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + driverProfileReference = mDatabase.child(USER_FIREBASE).child(auth.getCurrentUser().getUid()) + .child(DRIVER_FIREBASE); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_driver_profile, container, false); + + driverPic = view.findViewById(R.id.driver_pic); + addPic = view.findViewById(R.id.add_driver_pic); + forenames = view.findViewById(R.id.names); + address = view.findViewById(R.id.address); + postcode = view.findViewById(R.id.postcode); + dob = view.findViewById(R.id.dob); + ni = view.findViewById(R.id.ni_number); + privateHire = view.findViewById(R.id.private_hire); + retrievedPH = view.findViewById(R.id.retrievedPH); + dateFirst = view.findViewById(R.id.date_first); + driverLi = view.findViewById(R.id.drivers_li); + retrievedDl = view.findViewById(R.id.retrieved_dl); + submit_driver = view.findViewById(R.id.submit_driver); + + driverPic.setVisibility(View.GONE); + + driverProfileReference.addListenerForSingleValueEvent(valueEventListener); + + addPic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ImageSelectorDialog imageSelectorDialog = new ImageSelectorDialog(getContext()); + imageSelectorDialog.setImageName("driver_pic"+getDateStamp()); + imageSelectorDialog.show(); + } + }); + + privateHire.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + executeFragment(new PrivateHireLicenseFragment()); + } + }); + + driverLi.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + executeFragment(new DriverLicenseFragment()); + } + }); + + dob.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + DateDialog dateDialog = new DateDialog(getContext()); + dateDialog.init(dob); + } + }); + + dateFirst.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + DateDialog dateDialog = new DateDialog(getContext()); + dateDialog.init(dateFirst); + } + }); + + submit_driver.setOnClickListener(submitOnClickListener); + + + return view; + } + + ValueEventListener valueEventListener = new ValueEventListener(){ + + @Override + public void onDataChange(@NonNull DataSnapshot dataSnapshot) { + try{ + privateHireObject = dataSnapshot.child(PRIVATE_HIRE_FIREBASE).getValue(PrivateHireObject.class); + }catch (Exception e){ + Log.e(TAG, "onDataChange: ", e); + }finally { + if (privateHireObject != null){ + + retrievedPH.setText("Private Hire License no.: " +privateHireObject.getPhNumber() + +"\nPrivate Hire License expiry: " + privateHireObject.getPhExpiry()); + } + } + + try { + driverProfileObject = dataSnapshot.child(DRIVER_DETAILS_FIREBASE).getValue(DriverProfileObject.class); + }catch (Exception e){ + Log.e(TAG, "onDataChange: ", e); + }finally { + if (driverProfileObject != null){ + forenames.setText(driverProfileObject.getForenames()); + address.setText(driverProfileObject.getAddress()); + postcode.setText(driverProfileObject.getPostcode()); + dob.setText(driverProfileObject.getDob()); + dateFirst.setText(driverProfileObject.getDateFirst()); + ni.setText(driverProfileObject.getNi()); + driverPic.setVisibility(View.VISIBLE); + Picasso.get().load(driverProfileObject.getDriverPic()).into(driverPic); + picUri = Uri.parse(driverProfileObject.getDriverPic()); + + }else { + driverPic.setVisibility(View.GONE); + } + } + + try{ + driversLicenseObject = dataSnapshot.child(DRIVERS_LICENSE_FIREBASE).getValue(DriversLicenseObject.class); + }catch (Exception e){ + Log.e(TAG, "onDataChange: ", e); + }finally { + if (driversLicenseObject != null){ + retrievedDl.setText("Driving License no.: " +driversLicenseObject.getLicenseNumber() + +"\nDriving License expiry: " + driversLicenseObject.getLicenseExpiry()); + } + } + } + + @Override + public void onCancelled(@NonNull DatabaseError databaseError) { + + } + }; + + View.OnClickListener submitOnClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + String driverForename = forenames.getText().toString().trim(); + String AddressString = address.getText().toString().trim(); + String postCodeString = postcode.getText().toString().trim(); + String dobString = dob.getText().toString().trim(); + String niString = ni.getText().toString().trim(); + String dateFirstString = dateFirst.getText().toString().trim(); + + if ( !TextUtils.isEmpty(driverForename) && + !TextUtils.isEmpty(AddressString) && + !TextUtils.isEmpty(postCodeString) && + !TextUtils.isEmpty(dobString) && + !TextUtils.isEmpty(niString) && + !TextUtils.isEmpty(dateFirstString)){ + if (filePath != null){ + Log.i(TAG, "onClick: new Image uploaded"); + new FirebaseClass(getContext(),filePath,new FirebaseClass.Response(){ + @Override + public void processFinish(Uri output) { + Log.i(TAG, "processFinish: "); + if (output != null){ + picUri = output; + writeDriverToDb(); + fragmentManager.popBackStack(); + } + + } + }).uploadImage(DRIVERS_LICENSE_FIREBASE,DRIVERS_LICENSE_FIREBASE + getDateStamp()); + }else{ + Log.i(TAG, "onClick: pushing with same image"); + writeDriverToDb(); + } + + }else { + if (TextUtils.isEmpty(driverForename)){ + forenames.setError("Field required"); + } + if (TextUtils.isEmpty(AddressString)){ + address.setError("Field required"); + } + if (TextUtils.isEmpty(postCodeString)){ + postcode.setError("Field required"); + } + if (TextUtils.isEmpty(dobString)){ + dob.setError("Field required"); + } + if (TextUtils.isEmpty(niString)){ + ni.setError("Field required"); + } + if (TextUtils.isEmpty(dateFirstString)){ + dateFirst.setError("Field required"); + } + if (picUri == null){ + Toast.makeText(getContext(), getString(R.string.image_required), Toast.LENGTH_SHORT).show(); + } + } + + } + + }; + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + new ImageSelectorResults(new ImageSelectorResults.FilepathResponse() { + @Override + public void processFinish(Uri output) { + filePath = output; + } + }).Results(getActivity(),requestCode, resultCode, data, + filePath,driverPic); + driverPic.setVisibility(View.VISIBLE); + + } + + private void writeDriverToDb(){ + + String forenameText = forenames.getText().toString().trim(); + String addressText = address.getText().toString().trim(); + String postcodeText = postcode.getText().toString().trim(); + String dobText = dob.getText().toString().trim(); + String niText = ni.getText().toString().trim(); + String datefirstText = dateFirst.getText().toString().trim(); + + DriverProfileObject driverProfileObject = new DriverProfileObject(picUri.toString(),forenameText, + addressText,postcodeText,dobText,niText,datefirstText); + + driverProfileReference.child(DRIVER_DETAILS_FIREBASE).setValue(driverProfileObject); + } +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/homeFragment.java b/app/src/main/java/h_mal/appttude/com/driver/homeFragment.java new file mode 100644 index 0000000..29e3a89 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/homeFragment.java @@ -0,0 +1,55 @@ +package h_mal.appttude.com.driver; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.widget.CardView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import static h_mal.appttude.com.driver.MainActivity.auth; +import static h_mal.appttude.com.driver.MainActivity.executeFragment; +import static h_mal.appttude.com.driver.MainActivity.fragmentManager; + + +public class homeFragment extends Fragment { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_home, container, false); + + Button button = view.findViewById(R.id.driver); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + executeFragment(new driverProfileFragment()); + } + }); + + CardView second= view.findViewById(R.id.car); + second.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + executeFragment(new VehicleSetupFragment()); + } + }); + + return view; + } + + + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/logbookFragment.java b/app/src/main/java/h_mal/appttude/com/driver/logbookFragment.java new file mode 100644 index 0000000..9b17243 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/logbookFragment.java @@ -0,0 +1,31 @@ +package h_mal.appttude.com.driver; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + + +public class logbookFragment extends Fragment { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_logbook, container, false); + + + + return view; + } + +} diff --git a/app/src/main/java/h_mal/appttude/com/driver/profileFragment.java b/app/src/main/java/h_mal/appttude/com/driver/profileFragment.java new file mode 100644 index 0000000..943cb15 --- /dev/null +++ b/app/src/main/java/h_mal/appttude/com/driver/profileFragment.java @@ -0,0 +1,257 @@ +package h_mal.appttude.com.driver; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.design.widget.NavigationView; +import android.support.v4.app.Fragment; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.tasks.Continuation; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.auth.UserProfileChangeRequest; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.OnProgressListener; +import com.google.firebase.storage.StorageReference; +import com.google.firebase.storage.UploadTask; +import com.squareup.picasso.Picasso; + +import java.io.IOException; +import java.util.UUID; + +import static android.app.Activity.RESULT_OK; +import static h_mal.appttude.com.driver.MainActivity.auth; +import static h_mal.appttude.com.driver.MainActivity.fragmentManager; +import static h_mal.appttude.com.driver.MainActivity.setupDrawer; + +public class profileFragment extends Fragment { + + private String TAG = this.getClass().getSimpleName(); + private final int PICK_IMAGE_REQUEST = 70; + + private ImageView imageView; + private EditText email; + private EditText name; + + FirebaseStorage storage; + StorageReference storageReference; + + private FirebaseUser user; + + private Uri filePath; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + user = auth.getCurrentUser(); + storage = FirebaseStorage.getInstance(); + storageReference = storage.getReference(); + + setRetainInstance(true); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_profile, container, false); + + imageView = view.findViewById(R.id.profile_pic); + email = view.findViewById(R.id.profile_email); + name = view.findViewById(R.id.profile_name); + + TextView upload = view.findViewById(R.id.uploadprofilepic); + + upload.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + chooseImage(); + } + }); + + retrieveProfile(); + + Button button = view.findViewById(R.id.submit_profile); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + updateProfile(); + } + }); + + return view; + } + + public void retrieveProfile(){ + email.setText(user.getEmail()); + if (user.getDisplayName() != null){ + name.setText(user.getDisplayName()); + } + + if(imageView != null){ + Picasso.get() + .load(user.getPhotoUrl()) + .placeholder(R.mipmap.ic_launcher_round) + .into(imageView); + } + + } + + private void updateProfile(){ + UserProfileChangeRequest.Builder profileUpdatesBuilder = new UserProfileChangeRequest.Builder(); + + String profileName = name.getText().toString().trim(); + + + if (!TextUtils.isEmpty(profileName)){ + profileUpdatesBuilder.setDisplayName(profileName); + } + if (filePath != null || + imageView.getDrawable().getConstantState() != getResources().getDrawable( R.mipmap.ic_launcher_round).getConstantState()){ + profileUpdatesBuilder.setPhotoUri(filePath); + } + + UserProfileChangeRequest profileUpdates = profileUpdatesBuilder.build(); + + user.updateProfile(profileUpdates) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + Log.d(TAG, "User profile updated."); + setupDrawer(); + fragmentManager.popBackStack(); + } + } + }) + .addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Toast.makeText(getContext(), "Update Failed", Toast.LENGTH_SHORT).show(); + } + }); + } + + private void uploadImage() { + + if(filePath != null) + { + final ProgressDialog progressDialog = new ProgressDialog(getContext()); + progressDialog.setTitle("Uploading..."); + progressDialog.show(); + + final StorageReference ref = storageReference.child("images/"+ user.getUid() + "/profile_pic"); + UploadTask uploadTask = ref.putFile(filePath); + + uploadTask.addOnProgressListener(new OnProgressListener() { + @Override + public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { + double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot + .getTotalByteCount()); + progressDialog.setMessage("Uploaded "+(int)progress+"%"); + } + }).continueWithTask(new Continuation>() { + @Override + public Task then(@NonNull Task task) throws Exception { + if (!task.isSuccessful()) { + throw task.getException(); + } + + // Continue with the task to get the download URL + return ref.getDownloadUrl(); + } + }).addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + filePath = task.getResult(); + progressDialog.dismiss(); + Toast.makeText(getContext(), "Uploaded Successfully", Toast.LENGTH_SHORT).show(); + Log.i(TAG, "onComplete: uploaded Successful uri: " + task.getResult()); + } else { + progressDialog.dismiss(); + Toast.makeText(getContext(), "Failed to upload", Toast.LENGTH_SHORT).show(); + Log.i(TAG, "onComplete: failed to get url"); + } + } + }); + +// uploadTask.addOnSuccessListener(new OnSuccessListener() { +// @Override +// public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { +// +// } +// }) +// .addOnFailureListener(new OnFailureListener() { +// @Override +// public void onFailure(@NonNull Exception e) { +// +// } +// }) +// .addOnProgressListener(new OnProgressListener() { +// @Override +// public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { +// double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot +// .getTotalByteCount()); +// progressDialog.setMessage("Uploaded "+(int)progress+"%"); +// } +// }); + + + } + } + + private void chooseImage() { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK + && data != null && data.getData() != null ) + { + filePath = data.getData(); + Bitmap bitmap = null; + try { + bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), filePath); + imageView.setImageBitmap(bitmap); + } + catch (IOException e) + { + e.printStackTrace(); + } + finally { + if (bitmap != null){ + uploadImage(); + } + } + } + } + +} diff --git a/app/src/main/res/drawable-v21/cardviewoutline.xml b/app/src/main/res/drawable-v21/cardviewoutline.xml new file mode 100644 index 0000000..d2640f1 --- /dev/null +++ b/app/src/main/res/drawable-v21/cardviewoutline.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v21/cars.jpg b/app/src/main/res/drawable-v21/cars.jpg new file mode 100644 index 0000000..e0d291a Binary files /dev/null and b/app/src/main/res/drawable-v21/cars.jpg differ diff --git a/app/src/main/res/drawable-v21/gradient_colour.xml b/app/src/main/res/drawable-v21/gradient_colour.xml new file mode 100644 index 0000000..6037c6c --- /dev/null +++ b/app/src/main/res/drawable-v21/gradient_colour.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v21/ic_menu_camera.xml b/app/src/main/res/drawable-v21/ic_menu_camera.xml new file mode 100644 index 0000000..634fe92 --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_menu_camera.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable-v21/ic_menu_gallery.xml b/app/src/main/res/drawable-v21/ic_menu_gallery.xml new file mode 100644 index 0000000..03c7709 --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_menu_gallery.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-v21/ic_menu_manage.xml b/app/src/main/res/drawable-v21/ic_menu_manage.xml new file mode 100644 index 0000000..aeb047d --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_menu_manage.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v21/ic_menu_send.xml b/app/src/main/res/drawable-v21/ic_menu_send.xml new file mode 100644 index 0000000..fdf1c90 --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_menu_send.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-v21/ic_menu_share.xml b/app/src/main/res/drawable-v21/ic_menu_share.xml new file mode 100644 index 0000000..338d95a --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_menu_share.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-v21/ic_menu_slideshow.xml b/app/src/main/res/drawable-v21/ic_menu_slideshow.xml new file mode 100644 index 0000000..5e9e163 --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_menu_slideshow.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-v21/round_edit_text.xml b/app/src/main/res/drawable-v21/round_edit_text.xml new file mode 100644 index 0000000..fa2415d --- /dev/null +++ b/app/src/main/res/drawable-v21/round_edit_text.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable-xxhdpi/background.jpg b/app/src/main/res/drawable-xxhdpi/background.jpg new file mode 100644 index 0000000..71d558d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/background.jpg differ diff --git a/app/src/main/res/drawable-xxhdpi/bg.jpg b/app/src/main/res/drawable-xxhdpi/bg.jpg new file mode 100644 index 0000000..3477474 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg.jpg differ diff --git a/app/src/main/res/drawable-xxhdpi/cars.jpg b/app/src/main/res/drawable-xxhdpi/cars.jpg new file mode 100644 index 0000000..e0d291a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/cars.jpg differ diff --git a/app/src/main/res/drawable/background.jpg b/app/src/main/res/drawable/background.jpg new file mode 100644 index 0000000..61809d0 Binary files /dev/null and b/app/src/main/res/drawable/background.jpg differ diff --git a/app/src/main/res/drawable/cars.jpg b/app/src/main/res/drawable/cars.jpg new file mode 100644 index 0000000..e0d291a Binary files /dev/null and b/app/src/main/res/drawable/cars.jpg differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml new file mode 100644 index 0000000..3777d1b --- /dev/null +++ b/app/src/main/res/drawable/side_nav_bar.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_image_selector.xml b/app/src/main/res/layout/activity_image_selector.xml new file mode 100644 index 0000000..71cb80f --- /dev/null +++ b/app/src/main/res/layout/activity_image_selector.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..2e1cb83 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +