Android之间在在局域网下互传消息,咱就不用走云服务器了吧,让俩安卓设备,自己传呗
方式1 通过在安卓设备上搭建Web服务器接收数据,可参考
Android使用AndServer在安卓设备上搭建服务端(Java)(Kotlin)两种写法
方式2 本文章,搭建Socket服务器,接收数据,发送TCP
此类文章网上一大堆,不多做讲解,直接上代码,自行参考
清单文件中添加权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
MainActivity
class MainActivity : AppCompatActivity() {
var mBinding: ActivityMainBinding? = null
var timer: Timer? = null
var mSocket: Socket? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
this.window.statusBarColor = this.resources.getColor(R.color.white)
this.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
requestPermission()
mBinding!!.tv1.setOnClickListener {
val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
startActivity(intent)
}
}
override fun onResume() {
super.onResume()
if (mSocket != null){
mSocket!!.close()
mSocket = null
}
initServer()
//定时器
if (timer != null){
timer!!.cancel()
timer = null
}
timer = Timer()
val timerTask: TimerTask = object : TimerTask() {
override fun run() {
runOnUiThread {
//每次刷新再次操作
//加个定时器,动态获取ip地址
mBinding!!.tv1.text = "本机IP:${getLocalIpAddress()},端口号: 8020"
}
}
}
timer?.schedule(timerTask, 0, 1000) //开启刷新,第二个参数是多长时间之后开始倒计时,第三个参数是多长时间进行一次
}
private fun initServer(){
object : Thread() {
override fun run() {
try {
// 创建ServerSocket E5 93 88 E5 93 88 E5 93 88 E5 93 88 0A
val serverSocket = ServerSocket(8020)
Log.e("TAG","32131232321--开启服务器,监听端口 9569--" + getLocalIpAddress())
// 监听端口,等待客户端连接
while (true) {
Log.e("TAG","32131232321--等待客户端连接--")
mSocket = serverSocket.accept() //等待客户端连接
Log.e("TAG","32131232321---得到客户端连接:$mSocket")
mBinding!!.tv2.post {
mBinding!!.tv2.text = "当前连接IP:${mSocket}"
}
startReader(mSocket!!)
}
} catch (e: IOException) {
e.printStackTrace()
}
}
}.start()
}
// 获取ip地址
private fun getLocalIpAddress(): String? {
val netManager =
applicationContext.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val info = netManager.activeNetworkInfo
// 网络是否连接
return if (info != null && info.isConnected) {
// wifi类型
if (info.type == ConnectivityManager.TYPE_WIFI) {
getWifiIpAddress()
} else {
// 其他类型
getEthIpAddress()
}
} else "0.0.0.0"
}
// 获取有线网络的ip4地址
private fun getEthIpAddress(): String? {
val infaceName = "eth0"
val ip = "0.0.0.0"
try {
val netInterface: Enumeration<NetworkInterface> =
NetworkInterface.getNetworkInterfaces()
while (netInterface.hasMoreElements()) {
val inface: NetworkInterface = netInterface.nextElement()
if (!inface.isUp()) {
continue
}
// eth0 有线网络判断
if (infaceName != inface.getDisplayName()) {
continue
}
val netAddressList: Enumeration<InetAddress> = inface.getInetAddresses()
while (netAddressList.hasMoreElements()) {
val inetAddress: InetAddress = netAddressList.nextElement()
// 获取IP4地址
if (inetAddress is Inet4Address) {
return inetAddress.getHostAddress()
}
}
}
} catch (e: Exception) {
}
return ip
}
// 获取wifi的ip地址
private fun getWifiIpAddress(): String? {
val wifiManager = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
val wifiInfo = wifiManager.connectionInfo
// 获取32位整型IP地址
val ipAddress = wifiInfo.ipAddress
//返回整型地址转换成“*.*.*.*”地址
return String.format(
"%d.%d.%d.%d",
ipAddress and 0xff, ipAddress shr 8 and 0xff,
ipAddress shr 16 and 0xff, ipAddress shr 24 and 0xff
)
}
/**
* 从参数的Socket里获取消息
*/
private fun startReader(mSocket: Socket) {
object : Thread() {
override fun run() {
try {
// 获取读取流
val ins = mSocket.getInputStream()
val buf = ByteArray(32)
//获取数据赋值
while (ins.read(buf) > 0) {
//收到客户端发送的数据之后再发
//serverSendMessage(getAppData())
mBinding!!.tvId.post {
var mS = mBinding!!.tvId.text.toString();
mS += String(buf)
mBinding!!.tvId.text = mS
setML(String(buf))
}
/*if (buf != null) {
//延迟销毁
runOnUiThread {
Handler().postDelayed({
ins.close()
if (mSocket != null){
mSocket.close()
}
}, 3000)
}
}*/
}
} catch (e: IOException) {
e.printStackTrace()
}
}
}.start()
/*object : Thread() {
override fun run() {
try {
// 获取读取流
val mIn = BufferedReader(InputStreamReader(mSocket.getInputStream(), "utf-8"))
var line = ""
Log.e("TAG","32131232321---*等待客户端输入---13132321*---")
while (mIn.readLine().also { line = it } != null) { // 读取数据
Log.e("TAG","32131232321---*等待客户端输入*")
Log.e("TAG","32131232321----获取到客户端的信息:$line")
}
} catch (e: IOException) {
e.printStackTrace()
}
}
}.start()*/
}
//通过socket来给客户端发送消息
private fun serverSendMessage(mServerSendMessage: String) {
object : Thread() {
override fun run() {
val out: PrintWriter
try {
out = PrintWriter(
BufferedWriter(OutputStreamWriter(mSocket!!.getOutputStream())),
true
)
Log.e("TAG","32131232321---发送给客户数据*---" + mServerSendMessage)
out.println(mServerSendMessage)
} catch (e: IOException) {
e.printStackTrace()
}
}
}.start()
}
/*动态申请权限操作*/
private var isPermissionRequested = false
private fun requestPermission() {
if (Build.VERSION.SDK_INT >= 23 && !isPermissionRequested) {
isPermissionRequested = true
val permissionsList: ArrayList<String> = ArrayList()
val permissions = arrayOf<String>(
//在这里加入你要使用的权限
Manifest.permission.READ_CONTACTS,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.READ_CALENDAR,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_CONTACTS,
Manifest.permission.ACCESS_WIFI_STATE,
)
for (perm in permissions) {
if (PackageManager.PERMISSION_GRANTED != checkSelfPermission(perm)) {
permissionsList.add(perm)
// 进入这里代表没有权限.
}
}
if (permissionsList.isNotEmpty()) {
val strings = arrayOfNulls<String>(permissionsList.size)
requestPermissions(permissionsList.toArray(strings), 0)
}
}
}
//单独处理命令
private fun setML(ml: String){
if (ml.contains("xc")){
val intent = Intent(Intent.ACTION_PICK)
//指定获取的是图片
intent.type = "image/*"
startActivityForResult(intent,10086)
}
if (ml.contains("qc")){
mBinding!!.tvId.post {
mBinding!!.tvId.text = ""
}
}
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#000000"
android:text="本机IP"/>
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginTop="10dp"
android:textColor="#000000"
android:text="未连接"/>
<TextView
android:id="@+id/tv_id"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</androidx.appcompat.widget.LinearLayoutCompat>
</layout>
因为用到了 DataBind,这里提一下吧