Membuat Halaman Login dan Update User Info Rainbow Android Apps – Pada tutorial sebelumnya kita sudah belajar bagaimana cara mengintegrasikan Rainbow API pada Android Apps. Nah kali ini saatnya kita belajar cara membuat halaman login dan mengupdate user info Rainbow pada Android.
Bedanya, kali ini kita tidak menggunakan Android SDK melainkan Rainbow Rest API. Lhoo ? Rainbow Rest API merupakan API berbasis metode HTTP. Kelebihannya, ia dapat membantu mengembangkan Aplikasi agar terhubung dengan layanan yang tersedia menggunakan berbagai bahasa pemrograman.
Apa yang ditawarkan Rainbow Rest APIs ?
Platform Rainbow menawarkan sebuah API untuk membantu perusahaan yang ingin terintegrasi dengan layanan yang disediakan Rainbow. Dalam hal ini mengintegrasikan dengan SDK sedikit sulit jika ingin menggunakan API secara langsung.
💻 Mulai Belajar Pemrograman
Belajar pemrograman di Dicoding Academy dan mulai perjalanan Anda sebagai developer profesional.
Daftar SekarangDi sinilah Rainbow Rest API berfungsi. Ia memungkinkan sebuah perusahaan, Integrator, TI, Mitra Bisnis & Administrator untuk dapat menghubungkan layanan yang dimiliki Rainbow ke server back-end mereka (Integrasi B2B). Tujuannya adalah untuk mengotomatisasi tugas seperti pembuatan akun dan menerapkan sistem PBX kealaman situs.
Bagaimana cara mengakses Rainbow Rest API ?
Dalam mengakses Rainbow Rest API terdapat dua cara, yaitu :
- Jika ingin terhubung dengan Rainbow Developer Sandboxed Platform, gunakan endpoint https://sandbox.openrainbow.com.
- Jika ingin terhubung dengan Rainbow Official Platform, gunakan endpoint https://openrainbow.com.
Menggunakan Rest API pada Rainbow Developer Sandboxed
Terdapat beberapa batasan penggunaan Rest API yang terhubung pada Rainbow Developer Sandboxed seperti berikut :
- Subscriptions API
- Offers API
- Quotations API
- Invoices API
- Payments API
Semua API kecuali yang sudah disebutkan, bisa digunakan tergantung hak akses pengguna yang ingin request (meminta) akses Rest API. Di sini pembatasan akses pengguna bisa berlaku. Contoh : pengguna tidak dapat mengaitkan sebuah perusahaan dengan suatu organisasi jika pengguna bukan admin dari organisasi tersebut.
Menggunakan Rest API pada Rainbow Official Platform
Tidak ada batasan akses Rest API pada Rainbow Official Platform. Semua API dapat digunakan tergantung hak akses pengguna yang ingin request (meminta) akses Rest API. Dalam hal ini, pembatasan akses pengguna bisa berlaku. Contohnya pengguna tidak dapat mengaitkan sebuah perusahaan dengan suatu organisasi jika pengguna bukan admin dari organisasi tersebut.
Pembuatan Project
Pada project kali ini kita menggunakan Retrofit sebagai Rest API client. Why Retrofit ? Karena Retrofit memiliki performa yang cukup mumpuni dalam hal urusan Networking.
Setelah project baru selesai dibuat, buka berkas (file) build.gradle dan tambahkan dependensi Retrofit seperti berikut :
1 2 3 4 5 6 7 8 9 |
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.2' implementation 'com.squareup.retrofit2:retrofit:2.4.0' implementation 'com.squareup.retrofit2:converter-gson:2.4.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0' } |
Setelah menambahkan dependensi Retrofit, lakukan sinkronisasi project dengan menekan tombol Sync Now. Setelah selesai jangan lupa menambahkan internet permission pada berkas (file) AndroidManifest.xml seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.dicoding.rainbowrestapi"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="LoginActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SplashScreenActivity" /> <activity android:name=".UserInfoActivity" /> <activity android:name=".UpdateUserInfoActivity"/> </application> </manifest> |
Struktur kelas dan package dari project kali ini adalah seperti berikut :
Komponen Model
Yang pertama kita buat adalah komponen model di mana terdapat beberapa kelas yang akan digunakan untuk menampung respon dari Rest API Rainbow. Pembuatan kelas model sendiri cukup mudah loh. Gunakan bantuan plugin yang bernama RoboPojoGenerator.
Nah, berikut daftar beberapa model kelas yang akan digunakan untuk menampung respon dari Rest API Rainbow
AuthorizationResponse.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class AuthorizationResponse { private LoggedInUser loggedInUser; private String token; public LoggedInUser getLoggedInUser() { return loggedInUser; } public String getToken() { return token; } } |
LoggedInUser.java
1 2 3 4 5 6 7 8 |
public class LoggedInUser { private String id; public String getId() { return id; } } |
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public class User { private String loginEmail; private String firstName; private String lastName; private String jobTitle; public String getLoginEmail() { return loginEmail; } public void setLoginEmail(String loginEmail) { this.loginEmail = loginEmail; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getJobTitle() { return jobTitle; } public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; } } |
UserResponse.java
1 2 3 4 5 6 7 |
public class UserResponse { private User data; public User getData() { return data; } } |
Komponen Networking
Setelah selesai dengan komponen model, selanjutnya kita akan membuat kelas untuk komponen Networking, komponen yang digunakan untuk menghubungkan aplikasi dengan Rest API. Pada komponen networking terdapat dua kelas yang akan dibuat yaitu kelas ServiceClient seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class ServiceClient { private static Retrofit.Builder builder = new Retrofit.Builder(); private static OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); public static ServiceRepository buildServiceClient() { return builder.baseUrl("https://sandbox.openrainbow.com/") .addConverterFactory(GsonConverterFactory.create()) .client(client) .build() .create(ServiceRepository.class); } } |
Kelas ServiceClient digunakan untuk konfigurasi Retrofit agar bisa digunakan.
Sementara kelas ServiceRepository seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public interface ServiceRepository { @Headers({ "Accept: application/json", "x-rainbow-client: android", "x-rainbow-client-version: 1.10.7" }) @GET("api/rainbow/authentication/v1.0/login") Call<AuthorizationResponse> login(@Header("Authorization") String authorization); @Headers({ "Accept: application/json" }) @GET("api/rainbow/authentication/v1.0/logout") Call<Void> logout(@Header("Authorization") String authorization); @Headers( "Accept: application/json" ) @GET("api/rainbow/admin/v1.0/users/{userId}") Call<UserResponse> getUser(@Header("Authorization") String authorization, @Path("userId") String userId); @Headers( "Content-Type: application/json" ) @PUT("api/rainbow/admin/v1.0/users/{userId}") Call<UserResponse> updateInfoUser(@Header("Authorization") String authorization, @Path("userId") String userId, @Body User user); } |
Pada kelas ServiceRepository terdapat beberapa fungsi seperti login, logout, get user, update user info dengan detail endpoint dan parameter sebagai berikut :
Login
GET : /api/rainbow/authentication/v1.0/login
Header Parameter
* Jika terhubung ke Rainbow Developer Sandboxed Platform bisa tanpa dengan parameter “x-rainbow-app-auth”
Logout
GET : /api/rainbow/authentication/v1.0/logout
Header Parameter
Get User
GET : /api/rainbow/admin/v1.0/users/{userId}
Header Parameter
Path Parameter
Query Parameter
Update User Info
PUT : /api/rainbow/admin/v1.0/users/{userId}
Header Parameter
Path Parameter
Request Body
Komponen Common
Pada komponen common ada dua kelas yang akan dibuat, yaitu kelas UserPreferences dan kelas Utils. Pada kelas UserPreferences terdapat beberapa fungsi yang digunakan untuk menyimpan dan mengambil informasi yang tersimpan pada penyimpanan lokal menggunakan SharedPreferences seperti berikut :
UserPreferences.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public class UserPreferences { private static SharedPreferences preferences; public static boolean isLogin(Context context) { preferences = PreferenceManager.getDefaultSharedPreferences(context); return preferences.getBoolean("login", false); } public static void hasLogin(Context context) { preferences = PreferenceManager.getDefaultSharedPreferences(context); preferences.edit().putBoolean("login", true).apply(); } public static void logout(Context context) { preferences = PreferenceManager.getDefaultSharedPreferences(context); preferences.edit().clear().apply(); } public static String getTokeUser(Context context) { preferences = PreferenceManager.getDefaultSharedPreferences(context); return preferences.getString("token", ""); } public static void setTokenUser(Context context, String token) { preferences = PreferenceManager.getDefaultSharedPreferences(context); preferences.edit().putString("token", token).apply(); } public static String getUserId(Context context) { preferences = PreferenceManager.getDefaultSharedPreferences(context); return preferences.getString("userId", ""); } public static void setUserId(Context context, String userId) { preferences = PreferenceManager.getDefaultSharedPreferences(context); preferences.edit().putString("userId", userId).apply(); } } |
Kemudian pada kelas Utils terdapat dua fungsi, yaitu fungsi untuk melakukan encode String ke Base64 dan fungsi untuk menyembunyikan softkey seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Utils { public static String base64Encode(String email, String password) { String auth = email + ":" + password; return Base64.encodeToString(auth.getBytes(), Base64.NO_WRAP); } public static void hideSoftKey(View view) { if (view.getContext() != null) { InputMethodManager iml = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (iml != null) { iml.hideSoftInputFromWindow(view.getWindowToken(), 0); } } } } |
Halaman Splash Screen
Pada halaman splash screen tambahkan beberapa baris kode pada fungsi onCreate() untuk mengecek apakah sebelumnya pengguna sudah pernah melakukan login atau belum seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class SplashScreenActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (UserPreferences.isLogin(this)) { startActivity(new Intent(this, UserInfoActivity.class)); } else { startActivity(new Intent(this, LoginActivity.class)); } } @Override protected void onPause() { super.onPause(); finish(); } } |
Kode yang berada pada fungsi onCreate() bertujuan agar saat pengguna sebelumnya sudah pernah melakukan login, ia akan diarahkan ke halaman UserInfoActivity. Namun jika belum melakukan login, ia akan diarahkan ke halaman MainActivity.
Setelah halaman SplashScreen dibuat jangan lupa untuk merubah berkas (file) AndroidManifest.xml menjadi seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.dicoding.rainbowrestapi"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".SplashScreenActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".LoginActivity" /> <activity android:name=".UserInfoActivity" /> <activity android:name=".UpdateUserInfoActivity"/> </application> </manifest> |
Halaman informasi pengguna
Di halaman informasi pengguna terdapat beberapa widget TextView, satu widget ProgressBar dan tiga widget Button pada layout activity_user_info.xml seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:orientation="vertical" android:padding="16dp" tools:context=".activity.UserInfoActivity"> <ProgressBar android:id="@+id/loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> <LinearLayout android:id="@+id/llError" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="16dp" android:gravity="center_horizontal" android:orientation="vertical" android:visibility="gone"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Something Wrong" android:textSize="20sp" android:textStyle="bold" /> <Button android:id="@+id/btnTryAgain" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Try Again" /> </LinearLayout> <LinearLayout android:id="@+id/llInfo" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" android:visibility="gone"> <RelativeLayout android:layout_width="100dp" android:layout_height="100dp" android:background="@drawable/cirlce_avatar"> <TextView android:id="@+id/tvNameBadge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textColor="#fff" android:textSize="40sp" tools:text="ZZ" /> </RelativeLayout> <TextView android:id="@+id/tvDisplayName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="20sp" android:textStyle="bold" tools:text="Display Name" /> <TextView android:id="@+id/tvEmail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="17sp" tools:text="Email" /> <TextView android:id="@+id/tvJobTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:textSize="15sp" android:textStyle="italic" tools:text="Job Title" /> <Button android:id="@+id/btnUpdateInfo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="Update Info" /> <Button android:id="@+id/btnLogout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Logout" /> </LinearLayout> </LinearLayout> |
Kemudian pada kelas UserInfoActivity tambahkan fungsi loadUserInfo() untuk memuat informasi pengguna seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
public class UserInfoActivity extends AppCompatActivity { private TextView tvNameBadge; private TextView tvDisplayName; private TextView tvEmail; private TextView tvJobTitle; private ProgressBar loading; private LinearLayout llError; private LinearLayout llInfo; private String firstName; private String lastName; private String email; private String jobTitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_info); tvNameBadge = findViewById(R.id.tvNameBadge); tvDisplayName = findViewById(R.id.tvDisplayName); tvEmail = findViewById(R.id.tvEmail); tvJobTitle = findViewById(R.id.tvJobTitle); llError = findViewById(R.id.llError); llInfo = findViewById(R.id.llInfo); loading = findViewById(R.id.loading); Button btnTryAgain = findViewById(R.id.btnTryAgain); btnTryAgain.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { loadUserInfo(); } }); final Button btnUpdateUserInfo = findViewById(R.id.btnUpdateInfo); final Button btnLogout = findViewById(R.id.btnLogout); loadUserInfo(); } private void loadUserInfo() { loading.setVisibility(View.VISIBLE); if (llError.getVisibility() == View.VISIBLE) llError.setVisibility(View.GONE); ServiceClient .buildServiceClient() .getUser( "Bearer " + UserPreferences.getTokeUser(UserInfoActivity.this), UserPreferences.getUserId(UserInfoActivity.this)) .enqueue(new Callback<UserResponse>() { @Override public void onResponse(Call<UserResponse> call, Response<UserResponse> response) { if (response.isSuccessful()) { llInfo.setVisibility(View.VISIBLE); User user = response.body().getData(); firstName = user.getFirstName(); lastName = user.getLastName(); email = user.getLoginEmail(); jobTitle = user.getJobTitle().isEmpty() ? "-" : user.getJobTitle(); tvNameBadge.setText(firstName.charAt(0) + "" + lastName.charAt(0)); tvDisplayName.setText(firstName + " " + lastName); tvEmail.setText(email); tvJobTitle.setText(jobTitle); } else { llError.setVisibility(View.VISIBLE); } loading.setVisibility(View.GONE); } @Override public void onFailure(Call<UserResponse> call, Throwable t) { llError.setVisibility(View.VISIBLE); loading.setVisibility(View.GONE); } }); } } |
Halaman Login
Pada halaman login terdapat dua widget EditText, satu widget ProgressBar dan satu widget Button pada layout activity_login.xml seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="LoginActivity”> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:clipToPadding="false" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/etEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/email_hint" android:inputType="textEmailAddress|textNoSuggestions" /> <EditText android:id="@+id/etPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:hint="@string/password_hint" android:inputType="textPassword" /> <Button android:id="@+id/btnLogin" style="@style/Widget.AppCompat.Button.Colored" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="@string/sign_in_text_btn" /> <ProgressBar android:id="@+id/loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="20dp" android:visibility="gone" /> </LinearLayout> </ScrollView> </RelativeLayout> |
Kemudian pada kelas LoginActivity tambahkan fungsi doLogin() seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
public class LoginActivity extends AppCompatActivity { private EditText etEmail; private EditText etPassword; private Button btnLogin; private ProgressBar loading; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etEmail = findViewById(R.id.etEmail); etPassword = findViewById(R.id.etPassword); loading = findViewById(R.id.loading); btnLogin = findViewById(R.id.btnLogin); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String email = etEmail.getText().toString(); String password = etPassword.getText().toString(); if (email.isEmpty()) { etEmail.setError("Email Empty"); return; } if (password.isEmpty()) { etPassword.setError("Password Empty"); return; } Utils.hideSoftKey(etEmail); doLogin(email, password); } }); } private void doLogin(final String email, String password) { loading.setVisibility(View.VISIBLE); etEmail.setEnabled(false); etPassword.setEnabled(false); btnLogin.setEnabled(false); String authorization = "Basic " + Utils.base64Encode(email, password); ServiceClient .buildServiceClient() .login(authorization) .enqueue(new Callback<AuthorizationResponse>() { @Override public void onResponse(Call<AuthorizationResponse> call, Response<AuthorizationResponse> response) { if (response.isSuccessful()) { AuthorizationResponse auth = response.body(); UserPreferences.setTokenUser(LoginActivity.this, auth.getToken()); UserPreferences.setUserId(MainActivity.this, auth.getLoggedInUser().getId()); UserPreferences.hasLogin(MainActivity.this); startActivity(new Intent(MainActivity.this, UserInfoActivity.class)); finish(); } else { Toast.makeText(MainActivity.this, "Unknown login or wrong password for login " + email, Toast.LENGTH_SHORT).show(); Log.d("onResponse", "onResponse: " + response.message()); loading.setVisibility(View.GONE); etEmail.setEnabled(true); etPassword.setEnabled(true); btnLogin.setEnabled(true); } } @Override public void onFailure(Call<AuthorizationResponse> call, Throwable t) { Toast.makeText(MainActivity.this, "Something Wrong!", Toast.LENGTH_SHORT).show(); Log.d("onFailure", "onFailure: " + t.getMessage()); loading.setVisibility(View.VISIBLE); etEmail.setEnabled(true); etPassword.setEnabled(true); btnLogin.setEnabled(true); } }); } } |
Jika fungsi login di atas berhasil maka sistem akan menyimpan beberapa informasi pengguna ke dalam penyimpanan lokal. Kemudian pengguna akan diarahkan ke halaman informasi. Tapi jika gagal, pop-up berupa Toast akan muncul dan menampilkan pesan yang sudah ditentukan seperti berikut :
Halaman untuk memperbaharui informasi pengguna
Next, pembuatan halaman untuk memperbaharui informasi pengguna. Sama halnya dengan halaman login, halaman ini memiliki beberapa widget EditText, satu widget Progressbar dan satu widget Button pada layout activity_update_user_info.xml seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="UpdateUserInfoActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp" android:orientation="vertical"> <EditText android:id="@+id/etFirstName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="First name" android:inputType="textNoSuggestions" /> <EditText android:id="@+id/etLastName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:hint="Last name" android:inputType="textNoSuggestions" /> <EditText android:id="@+id/etEmail" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:hint="Email" android:inputType="textEmailAddress" /> <EditText android:id="@+id/etJobTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:hint="Jobtitle" android:inputType="textNoSuggestions" /> <Button android:id="@+id/btnUpdateUserInfo" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="update user info" /> <ProgressBar android:id="@+id/loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="16dp" android:visibility="gone" /> </LinearLayout> </ScrollView> |
Kemudian pada kelas UpdateUserInfoActivity tambahkan fungsi updateuserInfo() untuk memperbaharui informasi pengguna seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
public class UpdateUserInfoActivity extends AppCompatActivity { private EditText etFirstName; private EditText etLastName; private EditText etEmail; private EditText etJobTitle; private ProgressBar loading; private Button btnUpdateUserInfo; private User user; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_update_user_info); etFirstName = findViewById(R.id.etFirstName); etLastName = findViewById(R.id.etLastName); etEmail = findViewById(R.id.etEmail); etJobTitle = findViewById(R.id.etJobTitle); loading = findViewById(R.id.loading); btnUpdateUserInfo = findViewById(R.id.btnUpdateUserInfo); btnUpdateUserInfo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String firstName = etFirstName.getText().toString(); String lastName = etLastName.getText().toString(); String email = etEmail.getText().toString(); String job = etJobTitle.getText().toString(); if (firstName.isEmpty()) { etFirstName.setError("First Name empty"); return; } if (lastName.isEmpty()) { etLastName.setError("Last Name empty"); return; } if (email.isEmpty()) { etEmail.setError("Email empty"); return; } if (job.isEmpty()) { etJobTitle.setError("Job title empty"); return; } user = new User(); user.setFirstName(firstName); user.setLastName(lastName); user.setLoginEmail(email); user.setJobTitle(job); Utils.hideSoftKey(etEmail); updateUserInfo(user); } }); user = new User(); user.setFirstName(getIntent().getStringExtra("firstName")); user.setLastName(getIntent().getStringExtra("lastName")); user.setLoginEmail(getIntent().getStringExtra("email")); user.setJobTitle(getIntent().getStringExtra("jobTitle")); etFirstName.setText(user.getFirstName()); etLastName.setText(user.getLastName()); etJobTitle.setText(user.getJobTitle()); etEmail.setText(user.getLoginEmail()); } private void updateUserInfo(User user) { loading.setVisibility(View.VISIBLE); etFirstName.setEnabled(false); etLastName.setEnabled(false); etEmail.setEnabled(false); etJobTitle.setEnabled(false); btnUpdateUserInfo.setEnabled(false); ServiceClient .buildServiceClient() .updateInfoUser( "Bearer " + UserPreferences.getTokeUser(UpdateUserInfoActivity.this), UserPreferences.getUserId(UpdateUserInfoActivity.this), user) .enqueue(new Callback<UserResponse>() { @Override public void onResponse(Call<UserResponse> call, Response<UserResponse> response) { if (response.isSuccessful()) { Toast.makeText(UpdateUserInfoActivity.this, "Success to update user info", Toast.LENGTH_SHORT).show(); setResult(Activity.RESULT_OK); finish(); } else { Toast.makeText(UpdateUserInfoActivity.this, "Failed to update user info", Toast.LENGTH_SHORT).show(); Log.d("onFailure", "onFailure: " + response.message()); loading.setVisibility(View.GONE); etFirstName.setEnabled(true); etLastName.setEnabled(true); etEmail.setEnabled(true); etJobTitle.setEnabled(true); btnUpdateUserInfo.setEnabled(true); } } @Override public void onFailure(Call<UserResponse> call, Throwable t) { Toast.makeText(UpdateUserInfoActivity.this, "Failed to update user info", Toast.LENGTH_SHORT).show(); Log.d("onFailure", "onFailure: " + t.getMessage()); loading.setVisibility(View.GONE); etFirstName.setEnabled(true); etLastName.setEnabled(true); etEmail.setEnabled(true); etJobTitle.setEnabled(true); btnUpdateUserInfo.setEnabled(true); } }); } } |
Jika informasi pengguna berhasil diperbaharui maka halaman akan secara otomatis tertutup dan mengembalikan nilai RESULT_OK. Namun jika gagal, pop-up berupa Toast akan muncul dan menampilkan pesan yang sudah ditentukan.
Kemudian pada kelas UserInfoActivity, tambahkan fungsi setOnClickListener() pada variable btnUpdateUserInfo seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
final Button btnUpdateUserInfo = findViewById(R.id.btnUpdateInfo); btnUpdateUserInfo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent update = new Intent(UserInfoActivity.this, UpdateUserInfoActivity.class); update.putExtra("firstName", firstName); update.putExtra("lastName", lastName); update.putExtra("email", email); update.putExtra("jobTitle", jobTitle); startActivityForResult(update, 0x01); } }); |
Di dalam fungsi setOnClickListener() di atas terdapat beberapa baris untuk mengirim dan menampilkan data ke halaman untuk memperbaharui informasi pengguna.
Masih dalam kelas UserInfoActivity, tambahkan fungsi onActivityResult() seperti berikut :
1 2 3 4 5 6 7 8 9 |
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 0x01 && resultCode == RESULT_OK) { llInfo.setVisibility(View.GONE); loadUserInfo(); } } |
onActivityResult() berfungsi untuk mengecek nilai kembalian dari kelas UpdateUserInfoActivity, jika bernilai RESULT_OK maka secara otomatis informasi pengguna akan dimuat kembali seperti berikut
Menambahkan fungsi Logout
Untuk menambahkan fungsi logout, buka kembali kelas UserInfoActivity. Tambahkan fungsi setOnClickListener() pada variable btnLogout seperti berikut :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
final Button btnLogout = findViewById(R.id.btnLogout); btnLogout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { loading.setVisibility(View.VISIBLE); llInfo.setVisibility(View.GONE); ServiceClient .buildServiceClient() .logout( "Bearer " + UserPreferences.getTokeUser(UserInfoActivity.this)) .enqueue(new Callback<Void>() { @Override public void onResponse(Call<Void> call, Response<Void> response) { if (response.isSuccessful()) { UserPreferences.logout(UserInfoActivity.this); Toast.makeText(UserInfoActivity.this, "User " + email + " successfully logged out", Toast.LENGTH_SHORT).show(); startActivity(new Intent(UserInfoActivity.this, MainActivity.class)); finish(); } else { llInfo.setVisibility(View.VISIBLE); loading.setVisibility(View.GONE); Toast.makeText(UserInfoActivity.this, "Logout Failed", Toast.LENGTH_SHORT).show(); Log.d("OnFailure", "onFailure: " + response.raw().toString()); } } @Override public void onFailure(Call<Void> call, Throwable t) { llInfo.setVisibility(View.VISIBLE); loading.setVisibility(View.GONE); Toast.makeText(UserInfoActivity.this, "Logout Failed", Toast.LENGTH_SHORT).show(); Log.d("OnFailure", "onFailure: " + t.getLocalizedMessage()); } }); } }); |
Jika fungsi logout berhasil maka halaman akan tertutup dan diarahkan kembali ke halaman login seperti berikut :
Karena project pada tutorial ini terhubung ke Rainbow Developer Sandboxed Platform, pastikan saat mencobanya kamu menggunakan akun Sandboxed Rainbow yang telah aktif seperti berikut :
Demikian tutorial membuat Halaman Login dan Update User Info Rainbow Android Apps.
Semoga artikel ini dapat membantu anda. Jika ada pertanyaan, silakan tinggalkan komentar di halaman blog ini dan kami akan membantu anda.
Mau belajar lebih dalam mengenai Android? Daftar ke kelas Menjadi Android Developer Expert di https://www.dicoding.com/academies/14
Simak juga informasi mengenai Rainbow Android berikut:
“Cara Integrasi Rainbow API pada Android Apps” https://www.dicoding.com/blog/cara-integrasi-rainbow-api-pada-android-apps/
“Menampilkan List Kontak Rainbow Pada Android Apps” https://www.dicoding.com/blog/menampilkan-list-kontak-rainbow-pada-android-apps/
“Indonesia Diaspora Connect: Karya Pemenang Dicoding Challenge: ALE Hackathon 2018” https://www.dicoding.com/blog/indonesia-diaspora-connect-karya-pemenang-dicoding-challenge-ale-hackathon-2018/