이번편은 user fragment 부분과 기반앱의 common 패키지의 서비스 부분을 만든다.
일단 userfragment의 xml을 복사하고 java 파일을 변환해서 kt로 옮겨 복사한다.
구현중 내부에 UserPWActivity.kt 도 필요해서 xml과 java를 같이 복사해 변환하였다.
먼저 UserPWActivity는
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
|
class UserPWActivity : AppCompatActivity() {
private var user_pw1: EditText? = null
private var user_pw2: EditText? = null
private var saveBtn: Button? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_userpw)
user_pw1 = findViewById(R.id.user_pw1)
user_pw2 = findViewById(R.id.user_pw2)
saveBtn!!.setOnClickListener{
val pw1 = user_pw1!!.text.toString().trim { it <= ' ' }
if (pw1.length < 8) {
helpers.showMessage(applicationContext, "Please enter at least eight characters.")
return@setOnClickListener
}
if (pw1 != user_pw2!!.text.toString().trim { it <= ' ' }) {
helpers.showMessage(
applicationContext,
"Password does not match the confirm password."
)
return@setOnClickListener
}
val user = FirebaseAuth.getInstance().currentUser
user!!.updatePassword(pw1).addOnCompleteListener {
helpers.showMessage(applicationContext, "Password changed")
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(user_pw2!!.windowToken, 0)
onBackPressed()
}
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
위와 같이 바꾸었다.
UserFragment는
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
|
@Suppress("DEPRECATION")
class UserFragment : Fragment() {
companion object {
private val PICK_FROM_ALBUM = 1
}
private var user_photo: ImageView? = null
private var user_id: EditText? = null
private var user_name: EditText? = null
private var user_msg: EditText? = null
private var userModel: UserModel? = null
private var userPhotoUri: Uri? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_user, container, false)
user_id?.isEnabled = false
user_photo?.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
startActivityForResult(intent, PICK_FROM_ALBUM)
}
saveBtn.setOnClickListener{
if (!validateForm()) return@setOnClickListener
userModel?.usernm = user_name!!.text.toString()
userModel?.usermsg = user_msg!!.text.toString()
val uid = FirebaseAuth.getInstance().currentUser!!.uid
val db = FirebaseFirestore.getInstance()
if (userPhotoUri != null) userModel!!.userphoto = uid
db.collection("users").document(uid)
.set(userModel!!)
.addOnSuccessListener {
if (userPhotoUri == null) {helpers.showMessage(activity!!, "Success to Save.")}
else {
// small image
.asBitmap().load(userPhotoUri).apply(RequestOptions().override(150, 150))
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(
bitmap: Bitmap,
transition: Transition<in Bitmap>?
) {
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
FirebaseStorage.getInstance().reference.child("userPhoto/$uid")
.putBytes(data)
helpers.showMessage(activity!!, "Success to Save.")
}
})
}
}
}
changePWBtn.setOnClickListener {
startActivity(Intent(activity, UserPWActivity::class.java))
}
getUserInfoFromServer()
return view
}
private fun getUserInfoFromServer() {
val uid = FirebaseAuth.getInstance().currentUser!!.uid
val docRef = FirebaseFirestore.getInstance().collection("users").document(uid)
userModel = documentSnapshot.toObject<UserModel>(UserModel::class.java)
user_id!!.setText(userModel?.userid)
user_name!!.setText(userModel?.usernm)
user_msg!!.setText(userModel?.usermsg)
if (userModel?.userphoto != null && "" != userModel?.userphoto) {
Glide.with(activity!!).load(FirebaseStorage.getInstance().getReference("userPhoto/" + userModel?.userphoto)).into(user_photo!!)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == PICK_FROM_ALBUM && resultCode == Activity.RESULT_OK) {
user_photo!!.setImageURI(data?.data)
userPhotoUri = data?.data
}
}
private fun validateForm(): Boolean {
var valid = true
val userName = user_name!!.text.toString()
if (TextUtils.isEmpty(userName)) {
user_name!!.error = "Required."
valid = false
} else {
user_name!!.error = null
}
val userMsg = user_msg!!.text.toString()
if (TextUtils.isEmpty(userMsg)) {
user_msg!!.error = "Required."
valid = false
} else {
user_msg!!.error = null
}
helpers.hideKeyboard(activity!!)
return valid
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
Userfragment는 위와 같이 구성하였다.
그러고서 실행을 하면 아래와 같은 오류가 난다.
textinputlayout의 문제인것 같아
<com.google.android.material.textfield.TextInputLayout ... 로 바꾸어 다시 실행하였다.
그러면 또 문제가 발생하는데 이는 아래와 같다.
이는 onCreatedView 생성시 버튼 id를 찾을 시간이 확보되지않아 발생하는 문제이므로
onViewCreated에 버튼 관련 동작을 넣어준다. 그것은 아래와 같다.
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
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
user_photo?.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
startActivityForResult(intent, PICK_FROM_ALBUM)
}
saveBtn.setOnClickListener{
if (!validateForm()) return@setOnClickListener
userModel?.usernm = user_name!!.text.toString()
userModel?.usermsg = user_msg!!.text.toString()
val uid = FirebaseAuth.getInstance().currentUser!!.uid
val db = FirebaseFirestore.getInstance()
if (userPhotoUri != null) userModel!!.userphoto = uid
db.collection("users").document(uid)
.set(userModel!!)
.addOnSuccessListener {
if (userPhotoUri == null) {helpers.showMessage(activity!!, "Success to Save.")}
else {
// small image
.asBitmap().load(userPhotoUri).apply(RequestOptions().override(150, 150))
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(
bitmap: Bitmap,
transition: Transition<in Bitmap>?
) {
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
FirebaseStorage.getInstance().reference.child("userPhoto/$uid")
.putBytes(data)
helpers.showMessage(activity!!, "Success to Save.")
}
})
}
}
}
changePWBtn.setOnClickListener {
startActivity(Intent(activity, UserPWActivity::class.java))
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
이제 MyFirebaseMessagingService를 복사하고 매니패스트에 추가하자.
이는 간단히 kotlin converting 기능만으로 해결이 가능하다.
그리고
<service android:name=".common.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
를 매니페스트에 추가하면된다.
그리고 MyAppGlideModule.kt 이 부분도 추가해준다.
이제 실행을 하면 저기 floating button(붉은 원에 녹색 + 모양)을 클릭했을때 에러가 나며 종료가 되는데,
이 부분이 문제이므로 따라가본다.
확인해보니
<android.support.v7.widget.RecyclerView 로 되어있던 xml 의 recyclerview를
<androidx.recyclerview.widget.RecyclerView로 바꾸니까 잘 되었다.
그 다음으로 여기서 아이디를 클릭하니까 에러가 났다.
아래와 같은 에러인데... 이는 Null에 대한 처리 문제인듯하다.
ChatActivity에서 아래와 같이 되어있는 부분을
일단 아래와 같이 바꾸어 주었다.
그러니까
위와 같은 에러가 생겼는데, 이는 앞선 문제와 동일하므로 onViewCreated으로 EventListener부분 옮겨주었다.
그러고나니 또
위와 같은 에러가 발생하였는데 이를 확인해보면,
이때는 문제가 안생기는데 이 디버깅포인트가 다시 한번 호출 되어 아래와 같은 상황이 발생할때가 있다.
이때 usermodel의 uid가 null이므로 not null을 보장하는 uid!!을 사용하여 오류가 발생하는 것이다. 따라서 널처리를해주어야한다.
위와 같이 조건을 추가해주었고 아래와 같이 제대로 실행되는 것을 확인할 수 있다.