如何解决 LayoutInflaters 上的 NullPointerException?
How to solve NullPointerException on LayoutInflaters?
我已经在这个问题上停留了一段时间了,我已经浏览了关于这个问题的其他问题。但是,我不完全理解他们的解决方案以及如何将其应用于我的案例。
Logcat
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.realtimechat/com.example.realtimechat.chats.ChatActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.LayoutInflater android.view.Window.getLayoutInflater()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3022)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3259)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1950)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7073)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.LayoutInflater android.view.Window.getLayoutInflater()' on a null object reference
at android.app.Activity.getLayoutInflater(Activity.java:4435)
at com.example.realtimechat.chats.ChatActivity.<init>(ChatActivity.kt:66)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3010)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3259)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1950)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7073)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
聊天Activity
package com.example.realtimechat.chats
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_PICK
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.provider.MediaStore.ACTION_IMAGE_CAPTURE
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.example.realtimechat.R
import com.example.realtimechat.common.Constants
import com.example.realtimechat.common.Extras
import com.example.realtimechat.common.NodeNames
import com.example.realtimechat.common.Utils
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import com.google.firebase.storage.FirebaseStorage
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
class ChatActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var etMessage: EditText
private lateinit var ivSend: ImageView
private lateinit var ivAttachment: ImageView
private lateinit var mAuth: FirebaseAuth
private lateinit var mRootRef: DatabaseReference
private lateinit var currentUserId: String
private lateinit var chatUserId: String
private lateinit var rvMessages: RecyclerView
private lateinit var srlMessages: SwipeRefreshLayout
private lateinit var messagesAdapter: MessagesAdapter
private lateinit var messagesList: MutableList<MessageModel>
private var currentPage = 1
companion object {
private const val RECORD_PER_PAGE = 30
}
private val REQUEST_CODE_CAPTURE_IMAGE=102
private val REQUEST_CODE_PICK_IMAGE=101
private val REQUEST_CODE_PICK_VIDEO=103
private lateinit var databaseReferenceMessages: DatabaseReference
private lateinit var childEventListener: ChildEventListener
private lateinit var bottomSheetDialog: BottomSheetDialog
val view: View = layoutInflater.inflate(R.layout.chat_file_options, null)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
etMessage = findViewById(R.id.etMessage)
ivSend = findViewById(R.id.ivSend)
ivAttachment = findViewById(R.id.ivAttachment)
ivSend.setOnClickListener(this)
ivAttachment.setOnClickListener(this)
mAuth = FirebaseAuth.getInstance()
mRootRef = FirebaseDatabase.getInstance().reference
currentUserId = mAuth.currentUser!!.uid
if(intent.hasExtra(Extras.USER_KEY)){
chatUserId = intent.getStringExtra(Extras.USER_KEY)!!
}
rvMessages = findViewById(R.id.rvMessages)
srlMessages = findViewById(R.id.srlMessages)
val layoutManager = LinearLayoutManager(applicationContext)
layoutManager.orientation = RecyclerView.VERTICAL
rvMessages.layoutManager = layoutManager
rvMessages.setHasFixedSize(true)
messagesList = ArrayList()
messagesAdapter = MessagesAdapter(this, messagesList)
rvMessages.adapter = messagesAdapter
loadMessages()
rvMessages.scrollToPosition(messagesList.size-1)
srlMessages.setOnRefreshListener(object: SwipeRefreshLayout.OnRefreshListener{
override fun onRefresh() {
currentPage++
loadMessages()
}
})
bottomSheetDialog = BottomSheetDialog(this)
view.findViewById<View>(R.id.llCamera).setOnClickListener(this)
view.findViewById<View>(R.id.llGallery).setOnClickListener(this)
view.findViewById<View>(R.id.llVideo).setOnClickListener(this)
view.findViewById<View>(R.id.ivClose).setOnClickListener(this)
bottomSheetDialog.setContentView(view)
}
//send messages
private fun sendMessage(msg: String, msgType: String, pushId: String){
try {
if (msg != "") {
val messageMap = HashMap<Any, Any>()
messageMap[NodeNames.MESSAGE_ID] = pushId
messageMap[NodeNames.MESSAGE] = msg
messageMap[NodeNames.MESSAGE_TYPE] = msgType
messageMap[NodeNames.MESSAGE_FROM] = currentUserId
messageMap[NodeNames.MESSAGE_TIME] = ServerValue.TIMESTAMP
val currentUserRef = NodeNames.MESSAGES + "/" + currentUserId + "/" + chatUserId
val chatUserRef = NodeNames.MESSAGES + "/" + chatUserId + "/" + currentUserId
val messageUserMap = mutableMapOf<String, Any>()
messageUserMap["$currentUserRef/$pushId"] = messageMap
messageUserMap["$chatUserRef/$pushId"] = messageMap
etMessage.setText("")
mRootRef.updateChildren(messageUserMap, object : DatabaseReference.CompletionListener {
override fun onComplete(databaseError: DatabaseError?, databaseReference: DatabaseReference) {
if (databaseError != null) {
Toast.makeText(applicationContext, "Failed to send message: ${databaseError.message}", Toast.LENGTH_SHORT).show()
}
run{
Toast.makeText(applicationContext, "Message sent successfully!", Toast.LENGTH_SHORT).show()
}
}
})
}
} catch (e: Exception) {
Toast.makeText(applicationContext, "Failed to send message: ${e.localizedMessage}", Toast.LENGTH_SHORT).show()
}
}
private fun loadMessages(){
messagesList.clear()
databaseReferenceMessages = mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId)
val messageQuery: Query = databaseReferenceMessages.limitToLast(currentPage * RECORD_PER_PAGE)
childEventListener = object: ChildEventListener{
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
val message: MessageModel = snapshot.getValue(MessageModel::class.java)!!
messagesList.add(message)
messagesAdapter.notifyDataSetChanged()
rvMessages.scrollToPosition(messagesList.size-1)
srlMessages.isRefreshing = false
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
}
override fun onChildRemoved(snapshot: DataSnapshot) {
}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
}
override fun onCancelled(error: DatabaseError) {
srlMessages.isRefreshing = false
}
}
messageQuery.addChildEventListener(childEventListener)
}
private fun uploadFile(uri: Uri, messageType: String){
val databaseReference = mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId).push()
val pushId = databaseReference.key!!
val folderName =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) Constants.MESSAGE_VIDEOS else Constants.MESSAGE_IMAGES
val fileName: String =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) "$pushId.mp4" else "$pushId.jpg"
val storageReference = FirebaseStorage.getInstance().reference
val fileReference = storageReference.child(folderName).child(fileName)
fileReference.putFile(uri)
}
private fun uploadBytes(bytes: ByteArrayOutputStream, messageType: String){
val databaseReference = mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId).push()
val pushId = databaseReference.key!!
val folderName =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) Constants.MESSAGE_VIDEOS else Constants.MESSAGE_IMAGES
val fileName: String =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) "$pushId.mp4" else "$pushId.jpg"
val storageReference = FirebaseStorage.getInstance().reference
val fileReference = storageReference.child(folderName).child(fileName)
fileReference.putBytes(bytes.toByteArray())
}
//if any objects are clicked
override fun onClick(v: View?) {
when(v!!.id){
R.id.ivSend -> {
val utility = Utils()
if(utility.connectionAvailable(this)) {
val message = etMessage.text.toString().trim()
val messageType = NodeNames.MESSAGE_TYPE_TEXT
val userMessagePush =
mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId)
.push()
val pushId = userMessagePush.key
sendMessage(message, messageType, pushId!!)
}else{
Toast.makeText(applicationContext, "No Internet connection available", Toast.LENGTH_SHORT).show()
}
}
R.id.ivAttachment -> {
if(ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED){
if(bottomSheetDialog!=null){
bottomSheetDialog.show()
}
}else{
ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE), 1)
}
val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if(inputMethodManager!=null){
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
}
R.id.llCamera -> {
bottomSheetDialog.dismiss()
val intentCamera = Intent(ACTION_IMAGE_CAPTURE)
startActivityForResult(intentCamera, REQUEST_CODE_CAPTURE_IMAGE)
}
R.id.llGallery -> {
bottomSheetDialog.dismiss()
val intentImage = Intent(ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intentImage, REQUEST_CODE_PICK_IMAGE)
}
R.id.llVideo -> {
bottomSheetDialog.dismiss()
val intentVideo = Intent(ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intentVideo, REQUEST_CODE_PICK_VIDEO)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode== Activity.RESULT_OK){
if(requestCode==REQUEST_CODE_CAPTURE_IMAGE) {
val bitMap = data!!.extras!!.get("data") as Bitmap
val bytes = ByteArrayOutputStream()
bitMap.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
uploadBytes(bytes, Constants.MESSAGE_TYPE_IMAGE)
}else if(requestCode==REQUEST_CODE_PICK_IMAGE){
val uri = data!!.data!!
uploadFile(uri, Constants.MESSAGE_TYPE_IMAGE)
}else if(requestCode==REQUEST_CODE_PICK_VIDEO){
val uri = data!!.data!!
uploadFile(uri, Constants.MESSAGE_TYPE_VIDEO)
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode==1){
if(grantResults.size>1 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
if(bottomSheetDialog!=null){
bottomSheetDialog.show()
}
}else{
Toast.makeText(this, "Permission needed", Toast.LENGTH_SHORT).show()
}
}
}
}
如果有人能(以简单的方式)解释如何处理和解决这些类型的问题以及如何解决我的问题,将不胜感激!
layoutInflater 尚未实例化。在对视图进行任何操作时,您几乎必须等到 onCreate
方法。所以像这样:
var view: View? = null
// OR
lateinit var view: View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
view = layoutInflater.inflate(R.layout.chat_file_options, null)
......
}
我已经在这个问题上停留了一段时间了,我已经浏览了关于这个问题的其他问题。但是,我不完全理解他们的解决方案以及如何将其应用于我的案例。
Logcat
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.realtimechat/com.example.realtimechat.chats.ChatActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.LayoutInflater android.view.Window.getLayoutInflater()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3022)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3259)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1950)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7073)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.LayoutInflater android.view.Window.getLayoutInflater()' on a null object reference
at android.app.Activity.getLayoutInflater(Activity.java:4435)
at com.example.realtimechat.chats.ChatActivity.<init>(ChatActivity.kt:66)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3010)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3259)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1950)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7073)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
聊天Activity
package com.example.realtimechat.chats
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_PICK
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.provider.MediaStore.ACTION_IMAGE_CAPTURE
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.example.realtimechat.R
import com.example.realtimechat.common.Constants
import com.example.realtimechat.common.Extras
import com.example.realtimechat.common.NodeNames
import com.example.realtimechat.common.Utils
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import com.google.firebase.storage.FirebaseStorage
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
class ChatActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var etMessage: EditText
private lateinit var ivSend: ImageView
private lateinit var ivAttachment: ImageView
private lateinit var mAuth: FirebaseAuth
private lateinit var mRootRef: DatabaseReference
private lateinit var currentUserId: String
private lateinit var chatUserId: String
private lateinit var rvMessages: RecyclerView
private lateinit var srlMessages: SwipeRefreshLayout
private lateinit var messagesAdapter: MessagesAdapter
private lateinit var messagesList: MutableList<MessageModel>
private var currentPage = 1
companion object {
private const val RECORD_PER_PAGE = 30
}
private val REQUEST_CODE_CAPTURE_IMAGE=102
private val REQUEST_CODE_PICK_IMAGE=101
private val REQUEST_CODE_PICK_VIDEO=103
private lateinit var databaseReferenceMessages: DatabaseReference
private lateinit var childEventListener: ChildEventListener
private lateinit var bottomSheetDialog: BottomSheetDialog
val view: View = layoutInflater.inflate(R.layout.chat_file_options, null)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
etMessage = findViewById(R.id.etMessage)
ivSend = findViewById(R.id.ivSend)
ivAttachment = findViewById(R.id.ivAttachment)
ivSend.setOnClickListener(this)
ivAttachment.setOnClickListener(this)
mAuth = FirebaseAuth.getInstance()
mRootRef = FirebaseDatabase.getInstance().reference
currentUserId = mAuth.currentUser!!.uid
if(intent.hasExtra(Extras.USER_KEY)){
chatUserId = intent.getStringExtra(Extras.USER_KEY)!!
}
rvMessages = findViewById(R.id.rvMessages)
srlMessages = findViewById(R.id.srlMessages)
val layoutManager = LinearLayoutManager(applicationContext)
layoutManager.orientation = RecyclerView.VERTICAL
rvMessages.layoutManager = layoutManager
rvMessages.setHasFixedSize(true)
messagesList = ArrayList()
messagesAdapter = MessagesAdapter(this, messagesList)
rvMessages.adapter = messagesAdapter
loadMessages()
rvMessages.scrollToPosition(messagesList.size-1)
srlMessages.setOnRefreshListener(object: SwipeRefreshLayout.OnRefreshListener{
override fun onRefresh() {
currentPage++
loadMessages()
}
})
bottomSheetDialog = BottomSheetDialog(this)
view.findViewById<View>(R.id.llCamera).setOnClickListener(this)
view.findViewById<View>(R.id.llGallery).setOnClickListener(this)
view.findViewById<View>(R.id.llVideo).setOnClickListener(this)
view.findViewById<View>(R.id.ivClose).setOnClickListener(this)
bottomSheetDialog.setContentView(view)
}
//send messages
private fun sendMessage(msg: String, msgType: String, pushId: String){
try {
if (msg != "") {
val messageMap = HashMap<Any, Any>()
messageMap[NodeNames.MESSAGE_ID] = pushId
messageMap[NodeNames.MESSAGE] = msg
messageMap[NodeNames.MESSAGE_TYPE] = msgType
messageMap[NodeNames.MESSAGE_FROM] = currentUserId
messageMap[NodeNames.MESSAGE_TIME] = ServerValue.TIMESTAMP
val currentUserRef = NodeNames.MESSAGES + "/" + currentUserId + "/" + chatUserId
val chatUserRef = NodeNames.MESSAGES + "/" + chatUserId + "/" + currentUserId
val messageUserMap = mutableMapOf<String, Any>()
messageUserMap["$currentUserRef/$pushId"] = messageMap
messageUserMap["$chatUserRef/$pushId"] = messageMap
etMessage.setText("")
mRootRef.updateChildren(messageUserMap, object : DatabaseReference.CompletionListener {
override fun onComplete(databaseError: DatabaseError?, databaseReference: DatabaseReference) {
if (databaseError != null) {
Toast.makeText(applicationContext, "Failed to send message: ${databaseError.message}", Toast.LENGTH_SHORT).show()
}
run{
Toast.makeText(applicationContext, "Message sent successfully!", Toast.LENGTH_SHORT).show()
}
}
})
}
} catch (e: Exception) {
Toast.makeText(applicationContext, "Failed to send message: ${e.localizedMessage}", Toast.LENGTH_SHORT).show()
}
}
private fun loadMessages(){
messagesList.clear()
databaseReferenceMessages = mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId)
val messageQuery: Query = databaseReferenceMessages.limitToLast(currentPage * RECORD_PER_PAGE)
childEventListener = object: ChildEventListener{
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
val message: MessageModel = snapshot.getValue(MessageModel::class.java)!!
messagesList.add(message)
messagesAdapter.notifyDataSetChanged()
rvMessages.scrollToPosition(messagesList.size-1)
srlMessages.isRefreshing = false
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
}
override fun onChildRemoved(snapshot: DataSnapshot) {
}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
}
override fun onCancelled(error: DatabaseError) {
srlMessages.isRefreshing = false
}
}
messageQuery.addChildEventListener(childEventListener)
}
private fun uploadFile(uri: Uri, messageType: String){
val databaseReference = mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId).push()
val pushId = databaseReference.key!!
val folderName =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) Constants.MESSAGE_VIDEOS else Constants.MESSAGE_IMAGES
val fileName: String =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) "$pushId.mp4" else "$pushId.jpg"
val storageReference = FirebaseStorage.getInstance().reference
val fileReference = storageReference.child(folderName).child(fileName)
fileReference.putFile(uri)
}
private fun uploadBytes(bytes: ByteArrayOutputStream, messageType: String){
val databaseReference = mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId).push()
val pushId = databaseReference.key!!
val folderName =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) Constants.MESSAGE_VIDEOS else Constants.MESSAGE_IMAGES
val fileName: String =
if (messageType == Constants.MESSAGE_TYPE_VIDEO) "$pushId.mp4" else "$pushId.jpg"
val storageReference = FirebaseStorage.getInstance().reference
val fileReference = storageReference.child(folderName).child(fileName)
fileReference.putBytes(bytes.toByteArray())
}
//if any objects are clicked
override fun onClick(v: View?) {
when(v!!.id){
R.id.ivSend -> {
val utility = Utils()
if(utility.connectionAvailable(this)) {
val message = etMessage.text.toString().trim()
val messageType = NodeNames.MESSAGE_TYPE_TEXT
val userMessagePush =
mRootRef.child(NodeNames.MESSAGES).child(currentUserId).child(chatUserId)
.push()
val pushId = userMessagePush.key
sendMessage(message, messageType, pushId!!)
}else{
Toast.makeText(applicationContext, "No Internet connection available", Toast.LENGTH_SHORT).show()
}
}
R.id.ivAttachment -> {
if(ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED){
if(bottomSheetDialog!=null){
bottomSheetDialog.show()
}
}else{
ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE), 1)
}
val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if(inputMethodManager!=null){
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
}
R.id.llCamera -> {
bottomSheetDialog.dismiss()
val intentCamera = Intent(ACTION_IMAGE_CAPTURE)
startActivityForResult(intentCamera, REQUEST_CODE_CAPTURE_IMAGE)
}
R.id.llGallery -> {
bottomSheetDialog.dismiss()
val intentImage = Intent(ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intentImage, REQUEST_CODE_PICK_IMAGE)
}
R.id.llVideo -> {
bottomSheetDialog.dismiss()
val intentVideo = Intent(ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intentVideo, REQUEST_CODE_PICK_VIDEO)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode== Activity.RESULT_OK){
if(requestCode==REQUEST_CODE_CAPTURE_IMAGE) {
val bitMap = data!!.extras!!.get("data") as Bitmap
val bytes = ByteArrayOutputStream()
bitMap.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
uploadBytes(bytes, Constants.MESSAGE_TYPE_IMAGE)
}else if(requestCode==REQUEST_CODE_PICK_IMAGE){
val uri = data!!.data!!
uploadFile(uri, Constants.MESSAGE_TYPE_IMAGE)
}else if(requestCode==REQUEST_CODE_PICK_VIDEO){
val uri = data!!.data!!
uploadFile(uri, Constants.MESSAGE_TYPE_VIDEO)
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode==1){
if(grantResults.size>1 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
if(bottomSheetDialog!=null){
bottomSheetDialog.show()
}
}else{
Toast.makeText(this, "Permission needed", Toast.LENGTH_SHORT).show()
}
}
}
}
如果有人能(以简单的方式)解释如何处理和解决这些类型的问题以及如何解决我的问题,将不胜感激!
layoutInflater 尚未实例化。在对视图进行任何操作时,您几乎必须等到 onCreate
方法。所以像这样:
var view: View? = null
// OR
lateinit var view: View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
view = layoutInflater.inflate(R.layout.chat_file_options, null)
......
}