klappt mit multiplen vom originalen child monitor
This commit is contained in:
@@ -5,7 +5,7 @@ android {
|
|||||||
compileSdk 34
|
compileSdk 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "de.rochefort.childmonitor"
|
applicationId "com.example.childmonitor_multiple"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 14
|
versionCode 14
|
||||||
@@ -21,7 +21,7 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
}
|
}
|
||||||
namespace 'de.rochefort.childmonitor'
|
namespace 'com.example.childmonitor_multiple'
|
||||||
lint {
|
lint {
|
||||||
abortOnError true
|
abortOnError true
|
||||||
warning 'MissingTranslation'
|
warning 'MissingTranslation'
|
||||||
|
|||||||
@@ -14,10 +14,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.media.AudioFormat
|
import android.media.AudioFormat
|
||||||
import de.rochefort.childmonitor.audio.G711UCodec
|
|
||||||
|
|
||||||
object AudioCodecDefines {
|
object AudioCodecDefines {
|
||||||
const val FREQUENCY = 8000
|
const val FREQUENCY = 8000
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
@@ -28,7 +28,7 @@ import android.util.Log
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import de.rochefort.childmonitor.ListenService.ListenBinder
|
import com.example.childmonitor_multiple.ListenService.ListenBinder
|
||||||
|
|
||||||
class ListenActivity : Activity() {
|
class ListenActivity : Activity() {
|
||||||
// Don't attempt to unbind from the service unless the client has received some
|
// Don't attempt to unbind from the service unless the client has received some
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
@@ -28,7 +28,7 @@ import android.util.Log
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import de.rochefort.childmonitor.MonitorService.MonitorBinder
|
import com.example.childmonitor_multiple.MonitorService.MonitorBinder
|
||||||
|
|
||||||
class MonitorActivity : Activity() {
|
class MonitorActivity : Activity() {
|
||||||
private val connection: ServiceConnection = object : ServiceConnection {
|
private val connection: ServiceConnection = object : ServiceConnection {
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
@@ -91,6 +91,64 @@ class MonitorService : Service() {
|
|||||||
audioRecord.stop()
|
audioRecord.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private fun handleMultiClientStreaming(serverSocket: ServerSocket, clients: MutableList<Socket>) {
|
||||||
|
val frequency: Int = AudioCodecDefines.FREQUENCY
|
||||||
|
val channelConfiguration: Int = AudioCodecDefines.CHANNEL_CONFIGURATION_IN
|
||||||
|
val audioEncoding: Int = AudioCodecDefines.ENCODING
|
||||||
|
val bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding)
|
||||||
|
|
||||||
|
val audioRecord = AudioRecord(
|
||||||
|
MediaRecorder.AudioSource.MIC,
|
||||||
|
frequency,
|
||||||
|
channelConfiguration,
|
||||||
|
audioEncoding,
|
||||||
|
bufferSize
|
||||||
|
)
|
||||||
|
|
||||||
|
val pcmBufferSize = bufferSize * 2
|
||||||
|
val pcmBuffer = ShortArray(pcmBufferSize)
|
||||||
|
val ulawBuffer = ByteArray(pcmBufferSize)
|
||||||
|
|
||||||
|
try {
|
||||||
|
audioRecord.startRecording()
|
||||||
|
Log.i(TAG, "Mehrere Clients aktiv – Aufnahme gestartet.")
|
||||||
|
|
||||||
|
while (!Thread.currentThread().isInterrupted && !serverSocket.isClosed) {
|
||||||
|
val read = audioRecord.read(pcmBuffer, 0, bufferSize)
|
||||||
|
if (read > 0) {
|
||||||
|
val encoded: Int = AudioCodecDefines.CODEC.encode(pcmBuffer, read, ulawBuffer, 0)
|
||||||
|
|
||||||
|
synchronized(clients) {
|
||||||
|
val iterator = clients.iterator()
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
val client = iterator.next()
|
||||||
|
try {
|
||||||
|
val out = client.getOutputStream()
|
||||||
|
out.write(ulawBuffer, 0, encoded)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
try { client.close() } catch (ignored: IOException) {}
|
||||||
|
iterator.remove()
|
||||||
|
Log.w(TAG, "Client getrennt: ${client.inetAddress}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Streaming-Fehler", e)
|
||||||
|
} finally {
|
||||||
|
audioRecord.stop()
|
||||||
|
audioRecord.release()
|
||||||
|
synchronized(clients) {
|
||||||
|
clients.forEach {
|
||||||
|
try { it.close() } catch (_: IOException) {}
|
||||||
|
}
|
||||||
|
clients.clear()
|
||||||
|
}
|
||||||
|
Log.i(TAG, "Audioaufnahme beendet, alle Clients getrennt.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
Log.i(TAG, "ChildMonitor start")
|
Log.i(TAG, "ChildMonitor start")
|
||||||
@@ -130,15 +188,25 @@ class MonitorService : Service() {
|
|||||||
// Register the service so that parent devices can
|
// Register the service so that parent devices can
|
||||||
// locate the child device
|
// locate the child device
|
||||||
registerService(localPort)
|
registerService(localPort)
|
||||||
serverSocket.accept().use { socket ->
|
val clients = mutableListOf<Socket>()
|
||||||
Log.i(TAG, "Connection from parent device received")
|
|
||||||
|
|
||||||
// We now have a client connection.
|
// Thread zum Akzeptieren neuer Clients
|
||||||
// Unregister so no other clients will
|
Thread {
|
||||||
// attempt to connect
|
try {
|
||||||
unregisterService()
|
while (!Thread.currentThread().isInterrupted) {
|
||||||
serviceConnection(socket)
|
val client = serverSocket.accept()
|
||||||
|
client.tcpNoDelay = true
|
||||||
|
synchronized(clients) { clients.add(client) }
|
||||||
|
Log.i(TAG, "Neuer Client verbunden: ${client.inetAddress}")
|
||||||
}
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.e(TAG, "Client-Akzeptierungsfehler: ${e.message}")
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
|
||||||
|
// Aufnahme und Verteilung starten
|
||||||
|
handleMultiClientStreaming(serverSocket, clients)
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (this.connectionToken == currentToken) {
|
if (this.connectionToken == currentToken) {
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
* along with Child Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
* Taken from https://android.googlesource.com/platform/external/nist-sip/+/6f95fdeab4481188b6260041b41d1db12b101266/src/com/android/sip/media/G711UCodec.java
|
* Taken from https://android.googlesource.com/platform/external/nist-sip/+/6f95fdeab4481188b6260041b41d1db12b101266/src/com/android/sip/media/G711UCodec.java
|
||||||
* Adopted to the needs of the Child Monitor project.
|
* Adopted to the needs of the Child Monitor project.
|
||||||
*/
|
*/
|
||||||
package de.rochefort.childmonitor.audio
|
package com.example.childmonitor_multiple
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G.711 codec. This class provides u-law conversion.
|
* G.711 codec. This class provides u-law conversion.
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
tools:context="de.rochefort.childmonitor.MonitorActivity" >
|
tools:context="com.example.childmonitor_multiple.MonitorActivity" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/parentDeviceTitle"
|
android:id="@+id/parentDeviceTitle"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
tools:context="de.rochefort.childmonitor.MonitorActivity" >
|
tools:context="com.example.childmonitor_multiple.MonitorActivity" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/parentDeviceTitle"
|
android:id="@+id/parentDeviceTitle"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
tools:context="de.rochefort.childmonitor.MonitorActivity" >
|
tools:context="com.example.childmonitor_multiple.MonitorActivity" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/parentDeviceTitle"
|
android:id="@+id/parentDeviceTitle"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
tools:context="de.rochefort.childmonitor.MonitorActivity">
|
tools:context="com.example.childmonitor_multiple.MonitorActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@id/parentDeviceTitle"
|
android:id="@id/parentDeviceTitle"
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="15dip" />
|
android:layout_height="15dip" />
|
||||||
|
|
||||||
<de.rochefort.childmonitor.VolumeView
|
<com.example.childmonitor_multiple.VolumeView
|
||||||
android:id="@+id/volume"
|
android:id="@+id/volume"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:keepScreenOn="true"
|
android:keepScreenOn="true"
|
||||||
tools:context="de.rochefort.childmonitor.MonitorActivity" >
|
tools:context="com.example.childmonitor_multiple.MonitorActivity" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/childDeviceTitle"
|
android:id="@+id/childDeviceTitle"
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:keepScreenOn="true"
|
android:keepScreenOn="true"
|
||||||
tools:context="de.rochefort.childmonitor.MonitorActivity" >
|
tools:context="com.example.childmonitor_multiple.MonitorActivity" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/serviceTitle"
|
android:id="@+id/serviceTitle"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
tools:context="de.rochefort.childmonitor.StartActivity" >
|
tools:context="com.example.childmonitor_multiple.StartActivity" >
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/useChildDevice"
|
android:id="@+id/useChildDevice"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="app_name">Child Monitor</string>
|
<string name="app_name">Child Monitor Multiple Clients</string>
|
||||||
<string name="action_settings">Einstellungen</string>
|
<string name="action_settings">Einstellungen</string>
|
||||||
<string name="useAsParentDevice">Als Eltern-Gerät benutzen</string>
|
<string name="useAsParentDevice">Als Eltern-Gerät benutzen</string>
|
||||||
<string name="useAsChildDevice">Als Kind-Gerät benutzen</string>
|
<string name="useAsChildDevice">Als Kind-Gerät benutzen</string>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="app_name">ChildMonitor</string>
|
<string name="app_name">Child Monitor Multiple Clients</string>
|
||||||
<string name="action_settings">Instellingen</string>
|
<string name="action_settings">Instellingen</string>
|
||||||
<string name="useAsParentDevice">Gebruiken als ouderapparaat</string>
|
<string name="useAsParentDevice">Gebruiken als ouderapparaat</string>
|
||||||
<string name="useAsChildDevice">Gebruiken als kindapparaat</string>
|
<string name="useAsChildDevice">Gebruiken als kindapparaat</string>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="app_name">Child Monitor</string>
|
<string name="app_name">Child Monitor Multiple Clients</string>
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
<string name="useAsParentDevice">Use as Parent Device</string>
|
<string name="useAsParentDevice">Use as Parent Device</string>
|
||||||
<string name="useAsChildDevice">Use as Child Device</string>
|
<string name="useAsChildDevice">Use as Child Device</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user