Commit 14a31d8d authored by Lucas Braz Cunha's avatar Lucas Braz Cunha
Browse files

AGILE#295: First login on mobile checks for existence of user's e-mail


Signed-off-by: Lucas Braz Cunha's avatarLucas B. Cunha <lbc16@inf.ufpr.br>
parent da5258bb
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" /> android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application <application
android:allowBackup="false" android:allowBackup="false"
...@@ -48,7 +47,6 @@ ...@@ -48,7 +47,6 @@
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" /> <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter> </intent-filter>
</service> </service>
<service <service
android:name=".services.notification.NotificationReadService" android:name=".services.notification.NotificationReadService"
android:exported="false" android:exported="false"
...@@ -57,7 +55,6 @@ ...@@ -57,7 +55,6 @@
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" /> <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter> </intent-filter>
</service> </service>
<service <service
android:name=".services.notification.NotificationsListService" android:name=".services.notification.NotificationsListService"
android:exported="false" android:exported="false"
...@@ -67,18 +64,15 @@ ...@@ -67,18 +64,15 @@
</intent-filter> </intent-filter>
</service> </service>
<receiver android:name=".services.BootReceiver"> <receiver android:name=".services.BootReceiver">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".services.notification.NotificationReceiver"></receiver>
<receiver android:name=".services.notification.NotificationReceiver">
</receiver>
<activity android:name=".TermActivity" /> <activity android:name=".TermActivity" />
<activity android:name=".SchedulingActivity"/> <activity android:name=".SchedulingActivity" />
<activity android:name=".CitizenListActivity" /> <activity android:name=".CitizenListActivity" />
<activity android:name=".SchedulesActivity" /> <activity android:name=".SchedulesActivity" />
<activity android:name=".ScheduleConfirmationActivity" /> <activity android:name=".ScheduleConfirmationActivity" />
...@@ -88,10 +82,7 @@ ...@@ -88,10 +82,7 @@
<activity android:name=".RetrievalSuccessActivity" /> <activity android:name=".RetrievalSuccessActivity" />
<activity android:name=".SchedulesHistoryActivity" /> <activity android:name=".SchedulesHistoryActivity" />
<activity android:name=".ScheduleInfoActivity" /> <activity android:name=".ScheduleInfoActivity" />
<activity android:name=".EmailActivity"></activity>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package br.ufpr.c3sl.agendador.agendador;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import org.w3c.dom.Text;
import br.ufpr.c3sl.agendador.agendador.helpers.ConnectionErrorDialog;
import br.ufpr.c3sl.agendador.agendador.helpers.DateValidator;
import br.ufpr.c3sl.agendador.agendador.helpers.Utils;
import br.ufpr.c3sl.agendador.agendador.models.AccountUpdate;
import br.ufpr.c3sl.agendador.agendador.models.UserData;
import br.ufpr.c3sl.agendador.agendador.models.UserOutput;
import br.ufpr.c3sl.agendador.agendador.presenters.EmailActPresenter;
import br.ufpr.c3sl.agendador.agendador.presenters.PresenterManager;
import br.ufpr.c3sl.agendador.agendador.views.EmailActView;
public class EmailActivity extends AppCompatActivity implements EmailActView {
private EditText et_email;
private TextView tv_emailAlert;
private EmailActPresenter presenter;
private ProgressBar pb_emailAct;
private ConnectionErrorDialog dg_connection_error;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
presenter = new EmailActPresenter(this);
} else {
presenter = PresenterManager.getInstance().restorePresenter(savedInstanceState);
if (presenter == null)
presenter = new EmailActPresenter(this);
}
setContentView(R.layout.activity_email);
et_email = (EditText) findViewById(R.id.et_emailact_email);
tv_emailAlert = (TextView) findViewById(R.id.tv_emailact_invalid_email);
ImageView bt_confirm = (ImageView) findViewById(R.id.btn_emailact_send);
bt_confirm.setClickable(true);
bt_confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (DateValidator.isValidEmail(et_email.getText().toString())) {
tv_emailAlert.setVisibility(View.INVISIBLE);
UserData usrData = new UserData(et_email.getText().toString());
AccountUpdate update = new AccountUpdate(usrData, null, null, null);
presenter.updateEmail(update);
} else {
tv_emailAlert.setVisibility(View.VISIBLE);
et_email.setError(getString(R.string.invalid_email));
}
}
});
pb_emailAct = (ProgressBar) findViewById(R.id.pb_emailact);
}
@Override
protected void onResume() {
super.onResume();
presenter.bindView(this);
}
@Override
protected void onStop() {
super.onStop();
presenter.unbindView();
}
@Override
public void onSaveInstanceState(Bundle outState) {
PresenterManager.getInstance().savePresenter(presenter, outState);
super.onSaveInstanceState(outState);
}
public void onSuccessfulUpdate() {
Intent data = new Intent();
data.putExtra(Utils.EMAIL, et_email.getText().toString());
setResult(RESULT_OK, data);
finish();
}
public void onRequestFail() {
if (dg_connection_error == null) {
dg_connection_error = new ConnectionErrorDialog();
}
Bundle bundle = new Bundle();
bundle.putString(ConnectionErrorDialog.DIALOG_MESSAGE, getString(R.string.dialog_connection_error_message));
dg_connection_error.setArguments(bundle);
dg_connection_error.show(getFragmentManager(), ConnectionErrorDialog.DIALOG_CONNECTION_ERROR);
}
public void onServerError() {
if (dg_connection_error == null) {
dg_connection_error = new ConnectionErrorDialog();
}
Bundle bundle = new Bundle();
bundle.putString(ConnectionErrorDialog.DIALOG_MESSAGE, getString(R.string.dialog_no_connection_message));
dg_connection_error.setArguments(bundle);
dg_connection_error.show(getFragmentManager(), ConnectionErrorDialog.DIALOG_CONNECTION_ERROR);
}
@Override
public void showProgressBar(boolean show) {
if (show) {
pb_emailAct.setVisibility(View.VISIBLE);
} else {
pb_emailAct.setVisibility(View.INVISIBLE);
}
}
}
...@@ -181,12 +181,6 @@ public class HomeActivity extends AppCompatActivity implements HomeView, ...@@ -181,12 +181,6 @@ public class HomeActivity extends AppCompatActivity implements HomeView,
showSnackBar(getIntent()); showSnackBar(getIntent());
/*
Notification notification = new Notification(1, "2017-12-18T10:10:00.000-0200", false, "Alo Alo", "a@a.c", false);
Log.d("Agendador", "Criando notificação");
LocalNotificationManager.createLocalNotification(this, notification, osb, new Gson());
*/
} }
@TargetApi(23) @TargetApi(23)
......
...@@ -55,6 +55,8 @@ public class LoginActivity extends AppCompatActivity implements LoginView { ...@@ -55,6 +55,8 @@ public class LoginActivity extends AppCompatActivity implements LoginView {
private ConnectionErrorDialog dg_connection_error; private ConnectionErrorDialog dg_connection_error;
private static final int REQUEST_EMAIL_CODE = 1;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
...@@ -214,16 +216,43 @@ public class LoginActivity extends AppCompatActivity implements LoginView { ...@@ -214,16 +216,43 @@ public class LoginActivity extends AppCompatActivity implements LoginView {
} }
@Override @Override
public void afterSuccessfulLogin() { public void afterSuccessfulLogin(boolean needEmail) {
Intent intent;
if(needEmail){
intent = new Intent(LoginActivity.this, EmailActivity.class);
startActivityForResult(intent, REQUEST_EMAIL_CODE);
}else{
presenter.createServiceLocalNotificationsList();
intent = new Intent(LoginActivity.this, HomeActivity.class);
startActivity(intent);
finish();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Intent intent;
if(requestCode == REQUEST_EMAIL_CODE){
if(resultCode == RESULT_OK && data.getStringExtra(Utils.EMAIL) != null){
presenter.updateEmail(data.getStringExtra(Utils.EMAIL));
presenter.createServiceLocalNotificationsList();
intent = new Intent(LoginActivity.this, HomeActivity.class);
startActivity(intent);
finish();
}else if(resultCode == RESULT_CANCELED) {
Toast.makeText(this, getString(R.string.loginact_email_error), Toast.LENGTH_LONG).show();
presenter.cancelLogin();
et_cpf.requestFocus();
et_cpf.setText("");
et_password.setText("");
}
}
presenter.createServiceLocalNotificationsList();
Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
startActivity(intent);
finish();
} }
@Override @Override
public void afterSuccessfulPhoto(Bitmap bitmap, long id){ public void afterSuccessfulPhoto(Bitmap bitmap, long id, boolean needEmail){
// TODO: 17/04/17 user messages & error warning // TODO: 17/04/17 user messages & error warning
UserImgHelper userImgHelper = new UserImgHelper(getBaseContext()); UserImgHelper userImgHelper = new UserImgHelper(getBaseContext());
...@@ -233,7 +262,7 @@ public class LoginActivity extends AppCompatActivity implements LoginView { ...@@ -233,7 +262,7 @@ public class LoginActivity extends AppCompatActivity implements LoginView {
Toast.makeText(this, "Ocorreu um problema ao atualizar sua foto de perfil", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Ocorreu um problema ao atualizar sua foto de perfil", Toast.LENGTH_SHORT).show();
e.printStackTrace(); e.printStackTrace();
} }
afterSuccessfulLogin(); afterSuccessfulLogin(needEmail);
} }
private class LoginChangeListener implements TextWatcher { private class LoginChangeListener implements TextWatcher {
......
...@@ -156,6 +156,8 @@ public abstract class Utils { ...@@ -156,6 +156,8 @@ public abstract class Utils {
return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
} }
*/ */
// Converting File to Base64.encode String type using Method // Converting File to Base64.encode String type using Method
public static String getBase64FromFile(String absolutePath) { public static String getBase64FromFile(String absolutePath) {
InputStream inputStream = null; InputStream inputStream = null;
......
...@@ -48,6 +48,10 @@ public class UserData { ...@@ -48,6 +48,10 @@ public class UserData {
@SerializedName("image") @SerializedName("image")
private Image mImage; private Image mImage;
public UserData(String email){
this.mEmail = email;
}
public UserData(Map<String, String> values) { public UserData(Map<String, String> values) {
this.mAddress_Number = values.get(Utils.ADDRESS_NUMBER); this.mAddress_Number = values.get(Utils.ADDRESS_NUMBER);
this.mRg = values.get(Utils.RG); this.mRg = values.get(Utils.RG);
......
...@@ -317,4 +317,7 @@ public class UserOutput implements Parcelable { ...@@ -317,4 +317,7 @@ public class UserOutput implements Parcelable {
public String getmCep() { public String getmCep() {
return mCep; return mCep;
} }
} }
package br.ufpr.c3sl.agendador.agendador.presenters;
import android.content.Context;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import br.ufpr.c3sl.agendador.agendador.helpers.ObscuredSharedPreferences;
import br.ufpr.c3sl.agendador.agendador.helpers.Utils;
import br.ufpr.c3sl.agendador.agendador.models.AccountOutput;
import br.ufpr.c3sl.agendador.agendador.models.AccountUpdate;
import br.ufpr.c3sl.agendador.agendador.network.ApiEndpoints;
import br.ufpr.c3sl.agendador.agendador.network.ApiUtils;
import br.ufpr.c3sl.agendador.agendador.views.EmailActView;
import okhttp3.Headers;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by Lucas Braz Cunha on 29/01/18.
*/
public class EmailActPresenter extends BasePresenter<EmailActView>{
private EmailActPresenter presenter;
@Override
protected void updateView() {
}
public EmailActPresenter(Context context) {
this.context = context;
this.presenter = this;
this.osb = ObscuredSharedPreferences.getPrefs(context, "Agendador", Context.MODE_PRIVATE);
}
public void updateEmail(AccountUpdate accountUpdate){
presenter.view().showProgressBar(true);
Map<String, String> header = new HashMap<>();
header.put("Content-Type", "application/json");
header.put(Utils.ACCESS_TOKEN, osb.getString(Utils.ACCESS_TOKEN, null));
header.put(Utils.CLIENT, osb.getString(Utils.CLIENT, null));
header.put(Utils.UID, osb.getString(Utils.UID, null));
ApiEndpoints service = ApiUtils.request(header);
Call<AccountOutput> listCall = service.update(accountUpdate);
listCall.enqueue(new Callback<AccountOutput>() {
@Override
public void onResponse(Call<AccountOutput> call, Response<AccountOutput> response) {
Headers headers = response.headers();
int status = response.code();
presenter.updateHeaders(headers);
presenter.view().showProgressBar(false);
switch (status) {
case 200:
Log.v("Server response", this.getClass().getName() + ": 200 - Sucesso!");
presenter.view().onSuccessfulUpdate();
break;
default:
Log.e("Server response", this.getClass().getName() + ": " + status + " - Falha!");
presenter.view().onServerError();
break;
}
}
@Override
public void onFailure(Call<AccountOutput> call, Throwable t) {
Log.e("Server response", this.getClass().getName() + ": Sem conexão!");
presenter.view().showProgressBar(false);
presenter.view().onRequestFail();
}
});
}
}
...@@ -104,8 +104,16 @@ public class LoginPresenter extends BasePresenter<LoginView> { ...@@ -104,8 +104,16 @@ public class LoginPresenter extends BasePresenter<LoginView> {
break; break;
case 200: case 200:
Log.d("Login Request", "Voltou 200!!!"); Log.d("Login Request", "Voltou 200!!!");
boolean needEmail = false;
if(accountOutput.getCitizen().getmEmail() == null){
//cadastrar e-mail para o usuário.
needEmail = true;
}else if(accountOutput.getCitizen().getmEmail().equals("")) {
//cadastrar e-mail para o usuário.
needEmail = true;
}
onSuccessfulLogin(accountOutput, headers); onSuccessfulLogin(accountOutput, headers);
checkLocalPhoto(); checkLocalPhoto(needEmail);
break; break;
default: default:
Log.d("Login Request", "Voltou " + status + "!!!"); Log.d("Login Request", "Voltou " + status + "!!!");
...@@ -125,7 +133,7 @@ public class LoginPresenter extends BasePresenter<LoginView> { ...@@ -125,7 +133,7 @@ public class LoginPresenter extends BasePresenter<LoginView> {
} }
private void requestImage() { private void requestImage(final boolean needEmail) {
Map<String, String> header = new HashMap<>(); Map<String, String> header = new HashMap<>();
final String uid = osb.getString(Utils.UID, null); final String uid = osb.getString(Utils.UID, null);
header.put(Utils.ACCESS_TOKEN, osb.getString(Utils.ACCESS_TOKEN, null)); header.put(Utils.ACCESS_TOKEN, osb.getString(Utils.ACCESS_TOKEN, null));
...@@ -142,26 +150,27 @@ public class LoginPresenter extends BasePresenter<LoginView> { ...@@ -142,26 +150,27 @@ public class LoginPresenter extends BasePresenter<LoginView> {
@Override @Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
int status = response.code(); int status = response.code();
Log.d("Server response", this.getClass().getName() + ": Retorno da request de imagem: " + status); Log.d("Server response", this.getClass().getName() + ": Retorno da request de imagem: " + status);
switch (status) { switch (status) {
case 500: case 500:
loginPresenter.view().setProgressBar(false); loginPresenter.view().setProgressBar(false);
loginPresenter.view().afterSuccessfulLogin(); loginPresenter.view().afterSuccessfulLogin(needEmail);
break; break;
case 200: case 200:
loginPresenter.view().afterSuccessfulPhoto(BitmapFactory.decodeStream(response.body().byteStream()), osb.getLong(Utils.ID, 0)); loginPresenter.view().afterSuccessfulPhoto(BitmapFactory.decodeStream(response.body().byteStream()), osb.getLong(Utils.ID, 0), needEmail);
loginPresenter.view().setProgressBar(false); loginPresenter.view().setProgressBar(false);
break; break;
case 404: case 404:
//user has no picture on back-end side //user has no picture on back-end side
loginPresenter.view().setProgressBar(false); loginPresenter.view().setProgressBar(false);
loginPresenter.view().afterSuccessfulLogin(); loginPresenter.view().afterSuccessfulLogin(needEmail);
break; break;
default: default:
break; break;
} }
} }
@Override @Override
public void onFailure(Call<ResponseBody> call, Throwable t) { public void onFailure(Call<ResponseBody> call, Throwable t) {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
...@@ -169,7 +178,7 @@ public class LoginPresenter extends BasePresenter<LoginView> { ...@@ -169,7 +178,7 @@ public class LoginPresenter extends BasePresenter<LoginView> {
extras.putString(Utils.JOB_FILE_NAME, Utils.USR_PICT_FILE_NAME); extras.putString(Utils.JOB_FILE_NAME, Utils.USR_PICT_FILE_NAME);
Job job = dispatcher.newJobBuilder() Job job = dispatcher.newJobBuilder()
.setService(ImageUpdateService.class) .setService(ImageUpdateService.class)
.setTag(Utils.SERVICE_UPDATE_IMAGE) .setTag(Utils.SERVICE_UPDATE_IMAGE)
//time the function gets is in seconds, 60s = 1 minutes, 1 hour = 3600 //time the function gets is in seconds, 60s = 1 minutes, 1 hour = 3600
...@@ -182,13 +191,13 @@ public class LoginPresenter extends BasePresenter<LoginView> { ...@@ -182,13 +191,13 @@ public class LoginPresenter extends BasePresenter<LoginView> {
Constraint.ON_ANY_NETWORK Constraint.ON_ANY_NETWORK
) )
.setExtras(extras) .setExtras(extras)
//if device is rebooted the job will be restarted //if device is rebooted the job will be restarted
.setLifetime(Lifetime.FOREVER) .setLifetime(Lifetime.FOREVER)
.build(); .build();
dispatcher.mustSchedule(job); dispatcher.mustSchedule(job);
loginPresenter.view().setProgressBar(false); loginPresenter.view().setProgressBar(false);
loginPresenter.view().afterSuccessfulLogin(); loginPresenter.view().afterSuccessfulLogin(needEmail);
} }
}); });
...@@ -196,8 +205,7 @@ public class LoginPresenter extends BasePresenter<LoginView> { ...@@ -196,8 +205,7 @@ public class LoginPresenter extends BasePresenter<LoginView> {
} }
public void createServiceLocalNotificationsList() {
public void createServiceLocalNotificationsList(){