mirror of
https://gitlab.com/futo-org/fcast.git
synced 2025-08-09 18:52:50 +00:00
Added QR code.
This commit is contained in:
parent
eed50283bb
commit
b339f4f487
6 changed files with 336 additions and 37 deletions
|
@ -84,6 +84,7 @@ dependencies {
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0"
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0"
|
||||||
implementation 'com.google.android.exoplayer:exoplayer:2.18.6'
|
implementation 'com.google.android.exoplayer:exoplayer:2.18.6'
|
||||||
implementation "com.squareup.okhttp3:okhttp:4.11.0"
|
implementation "com.squareup.okhttp3:okhttp:4.11.0"
|
||||||
|
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
|
||||||
android:theme="@style/Theme.Main"
|
android:theme="@style/Theme.Main"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
|
@ -12,7 +12,9 @@ import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.util.Base64
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
|
@ -24,7 +26,11 @@ import com.google.android.exoplayer2.ExoPlayer
|
||||||
import com.google.android.exoplayer2.MediaItem
|
import com.google.android.exoplayer2.MediaItem
|
||||||
import com.google.android.exoplayer2.Player
|
import com.google.android.exoplayer2.Player
|
||||||
import com.google.android.exoplayer2.ui.StyledPlayerView
|
import com.google.android.exoplayer2.ui.StyledPlayerView
|
||||||
|
import com.google.zxing.BarcodeFormat
|
||||||
|
import com.journeyapps.barcodescanner.BarcodeEncoder
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
@ -42,6 +48,9 @@ class MainActivity : AppCompatActivity() {
|
||||||
private lateinit var _videoBackground: StyledPlayerView
|
private lateinit var _videoBackground: StyledPlayerView
|
||||||
private lateinit var _viewDemo: View
|
private lateinit var _viewDemo: View
|
||||||
private lateinit var _player: ExoPlayer
|
private lateinit var _player: ExoPlayer
|
||||||
|
private lateinit var _imageQr: ImageView
|
||||||
|
private lateinit var _textScanToConnect: TextView
|
||||||
|
private var _updateAvailable: Boolean? = null
|
||||||
private var _updating: Boolean = false
|
private var _updating: Boolean = false
|
||||||
private var _demoClickCount = 0
|
private var _demoClickCount = 0
|
||||||
private var _lastDemoToast: Toast? = null
|
private var _lastDemoToast: Toast? = null
|
||||||
|
@ -53,6 +62,12 @@ class MainActivity : AppCompatActivity() {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
if (savedInstanceState != null && savedInstanceState.containsKey("updateAvailable")) {
|
||||||
|
_updateAvailable = savedInstanceState.getBoolean("updateAvailable", false)
|
||||||
|
} else {
|
||||||
|
_updateAvailable = null
|
||||||
|
}
|
||||||
|
|
||||||
_buttonUpdate = findViewById(R.id.button_update)
|
_buttonUpdate = findViewById(R.id.button_update)
|
||||||
_text = findViewById(R.id.text_dialog)
|
_text = findViewById(R.id.text_dialog)
|
||||||
_textIPs = findViewById(R.id.text_ips)
|
_textIPs = findViewById(R.id.text_ips)
|
||||||
|
@ -62,6 +77,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
_layoutConnectionInfo = findViewById(R.id.layout_connection_info)
|
_layoutConnectionInfo = findViewById(R.id.layout_connection_info)
|
||||||
_videoBackground = findViewById(R.id.video_background)
|
_videoBackground = findViewById(R.id.video_background)
|
||||||
_viewDemo = findViewById(R.id.view_demo)
|
_viewDemo = findViewById(R.id.view_demo)
|
||||||
|
_imageQr = findViewById(R.id.image_qr)
|
||||||
|
_textScanToConnect = findViewById(R.id.text_scan_to_connect)
|
||||||
|
|
||||||
startVideo()
|
startVideo()
|
||||||
startAnimations()
|
startAnimations()
|
||||||
|
@ -105,13 +122,28 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_textIPs.text = "IPs\n" + getIPs().joinToString("\n") + "\n\nPort\n46899"
|
val ips = getIPs()
|
||||||
|
_textIPs.text = "IPs\n" + ips.joinToString("\n") + "\n\nPort\n46899"
|
||||||
|
|
||||||
|
try {
|
||||||
|
val barcodeEncoder = BarcodeEncoder()
|
||||||
|
val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100.0f, resources.displayMetrics).toInt()
|
||||||
|
val json = Json.encodeToString(FCastNetworkConfig(ips, listOf(
|
||||||
|
FCastService(46899, 0)
|
||||||
|
)))
|
||||||
|
val base64 = Base64.encode(json.toByteArray(), Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP)
|
||||||
|
val url = "fcast://r/${base64}"
|
||||||
|
val bitmap = barcodeEncoder.encodeBitmap(url, BarcodeFormat.QR_CODE, px, px)
|
||||||
|
_imageQr.setImageBitmap(bitmap)
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
_textScanToConnect.visibility = View.GONE
|
||||||
|
_imageQr.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
TcpListenerService.activityCount++
|
TcpListenerService.activityCount++
|
||||||
|
|
||||||
if (checkAndRequestPermissions()) {
|
checkAndRequestPermissions()
|
||||||
Log.i(TAG, "Notification permission already granted")
|
if (savedInstanceState == null) {
|
||||||
restartService()
|
|
||||||
} else {
|
|
||||||
restartService()
|
restartService()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +170,11 @@ class MainActivity : AppCompatActivity() {
|
||||||
TcpListenerService.activityCount--
|
TcpListenerService.activityCount--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
_updateAvailable?.let { outState.putBoolean("updateAvailable", it) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun restartService() {
|
private fun restartService() {
|
||||||
val i = TcpListenerService.instance
|
val i = TcpListenerService.instance
|
||||||
if (i != null) {
|
if (i != null) {
|
||||||
|
@ -294,6 +331,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
private suspend fun checkForUpdates() {
|
private suspend fun checkForUpdates() {
|
||||||
Log.i(TAG, "Checking for updates...")
|
Log.i(TAG, "Checking for updates...")
|
||||||
|
|
||||||
|
val updateAvailable = _updateAvailable
|
||||||
|
if (updateAvailable != null) {
|
||||||
|
setUpdateAvailable(updateAvailable)
|
||||||
|
} else {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val latestVersion = downloadVersionCode()
|
val latestVersion = downloadVersionCode()
|
||||||
|
@ -302,26 +343,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
val currentVersion = BuildConfig.VERSION_CODE
|
val currentVersion = BuildConfig.VERSION_CODE
|
||||||
Log.i(TAG, "Current version $currentVersion latest version $latestVersion.")
|
Log.i(TAG, "Current version $currentVersion latest version $latestVersion.")
|
||||||
|
|
||||||
if (latestVersion > currentVersion) {
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
try {
|
setUpdateAvailable(latestVersion > currentVersion)
|
||||||
(_updateSpinner.drawable as Animatable?)?.stop()
|
|
||||||
_updateSpinner.visibility = View.INVISIBLE
|
|
||||||
setText(resources.getText(R.string.there_is_an_update_available_do_you_wish_to_update))
|
|
||||||
_buttonUpdate.visibility = View.VISIBLE
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
Toast.makeText(this@MainActivity, "Failed to show update dialog", Toast.LENGTH_LONG).show()
|
|
||||||
Log.w(TAG, "Error occurred in update dialog.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
_updateSpinner.visibility = View.INVISIBLE
|
|
||||||
_buttonUpdate.visibility = View.INVISIBLE
|
|
||||||
//setText(getString(R.string.no_updates_available))
|
|
||||||
setText(null)
|
|
||||||
//Toast.makeText(this@MainActivity, "Already on latest version", Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Failed to retrieve version from version URL.")
|
Log.w(TAG, "Failed to retrieve version from version URL.")
|
||||||
|
@ -339,6 +362,27 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setUpdateAvailable(updateAvailable: Boolean) {
|
||||||
|
if (updateAvailable) {
|
||||||
|
try {
|
||||||
|
(_updateSpinner.drawable as Animatable?)?.stop()
|
||||||
|
_updateSpinner.visibility = View.INVISIBLE
|
||||||
|
setText(resources.getText(R.string.there_is_an_update_available_do_you_wish_to_update))
|
||||||
|
_buttonUpdate.visibility = View.VISIBLE
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Toast.makeText(this@MainActivity, "Failed to show update dialog", Toast.LENGTH_LONG).show()
|
||||||
|
Log.w(TAG, "Error occurred in update dialog.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_updateSpinner.visibility = View.INVISIBLE
|
||||||
|
_buttonUpdate.visibility = View.INVISIBLE
|
||||||
|
setText(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateAvailable = updateAvailable
|
||||||
|
}
|
||||||
|
|
||||||
private fun downloadVersionCode(): Int? {
|
private fun downloadVersionCode(): Int? {
|
||||||
val client = OkHttpClient()
|
val client = OkHttpClient()
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.futo.fcast.receiver
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class FCastNetworkConfig(
|
||||||
|
val ips: List<String>,
|
||||||
|
val services: List<FCastService>
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class FCastService(
|
||||||
|
val port: Int,
|
||||||
|
val type: Int
|
||||||
|
)
|
215
receivers/android/app/src/main/res/layout-land/activity_main.xml
Normal file
215
receivers/android/app/src/main/res/layout-land/activity_main.xml
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#000000">
|
||||||
|
|
||||||
|
<com.google.android.exoplayer2.ui.StyledPlayerView
|
||||||
|
android:id="@+id/video_background"
|
||||||
|
app:use_controller="false"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:resize_mode="zoom" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/view_demo"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="FCast"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter_bold"
|
||||||
|
android:textSize="40sp"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/layout_connection_info"/>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/layout_connection_info"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@drawable/background_manual_connect"
|
||||||
|
android:paddingStart="25dp"
|
||||||
|
android:paddingEnd="25dp"
|
||||||
|
android:paddingTop="25dp"
|
||||||
|
android:paddingBottom="25dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_title"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/text_dialog">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_waiting_for_connection"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:text="Waiting for a connection"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/text_manual_connection_information" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_spinner"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
app:srcCompat="@drawable/ic_loader_animated"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_waiting_for_connection"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_waiting_for_connection"
|
||||||
|
app:layout_constraintLeft_toRightOf="@id/text_waiting_for_connection" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_manual_connection_information"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#919191"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter_light"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:text="Manual connection information"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_waiting_for_connection"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/text_scan_to_connect"
|
||||||
|
app:layout_constraintBottom_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_ips"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:text="IPs\n192.168.1.3\n\nPort\n46899"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_manual_connection_information"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/text_manual_connection_information"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/text_manual_connection_information"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/text_automatic_discovery" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_qr"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_ips"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/text_scan_to_connect"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/text_scan_to_connect"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_ips" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_scan_to_connect"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#919191"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:text="Scan to connect"
|
||||||
|
android:layout_marginStart="50dp"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_manual_connection_information"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_manual_connection_information"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/text_manual_connection_information"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_automatic_discovery"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#919191"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:text="Automatic discovery is available via mDNS"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_ips"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_dialog"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/there_is_an_update_available_do_you_wish_to_update"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:paddingStart="30dp"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/layout_connection_info"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/button_update" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/button_update"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/background_button_primary"
|
||||||
|
android:layout_marginEnd="2dp"
|
||||||
|
android:clickable="true"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_dialog"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/update"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:paddingStart="28dp"
|
||||||
|
android:paddingEnd="28dp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/text_dialog"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_dialog"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_dialog">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/update_spinner"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
app:srcCompat="@drawable/ic_update_animated" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_progress"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text=""
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:fontFamily="@font/inter_regular" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -118,6 +118,31 @@
|
||||||
app:layout_constraintTop_toBottomOf="@id/text_ips"
|
app:layout_constraintTop_toBottomOf="@id/text_ips"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/image_qr"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_qr"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_automatic_discovery"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/text_scan_to_connect" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_scan_to_connect"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#919191"
|
||||||
|
android:gravity="center"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:text="Scan to connect"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/image_qr"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue