-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Asilbek199816
committed
Aug 7, 2019
0 parents
commit 167ed91
Showing
52 changed files
with
2,773 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
*.iml | ||
.gradle | ||
/local.properties | ||
/.idea | ||
/.idea/caches | ||
/.idea/libraries | ||
/.idea/modules.xml | ||
/.idea/workspace.xml | ||
/.idea/navEditor.xml | ||
/.idea/assetWizardSettings.xml | ||
.DS_Store | ||
/build | ||
/captures | ||
.externalNativeBuild | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
apply plugin: 'com.android.application' | ||
|
||
apply plugin: 'kotlin-android' | ||
|
||
apply plugin: 'kotlin-android-extensions' | ||
|
||
android { | ||
compileSdkVersion 29 | ||
buildToolsVersion "29.0.0" | ||
defaultConfig { | ||
applicationId "uz.anor.clientserver" | ||
minSdkVersion 21 | ||
targetSdkVersion 29 | ||
versionCode 1 | ||
versionName "1.0" | ||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation fileTree(dir: 'libs', include: ['*.jar']) | ||
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | ||
implementation 'androidx.appcompat:appcompat:1.0.2' | ||
implementation 'androidx.core:core-ktx:1.0.2' | ||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | ||
testImplementation 'junit:junit:4.12' | ||
androidTestImplementation 'androidx.test:runner:1.2.0' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
24 changes: 24 additions & 0 deletions
24
app/src/androidTest/java/uz/anor/clientserver/ExampleInstrumentedTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package uz.anor.clientserver | ||
|
||
import androidx.test.InstrumentationRegistry | ||
import androidx.test.runner.AndroidJUnit4 | ||
|
||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
import org.junit.Assert.* | ||
|
||
/** | ||
* Instrumented test, which will execute on an Android device. | ||
* | ||
* See [testing documentation](http://d.android.com/tools/testing). | ||
*/ | ||
@RunWith(AndroidJUnit4::class) | ||
class ExampleInstrumentedTest { | ||
@Test | ||
fun useAppContext() { | ||
// Context of the app under test. | ||
val appContext = InstrumentationRegistry.getTargetContext() | ||
assertEquals("uz.anor.clientserver", appContext.packageName) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="uz.anor.clientserver"> | ||
|
||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> | ||
<uses-permission android:name="android.permission.INTERNET"/> | ||
<uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" /> | ||
<application | ||
android:allowBackup="true" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/AppTheme"> | ||
<activity android:name=".MainActivity"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN"/> | ||
|
||
<category android:name="android.intent.category.LAUNCHER"/> | ||
</intent-filter> | ||
</activity> | ||
<activity android:name=".Server"/> | ||
<activity android:name=".Client"/> | ||
<activity android:name=".ServerActivity"/> | ||
<activity android:name=".ClientActivity"/> | ||
</application> | ||
|
||
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
package uz.anor.clientserver | ||
|
||
import android.content.Context | ||
import android.graphics.Color | ||
import android.net.nsd.NsdManager | ||
import android.net.nsd.NsdServiceInfo | ||
import android.os.Bundle | ||
import android.os.Handler | ||
import android.util.Log | ||
import android.view.View | ||
import android.widget.EditText | ||
import android.widget.LinearLayout | ||
import android.widget.TextView | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.core.content.ContextCompat | ||
import java.io.* | ||
import java.net.InetAddress | ||
import java.net.Socket | ||
import java.net.UnknownHostException | ||
import java.text.SimpleDateFormat | ||
import java.util.* | ||
|
||
class Client : AppCompatActivity(), View.OnClickListener { | ||
private val TAG = "MRX" | ||
private var clientThread: ClientThread? = null | ||
private var thread: Thread? = null | ||
private var handler: Handler? = null | ||
|
||
|
||
private val SERVICE_NAME = "Client Device" | ||
private val SERVICE_TYPE = "_http._tcp." | ||
|
||
private var hostAddress: InetAddress? = null | ||
private var hostPort: Int = 0 | ||
private var mNsdManager: NsdManager? = null | ||
private var clientTextColor: Int = 0 | ||
private var msgList: LinearLayout? = null | ||
private var edMessage: EditText? = null | ||
|
||
internal var mDiscoveryListener: NsdManager.DiscoveryListener = object : NsdManager.DiscoveryListener { | ||
|
||
// Called as soon as service discovery begins. | ||
override fun onDiscoveryStarted(regType: String) { | ||
Log.d(TAG, "Service discovery started") | ||
} | ||
|
||
override fun onServiceFound(service: NsdServiceInfo) { | ||
// A service was found! Do something with it. | ||
Log.d(TAG, "Service discovery success : $service") | ||
Log.d(TAG, "Host = " + service.serviceName) | ||
Log.d(TAG, "port = " + service.port.toString()) | ||
|
||
if (service.serviceType != SERVICE_TYPE) { | ||
// Service type is the string containing the protocol and | ||
// transport layer for this service. | ||
Log.d(TAG, "Unknown Service Type: " + service.serviceType) | ||
} else if (service.serviceName == SERVICE_NAME) { | ||
// The name of the service tells the user what they'd be | ||
// connecting to. It could be "Bob's Chat App". | ||
Log.d(TAG, "Same machine: $SERVICE_NAME") | ||
} else { | ||
Log.d(TAG, "Diff Machine : " + service.serviceName) | ||
// connect to the service and obtain serviceInfo | ||
|
||
mNsdManager!!.resolveService(service, object : NsdManager.ResolveListener { | ||
|
||
override fun onResolveFailed(nsdServiceInfo: NsdServiceInfo, errorCode: Int) { | ||
Log.e(TAG, "Resolve failed $errorCode") | ||
Log.e(TAG, "serivce = $nsdServiceInfo") | ||
} | ||
|
||
override fun onServiceResolved(serviceInfo: NsdServiceInfo) { | ||
Log.d(TAG, "Resolve Succeeded. $serviceInfo") | ||
|
||
if (serviceInfo.serviceName == SERVICE_NAME) { | ||
Log.d(TAG, "Same IP.") | ||
return | ||
} | ||
|
||
// Obtain port and IP | ||
hostPort = serviceInfo.port | ||
hostAddress = serviceInfo.host | ||
Log.d(TAG, "hostPort=$hostPort") | ||
Log.d(TAG, "hostAddess=" + hostAddress!!) | ||
if (serviceInfo.serviceName.equals(Server.SERVICE_NAME) && serviceInfo.serviceType.equals(Server.SERVICE_TYPE)) | ||
SERVER_IP = hostAddress!!.hostAddress | ||
|
||
} | ||
}) | ||
} | ||
} | ||
|
||
override fun onServiceLost(service: NsdServiceInfo) { | ||
// When the network service is no longer available. | ||
// Internal bookkeeping code goes here. | ||
Log.e(TAG, "service lost$service") | ||
} | ||
|
||
override fun onDiscoveryStopped(serviceType: String) { | ||
Log.i(TAG, "Discovery stopped: $serviceType") | ||
} | ||
|
||
override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) { | ||
Log.e(TAG, "Discovery failed: Error code:$errorCode") | ||
mNsdManager!!.stopServiceDiscovery(this) | ||
} | ||
|
||
override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) { | ||
Log.e(TAG, "Discovery failed: Error code:$errorCode") | ||
mNsdManager!!.stopServiceDiscovery(this) | ||
} | ||
} | ||
|
||
internal val time: String | ||
get() { | ||
val sdf = SimpleDateFormat("HH:mm:ss") | ||
return sdf.format(Date()) | ||
} | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.ac_client) | ||
|
||
title = "Client" | ||
clientTextColor = ContextCompat.getColor(this, R.color.green) | ||
msgList = findViewById(R.id.msgList) | ||
edMessage = findViewById(R.id.edMessage) | ||
|
||
handler = Handler() | ||
mNsdManager = getSystemService(Context.NSD_SERVICE) as NsdManager | ||
// mNsdManager.discoverServices(SERVICE_TYPE, | ||
// NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); | ||
} | ||
|
||
override fun onPause() { | ||
if (mNsdManager != null) { | ||
mNsdManager!!.stopServiceDiscovery(mDiscoveryListener) | ||
} | ||
super.onPause() | ||
} | ||
|
||
override fun onResume() { | ||
super.onResume() | ||
if (mNsdManager != null) { | ||
mNsdManager!!.discoverServices( | ||
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener | ||
) | ||
} | ||
|
||
} | ||
////////////////////////////////////////////// | ||
|
||
fun textView(message: String?, color: Int): TextView { | ||
var message = message | ||
if (null == message || message.trim { it <= ' ' }.isEmpty()) { | ||
message = "<Empty Message>" | ||
} | ||
val tv = TextView(this) | ||
tv.setTextColor(color) | ||
tv.text = "$message [$time]" | ||
tv.textSize = 20f | ||
tv.setPadding(0, 5, 0, 0) | ||
return tv | ||
} | ||
|
||
fun showMessage(message: String, color: Int) { | ||
handler!!.post { msgList!!.addView(textView(message, color)) } | ||
} | ||
|
||
override fun onClick(view: View) { | ||
|
||
if (view.id == R.id.connect_server) { | ||
msgList!!.removeAllViews() | ||
showMessage("Connecting to Server...", clientTextColor) | ||
clientThread = ClientThread() | ||
thread = Thread(clientThread) | ||
thread!!.start() | ||
showMessage("Connected to Server...", clientTextColor) | ||
return | ||
} | ||
|
||
if (view.id == R.id.send_data) { | ||
val clientMessage = edMessage!!.text.toString().trim { it <= ' ' } | ||
showMessage(clientMessage, Color.BLUE) | ||
if (null != clientThread) { | ||
clientThread!!.sendMessage(clientMessage) | ||
} | ||
} | ||
} | ||
|
||
internal inner class ClientThread : Runnable { | ||
|
||
private var socket: Socket? = null | ||
private var input: BufferedReader? = null | ||
|
||
override fun run() { | ||
|
||
try { | ||
val serverAddr = InetAddress.getByName(SERVER_IP) | ||
socket = Socket(serverAddr, SERVERPORT) | ||
|
||
while (!Thread.currentThread().isInterrupted) { | ||
|
||
this.input = BufferedReader(InputStreamReader(socket!!.getInputStream())) | ||
var message: String? = input!!.readLine() | ||
if (null == message || "Disconnect".contentEquals(message)) { | ||
Thread.interrupted() | ||
message = "Server Disconnected." | ||
showMessage(message, Color.RED) | ||
break | ||
} | ||
showMessage("Server: $message", clientTextColor) | ||
} | ||
|
||
} catch (e1: UnknownHostException) { | ||
e1.printStackTrace() | ||
} catch (e1: IOException) { | ||
e1.printStackTrace() | ||
} | ||
|
||
} | ||
|
||
fun sendMessage(message: String) { | ||
Thread(Runnable { | ||
try { | ||
if (null != socket) { | ||
val out = PrintWriter( | ||
BufferedWriter( | ||
OutputStreamWriter(socket!!.getOutputStream()) | ||
), | ||
true | ||
) | ||
out.println(message) | ||
} | ||
} catch (e: Exception) { | ||
e.printStackTrace() | ||
} | ||
}).start() | ||
} | ||
|
||
} | ||
|
||
override fun onDestroy() { | ||
// if (mNsdManager != null) { | ||
// mNsdManager.stopServiceDiscovery(mDiscoveryListener); | ||
// } | ||
super.onDestroy() | ||
if (null != clientThread) { | ||
clientThread!!.sendMessage("Disconnect") | ||
clientThread = null | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
val SERVERPORT = 3003 | ||
|
||
var SERVER_IP = "192.168.0.189" | ||
} | ||
} |
Oops, something went wrong.