目录结构
- 53. build.gradle+CMakeList.txt 实现编译脚本控制
- 52.tts文字转语音
- 51.获取指定sim卡槽的信号强度
- 50.android 13的PackageManagerService相关的解析部分说明
- 49. Warning: "/system/app/xxx/lib/arm/xxxx.so" has text relocations
- 48. tcp/udp socket通信小demo
- 47. debug调试脚本
- 46.webrtc降噪去回声
- 45.动态替换开机logo参考
- 44.概率性录像4K oom异常
- 43.iptables配置网络防火墙,只允许访问指定ip网段
- 42. 实现MediaRecorder按时间分段且不存在下一段视频和这一段存在较长的时间间隔
- 42.Android OpenGLES渲染灭屏水印抖动问题(无效修改... 有时候可以)
- 41.C++判断是否是合法的ip地址
- 40. OpenGL渲染后graphics内存不释放问题
- 39.高版本静默安装apk
- 38. android ffmpeg so文件编译
- 37.图片插值放大
- 36.后台录像待机功耗高的原因
- 35.MediaCodec录像的视频异常问题总结
- 34.build.gradle多变种基本配置
- 38. ubuntu 添加应用到收藏夹
- 37.ubuntu重启添加确认
- 36.ubuntu美化
- 35. ubuntu离线安装以太网卡驱动(r8125网卡驱动)
- 34.自定义sharedPreference保存的xm路径
- 33.快速生成dimens文件
- 32.根据uri获取文件md5
- 31.子控件跟随父控件状态
- 30. Android 进程保活
- 29.预置so到源码中遇到异常
- 28.模拟按键事件
- 27.模拟触摸事件
- 26.Android编译报错汇总
- 25. applicationContext弹出对话框
- 24.设备跌落检测
- 23.WallpaperPicker 原图显示
- 22.wifi概率性掉线与掉线重连问题
- 21.Android高版本允许应用调用hideapi 反射
- 20.Android 11 强制横屏所有应用
- 19.makefile中的比较内容
- 18.自定义prop带空格
- 17. Android默认关闭WIFI可达性检测,以防wifi无法自动重连
- 16. Android bp预置无源码apk
- 15.以太网开关
- 14.WiFi热点打开5G频段支持
- 13.记一次Android 12移植原生设置异常
- 12.MediaCodec: configure failed with err 0xffffffea, resetting...
- 11. Invalid revision: 3.18.1-g262b901
- 10. 下载高版本Android studio网站
- 9.移植settingslib的一些总结
- 8.AIDL的一次错误总结
- 7.反射机制调用系统服务EthernetManager
- 6.判断系统是升级还是第一次开机
- 5.新增kernel config。在头文件中使用该宏定义
- 4.shell脚本获取值
- 4.Android 分区大小修改
- 3.MediaCodeC解码本地视频文件
- 2.libyuv的使用
- 1.摄像头拍照录像相关
- 0.鼠标未触发ontouch ACITON_MOVE事件
- Android.mk引入aidl文件
53. build.gradle+CMakeList.txt 实现编译脚本控制
build.gradle
arguments "-DPRODUCT_NAME=AHKY"
defaultConfig {
。。。。
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
cppFlags "-frtti -fexceptions -std=c++11"
arguments "-DANDROID_STL=c++_shared"
abiFilters 'armeabi-v7a' //, "arm64-v8a"
arguments "-DPRODUCT_NAME=TESTAAB" //这里的意思是新增一个宏名称为PRODUCT_NAME 值为TESTAAB的宏
}
}
CMakeList.txt
# 打印消息,在 build output 中可以查看
# 打印所有参数 这里是打印所有arguments生成的信息
#get_cmake_property(_variableNames VARIABLES)
#list (SORT _variableNames)
#foreach (_variableName ${_variableNames})
# message(WARNING "params: ${_variableName}=${${_variableName}}")
#endforeach()
if("${PRODUCT_NAME}" STREQUAL "TESTAAB")
message(WARNING "这是一条测试项目.... ${CMAKE_SOURCE_DIR}")
#add_definitions(-DTESTAAB) //这行代码的作用是生成一个define 。在c++和头文件中可以直接使用
else()
message(WARNING "project name not defined")
add_definitions(-DNO_PROJECT)
#导入第三方so包,并声明为 IMPORTED 属性,指明只是想把 so 导入到项目中
endif()
# 通过参数来控制要打开哪个宏
52.tts文字转语音
需要apk预置且设置了文字转语音的应用
https://www.alipan.com/t/lJIbi8kop09Jpj3Zh5lv
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.speech.tts.Voice;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;
public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {
private static final String TAG = "MainActivity";
private TextToSpeech tts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this, this, "com.iflytek.speechcloud");
//getSharedPreferences("com.huadean.tcpudptest_preference", Context.MODE_PRIVATE).edit().putBoolean("tts_engine", true).apply();
//tts = new TextToSpeech(this, this, "com.google.android.tts");
}
@Override
public void onInit(int status) {
Log.e(TAG, "onInit: " + status);
if (status == TextToSpeech.SUCCESS) {
int retSetLanguage = tts.setLanguage(Locale.CHINESE);
// for (TextToSpeech.EngineInfo engine : tts.getEngines()) {
// Log.i(TAG, "onInit: engine voice "+engine.name +" tts.getDefaultEngine(); "+ tts.getDefaultEngine());
// }
//
// for (Voice voice : tts.getVoices()) {
// Log.i(TAG, "onInit: support voice "+voice.getLocale().getDisplayName());
// }
Log.d(TAG, "onInit() called with: status = [" +retSetLanguage+ "]");
if (retSetLanguage == TextToSpeech.LANG_AVAILABLE) {
tts.setPitch(1.0f);
tts.setSpeechRate(1.0f);
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
Log.d(TAG, "onStart() called with: utteranceId = [" + utteranceId + "]");
}
@Override
public void onDone(String utteranceId) {
Log.d(TAG, "onDone() called with: utteranceId = [" + utteranceId + "]");
}
@Override
public void onError(String utteranceId) {
Log.d(TAG, "onError() called with: utteranceId = [" + utteranceId + "]");
}
@Override
public void onError(String utteranceId,int code ) {
Log.d(TAG, "onError() called with: utteranceId = [" + utteranceId + "], code "+code);
super.onError(utteranceId,code);
}
});
}
} else {
}
}
@Override
protected void onResume() {
super.onResume();
play("这是一条测试消息");
// try {
// Context context = this.createPackageContext("com.google.android.tts", Context.CONTEXT_IGNORE_SECURITY);
// Log.d(TAG, "onResume() called context get ?"+(context==null));
// SharedPreferences sharedPreferences = context.getSharedPreferences("com.google.android.tts_preferences",MODE_PRIVATE);
// Log.d(TAG, "onResume() called context sharedPreferences ?"+(sharedPreferences==null));
// SharedPreferences.Editor editor = sharedPreferences.edit();
// Log.d(TAG, "onResume() called context editor ?"+(editor==null));
// editor.putString("default_voice_for_cmn-CN", "cmn-cn-x-cce").commit();
// editor.putString("xxxxxx-CN", "cmn-cn-dadasd-cce").commit();
// } catch (PackageManager.NameNotFoundException e) {
// e.printStackTrace();
// }
}
public synchronized boolean play(String text) {
//boolean ret = tts != null && tts.speak(text, TextToSpeech.QUEUE_ADD, null, "hdaspeech") == 0;
boolean ret = tts != null && tts.speak(text, TextToSpeech.QUEUE_ADD, null, "cqspeech") == 0;
Log.d(TAG, "play() called with: text = [" + text + "],ret "+ret);
return ret;
}
@Override
public void onBackPressed() {
super.onBackPressed();
this.finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
release();
}
public synchronized void release() {
try {
if (tts != null) {
//tts.setOnUtteranceProgressListener(null);
tts.stop();
tts.shutdown();
tts = null;
}
} catch (Exception e) {
}
}
}
51.获取指定sim卡槽的信号强度
package com.xxxxx
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.core.app.ActivityCompat;
import com.xxxx.xxxxx.BuildConfig;
import java.lang.reflect.Method;
import java.util.List;
/**
* 描述:
* 作者 xusibei
* 邮箱 [email protected]
* 部门 xxxxx
* 创建日期 2024/3/28
*/
public class TelephonyHelper {
private static final String TAG = "HDA-Telephony";
private static TelephonyHelper instance;
public static final int SLOT_INDEX_SIM_1 = 1;//卡1
public static final int SLOT_INDEX_SIM_2 = 2;//卡2
public static final int SLOT_INDEX_DUAL = 3;//双卡
public static final int SLOT_INDEX_NONE = 4;//无卡插入
public static TelephonyHelper getInstance() {
if (instance == null) {
synchronized (TelephonyHelper.class) {
if (instance == null) {
instance = new TelephonyHelper();
}
}
}
return instance;
}
private TelephonyHelper() {
}
/**
* 获取指定卡槽的 subid
*
* @param context
* @param slotIndex 卡槽位置
* @return
*/
@SuppressLint("MissingPermission")
public int getSubId(Context context, int slotIndex) {
SubscriptionManager subscriptionManager = context.getSystemService(SubscriptionManager.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
int[] subIdsSaved = subscriptionManager.getSubscriptionIds(slotIndex);
if (subIdsSaved != null && subIdsSaved.length > 0) {
return subIdsSaved[0];
}
} else {
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
//Log.i(TAG, "getDataEnabledSlotIndex: getDefaultDataSubscriptionId subId "+subId);
List<SubscriptionInfo> listInfo = subscriptionManager.getActiveSubscriptionInfoList();
if (listInfo != null && listInfo.size() > 0) {
for (int i = 0; i < listInfo.size(); i++) {
if (listInfo.get(i).getSimSlotIndex() == slotIndex) {
return listInfo.get(i).getSubscriptionId();
}
}
}
}
return -1;
}
/**
* 获取插入sim卡的卡槽数
*
* @param context
* @return @{
{@link #SLOT_INDEX_DUAL} 双卡} @{
{@link #SLOT_INDEX_SIM_1} 卡1} @{
{@link #SLOT_INDEX_SIM_2} 卡2} @{
{@link #SLOT_INDEX_NONE} 没有插入SIM卡}
*/
public int getActiveSlotIndex(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return SLOT_INDEX_NONE;
}
SubscriptionManager subscriptionManager = context.getSystemService(SubscriptionManager.class);
if (BuildConfig.DUAL_SIM_CARD) {
boolean isSimCard1Insert = false;
boolean isSimCard2Insert = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
//Log.i(TAG, "getDataEnabledSlotIndex: getDefaultDataSubscriptionId subId "+subId);
int[] slotIndex1 = subscriptionManager.getSubscriptionIds(0);
if (slotIndex1 != null && slotIndex1.length != 0) {
if (subId == slotIndex1[0]) {
return 0;
}
}
int[] slotIndex2 = subscriptionManager.getSubscriptionIds(1);
if (slotIndex2 != null && slotIndex2.length != 0) {
if (subId == slotIndex2[0]) {
return 1;
}
}
} else {
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
//Log.i(TAG, "getDataEnabledSlotIndex: getDefaultDataSubscriptionId subId "+subId);
List<SubscriptionInfo> listInfo = subscriptionManager.getActiveSubscriptionInfoList();
if (listInfo != null && listInfo.size() > 0) {
for (int i = 0; i < listInfo.size(); i++) {
if (listInfo.get(i).getSubscriptionId() == subId) {
if (listInfo.get(i).getSimSlotIndex() == 0) {
isSimCard1Insert = true;
} else if (listInfo.get(i).getSimSlotIndex() == 0) {
isSimCard2Insert = true;
}
}
}
}
}
if (isSimCard1Insert && isSimCard2Insert) {
return SLOT_INDEX_DUAL;
} else if (isSimCard1Insert && !isSimCard2Insert) {
return SLOT_INDEX_SIM_1;
} else if (!isSimCard1Insert && isSimCard2Insert) {
return SLOT_INDEX_SIM_2;
}
} else {
List<SubscriptionInfo> listInfo = subscriptionManager.getActiveSubscriptionInfoList();
if (listInfo != null && listInfo.size() > 0) {
return SLOT_INDEX_SIM_1;
}
}
return SLOT_INDEX_NONE;
}
/**
* 获取数据连接使能的sim卡卡槽信息
*
* @param ctx
* @return
*/
@SuppressLint("MissingPermission")
public int getDataEnabledSlotIndex(Context ctx) {
int slotState = getActiveSlotIndex(ctx);
//Log.i(TAG, "getDataEnabledSlotIndex: slotState "+slotState);
if (slotState == SLOT_INDEX_NONE) {
return -1;
}
if (slotState == SLOT_INDEX_SIM_1) {
return 0;
} else if (slotState == SLOT_INDEX_SIM_2) {
return 1;
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
SubscriptionManager subscriptionManager = ctx.getSystemService(SubscriptionManager.class);
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
//Log.i(TAG, "getDataEnabledSlotIndex: getDefaultDataSubscriptionId subId "+subId);
int[] slotIndex1 = subscriptionManager.getSubscriptionIds(0);
if (slotIndex1 != null && slotIndex1.length != 0) {
if (subId == slotIndex1[0]) {
return 0;
}
}
int[] slotIndex2 = subscriptionManager.getSubscriptionIds(1);
if (slotIndex2 != null && slotIndex2.length != 0) {
if (subId == slotIndex2[0]) {
return 1;
}
}
} else {
SubscriptionManager subscriptionManager = ctx.getSystemService(SubscriptionManager.class);
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
//Log.i(TAG, "getDataEnabledSlotIndex: getDefaultDataSubscriptionId subId "+subId);
List<SubscriptionInfo> listInfo = subscriptionManager.getActiveSubscriptionInfoList();
if (listInfo != null && listInfo.size() > 0) {
for (int i = 0; i < listInfo.size(); i++) {
if (listInfo.get(i).getSubscriptionId() == subId) {
return listInfo.get(i).getSimSlotIndex();
}
}
}
}
}
return -1;
}
public int getSlotIndexLevel(Context context, int slotIndex) {
TelephonyManager mTelephonyManager = context.getSystemService(TelephonyManager.class);
mTelephonyManager = mTelephonyManager.createForSubscriptionId(getSubId(context, slotIndex));
if (mTelephonyManager != null) {
SignalStrength signalStrength = mTelephonyManager.getSignalStrength();
if (signalStrength != null) {
int dbm = -1;
try {
Method method = signalStrength.getClass().getMethod("getDbm");
dbm = (int) method.invoke(signalStrength);
} catch (Exception e) {
e.printStackTrace();
}
return dbm;
}
}
return -1;
}
/**
* 获取sim卡状态
*
* @param context
* @param slotIndex
* @return
*/
public int getSlotIndexSimState(Context context, int slotIndex) {
TelephonyManager mTelephonyManager = context.getSystemService(TelephonyManager.class);
mTelephonyManager = mTelephonyManager.createForSubscriptionId(getSubId(context, slotIndex));
if (mTelephonyManager != null) {
return mTelephonyManager.getSimState();
}
return -1;
}
}
50.android 13的PackageManagerService相关的解析部分说明
InitAppsHelper.java 系统预置应用管理器, scanSystemDirs函数负责扫描传递过来的system/system_ext/odm/oem/vendor/product分区下的应用文件进行开机安装。获取其PackagePartitions.java中静态内部类SystemPartition的app目录以及priv-app目录调用InstallPackageHelper进行扫描安装 initNonSystemApps是安装/data/app目录下的app
PackageSessionVerifier.java 安装会话的验证
VerificationParams.java 安装会话的验证。主要是验证版本号差异,
PackageManagerShellCommand.java 继承自ShellCommand pm脚本是通过cmd package "$@" 执行的,其中package代表在ServiceManager注册的服务名
PackageHandler.java 处理分发PackageManager的消息,比如INIT_COPY/POST_INSTALL 其中post_install是安装完成的标志,会调用InstallPackageHelper中的handlePackagePostInstall发出package_addded广播
PackageInstallerSession.java 安装会话的服务端
InstallPackageHelper.java 负责安装流程处理包 负责处理多个安装请求
InstallParams.java 安装参数,带安装参数信息,在收到来自PackageHandler的INIT_COPY的msg时开启安装 该MSG由PackageInstallerSession.java监听PackageSessionVerifier的verify调用时执行onVerificationComplete()方法中的install方法
49. Warning: “/system/app/xxx/lib/arm/xxxx.so” has text relocations
android.mk中添加LOCAL_CFLAGS :=-fPIC
48. tcp/udp socket通信小demo
TcpUdpActivity
package com.huadean.tcpudptest;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class TcpUdpActivity extends AppCompatActivity {
private static final String TAG = "TcpUdpActivity";
private RadioGroup mRadioGroup;
private EditText ip_edit, send_port, rec_port, send_content;
private Button btn_createServer, btn_createClient, btn_send_msg;
//tcp
private Socket mClientSocket;
private Socket mServerAcceptSocket;
private ServerSocket mServerSocket;
//udp
private Executor mExecutor = Executors.newFixedThreadPool(4);
private OutputStream mOutputStream;//写入数据
private InputStream mInputStream;//读取数据
private boolean isReady = false;
private DatagramSocket mUdpReceiver;
private DatagramSocket mUdpSender;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tcp_udp);
mRadioGroup = findViewById(R.id.radioGroup);
ip_edit = findViewById(R.id.ip_edit);
send_port = findViewById(R.id.port_send);
rec_port = findViewById(R.id.port_recev);
send_content = findViewById(R.id.send_edit);
btn_createServer = findViewById(R.id.server_create);
btn_createClient = findViewById(R.id.client_create);
btn_send_msg = findViewById(R.id.send_btn);
if (isTcp()) {
btn_createServer.setVisibility(View.VISIBLE);
send_port.setVisibility(View.GONE);
findViewById(R.id.textView3).setVisibility(View.GONE);
btn_createClient.setText("连接服务器");
}else{
send_port.setVisibility(View.VISIBLE);
btn_createServer.setVisibility(View.GONE);
btn_createClient.setText("开启连接");
}
mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (isTcp()) {
btn_createServer.setVisibility(View.VISIBLE);
send_port.setVisibility(View.GONE);
findViewById(R.id.textView3).setVisibility(View.GONE);
btn_createClient.setText("连接服务器");
}else{
send_port.setVisibility(View.VISIBLE);
btn_createServer.setVisibility(View.GONE);
btn_createClient.setText("开启连接");
}
}
});
btn_createServer.setOnClickListener((v) -> {
try {
if (!isReady) {
mRadioGroup.setEnabled(false);
findViewById(R.id.tcp).setEnabled(false);
findViewById(R.id.udp).setEnabled(false);
btn_createServer.setText("关闭服务端");
startServer();
} else {
mRadioGroup.setEnabled(true);
findViewById(R.id.tcp).setEnabled(true);
findViewById(R.id.udp).setEnabled(true);
btn_createServer.setText("创建服务端");
stopServer();
}
} catch (Exception e) {
e.printStackTrace();
}
});
btn_createClient.setOnClickListener((v) -> {
try {
if (!isReady) {
mRadioGroup.setEnabled(false);
findViewById(R.id.tcp).setEnabled(false);
findViewById(R.id.udp).setEnabled(false);
btn_createClient.setText(isTcp()?"断开服务器":"断开连接");
startClient();
} else {
mRadioGroup.setEnabled(true);
findViewById(R.id.tcp).setEnabled(true);
findViewById(R.id.udp).setEnabled(true);
btn_createClient.setText(isTcp()?"连接服务器":"开启连接");
closeClient();
}
} catch (Exception e) {
e.printStackTrace();
}
});
btn_send_msg.setOnClickListener((v -> {
sendMsg();
}));
}
private void startClient() throws Exception {
isReady = true;
btn_createServer.setEnabled(false);
if (isTcp()) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
String ip = ip_edit.getText().toString();
int port = Integer.valueOf(send_port.getText().toString()).intValue();
Log.i(TAG, "startClient: 连接服务器 ip" + ip + ",端口" + port);
try {
mClientSocket = new Socket(ip, port);
Log.i(TAG, "startClient: socket创建成功?" + (mClientSocket != null));
mOutputStream = mClientSocket.getOutputStream();
mInputStream = mClientSocket.getInputStream();
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(TcpUdpActivity.this, "连接服务器失败!请确认服务器是否开启", Toast.LENGTH_SHORT).show();
btn_createClient.setText("开启客户端");
btn_createServer.setEnabled(true);
}
});
return;
}
BufferedReader br = new BufferedReader(new InputStreamReader(mInputStream));
String line = "";
while (isReady) {
try {
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if (!TextUtils.isEmpty(line)) {
final String content = line;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(TcpUdpActivity.this, "收到数据:\r\n" + content, Toast.LENGTH_SHORT).show();
}
});
}
}
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
} else {
int recPort = Integer.valueOf(rec_port.getText().toString()).intValue();
mUdpReceiver = new DatagramSocket(recPort);
mUdpSender = new DatagramSocket();
mExecutor.execute(new Runnable() {
@Override
public void run() {
while (isReady) {
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 3.接收数据
try {
mUdpReceiver.receive(dp);
} catch (IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(TcpUdpActivity.this, "UDP长连接关闭!", Toast.LENGTH_SHORT).show();
}
});
return;
}
// 4.解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
if (!s.isEmpty()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(TcpUdpActivity.this, "收到来自:" + ip + "的消息:\r\n" + s, Toast.LENGTH_SHORT).show();
}
});
} else {
Log.i(TAG, "run: empty udp msg");
}
}
}
});
}
}
private void closeClient() throws Exception {
btn_createServer.setEnabled(true);
isReady = false;
if (isTcp()) {
if (mOutputStream != null) {
mOutputStream.close();
mOutputStream = null;
}
if (mClientSocket != null) {
mClientSocket.close();
}
} else {
if (mUdpSender != null) {
mUdpSender.close();
mUdpSender = null;
}
if (mUdpReceiver != null) {
mUdpReceiver.close();
mUdpReceiver = null;
}
}
}
private void sendMsg() {
mExecutor.execute(new Runnable() {
@Override
public void run() {
if (!isReady) {
return;
}
if (isTcp()) {
if (btn_createClient.isEnabled()) {
PrintWriter pw = new PrintWriter(mOutputStream, true);
String text = send_content.getText().toString();
pw.println(text);
Log.i(TAG, "客户端发送消息完成..");
} else {
try {
PrintWriter pw = new PrintWriter(mServerAcceptSocket.getOutputStream(), true);
String text = send_content.getText().toString();
pw.println(text);
} catch (IOException e) {
Log.i(TAG, "服务端发送失败..");
}
Log.i(TAG, "服务端发送完成..");
}
} else {
int sendPort = Integer.valueOf(send_port.getText().toString()).intValue();
if (mUdpSender != null) {
byte[] content = send_content.getText().toString().getBytes();
try {
DatagramPacket packet = new DatagramPacket(content, 0, content.length, InetAddress.getByName(ip_edit.getText().toString()), sendPort);
mUdpSender.send(packet);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
});
}
private void startServer() throws Exception {
isReady = true;
mRadioGroup.setEnabled(false);
mExecutor.execute(new Runnable() {
@Override
public void run() {
if (isTcp()) {
int port = Integer.valueOf(send_port.getText().toString()).intValue();
Log.i(TAG, "startServer: 创建服务端.端口"+port);
try {
mServerSocket = new ServerSocket(port);
} catch (Exception e) {
e.printStackTrace();
}
while (isReady) {
try {
mServerAcceptSocket = mServerSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(mServerAcceptSocket.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {//阻塞
final String content = line;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(TcpUdpActivity.this, "收到来自客户端的数据数据:\r\n" + content, Toast.LENGTH_SHORT).show();
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
});
}
private void stopServer() throws Exception {
isReady = false;
btn_createClient.setEnabled(true);
if (isTcp()) {
if (mServerSocket != null) {
mServerS