I have a navigation drawer app in android studio using Kotlin v1.7.10 and gradle 7.2.2.
The idea is this: when we have internet, open a WebView in the default fragment, and if there is no internet, open a layout with internet error message.
I added a new Kotlin file in MainActivity.kt root called "LiveData_internet_Connections.kt"
the code of that file is this:
package com.myapp.app
import android.app.Application
import android.content.ContentValues
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
class LiveDataInternetConnections(private val connectivityManager: ConnectivityManager):
LiveData<Boolean>(){
constructor(appContext: Application) : this(
appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
)
private val networkCallback =
object : ConnectivityManager.NetworkCallback(){
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.d(ContentValues.TAG, "onAvailable: Network $network is Available")
postValue(true)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities) {
val isInternet = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
Log.d(ContentValues.TAG, "networkCapabilities: $network $networkCapabilities")
val isValidated = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
if (isValidated){
Log.d(ContentValues.TAG, "hasCapability: $network $networkCapabilities")
} else{
Log.d(ContentValues.TAG, "Network has No Connection Capability: $network $networkCapabilities")
}
postValue(isInternet && isValidated)
}
override fun onLost(network: Network) {
super.onLost(network)
Log.d(ContentValues.TAG, "onLost: $network Network Lost")
postValue(false)
}
}
override fun onActive() {
super.onActive()
val builder = NetworkRequest.Builder()
connectivityManager.registerNetworkCallback(builder
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), networkCallback)
}
override fun onInactive() {
super.onInactive()
connectivityManager.unregisterNetworkCallback(networkCallback)
}
}
this is the MainActivity.kt for above code, is working perfectly if I don´t use navigation drawer:
package com.myapp.app
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.webkit.WebView
import android.widget.TextView
class MainActivity : AppCompatActivity() {
private lateinit var TextView1 : WebView
private lateinit var TextView2 : TextView
private lateinit var cld : LiveDataInternetConnections
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
TextView1 = findViewById(R.id.connected)
TextView2 = findViewById(R.id.not_connected)
cld = LiveDataInternetConnections(application)
cld.observe(this) { isConnected ->
if (isConnected) {
TextView1.visibility = View.VISIBLE
TextView2.visibility = View.GONE
} else {
TextView1.visibility = View.GONE
TextView2.visibility = View.VISIBLE
}
}
}
}
And the activity_main.xml in my test is using 2 TextViews with id´s "connected" and "disconnected":
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#FAFAFA"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/connected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0B0A0A"
android:gravity="center"
android:text="Connected"
android:textColor="#ff669900"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="699dp" />
<TextView
android:id="@+id/not_connected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0B0A0A"
android:gravity="center"
android:text="No Connection"
android:textColor="#ffcc0000"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
android:textStyle="bold"
android:visibility="gone"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="699dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
I tried to add the textViews from activity_main.xml to my fragment_home.xml file, and pasted the Kotlin File "LiveData_internet_Connections.kt" and paste code from MainActivity, to my HomeFragment.kt file, but I get error.(Expecting member declaration)
this is my HomeFragment.kt file:
package com.myDrawer.app.ui.home
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.*
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.cbrweb.rosario.LiveDataInternetConnections
import com.cbrweb.rosario.R
//tested pasted code
//private lateinit var TextView1 : TextView
//private lateinit var TextView2 : TextView
private lateinit var cld : LiveDataInternetConnections
//tested pasted code
class HomeFragment : Fragment() {
@SuppressLint("SetJavaScriptEnabled")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
//▼▼▼▼▼▼▼▼ Code for WebView OK ▼▼▼▼▼▼▼▼
val v = inflater.inflate(R.layout.fragment_home, container, false)
val mWebView = v.findViewById<View>(R.id.webViewHome) as WebView
mWebView.loadUrl("https://rosario.modotriunfo.com/rosario")
// Enable Javascript
val webSettings: WebSettings = mWebView.settings
webSettings.javaScriptEnabled = true
// Force links and redirects to open in the WebView instead of in a browser
mWebView.webViewClient = WebViewClient()
// Go Back
mWebView.canGoBack()
mWebView.setOnKeyListener(View.OnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.action == MotionEvent.ACTION_UP
&& mWebView.canGoBack()) {
mWebView.goBack()
return@OnKeyListener true
}
false
})
return v
}
//▲▲▲▲▲▲▲▲ Code for WebView OK ▲▲▲▲▲▲▲▲
// tested pasted code
// TextView1 = findViewById(R.id.connected)
// TextView2 = findViewById(R.id.not_connected)
// cld = LiveDataInternetConnections(application)
// cld.observe(viewLifecycleOwner) { isConnected ->
// if (isConnected) {
// TextView1.visibility = View.VISIBLE
// TextView2.visibility = View.GONE
// } else {
// TextView1.visibility = View.GONE
// TextView2.visibility = View.VISIBLE
// }
// tested pasted code
}