前言
最近公司接入一个项目,红外遥控,就是用手机去控制机顶盒播放节目,截图所示。领导让我去对接歌华有线机顶盒一个红外数据。
问题
我拿着SDK对比api,很快找到获取特定id下的机顶盒红外数据方法,返回值里面的data封装在SDK里面无法直接tosring的形式直接输出数据,最后只能用Gson去转格式。如下gson换换公式,当时转过之后我想先Log看一下数据,然后我复制Log日志放在在线json格式化上查看,结果显示格式化错误。我想着是不是因为接口返回的json数据过大的原因导致无法使用Gson去解析的原因,后来又使用fastjson,然后还有超大json解析,最后打印的日志都是不全的,最后上网查到AS里面日志一行最多显示4000个字符。
解决问题
1.日志字符拼接
在网上找到关于过长日志打印限制问题,超过4000个字符之后通过换行的形式,然后把所有的日志再进行拼接起来输出。
public static void LoggerE(String tag, String bodyMsg) { //信息太长,分段打印
//因为String的length是字符数量不是字节数量所以为了防止中文字符过多,
// 把4*1024的MAX字节打印长度改为2001字符数
if (bodyMsg.length() > 4000) {
for (int i = 0; i < bodyMsg.length(); i += 4000) {
//当前截取的长度<总长度则继续截取最大的长度来打印
if (i + 4000 < bodyMsg.length()) {
Log.e(tag + i, bodyMsg.substring(i, i + 4000));
} else {
//当前截取的长度已经超过了总长度,则打印出剩下的全部信息
Log.e(tag + i, bodyMsg.substring(i, bodyMsg.length()));
}
}
} else {
//直接打印
Log.e(tag, bodyMsg);
}
}
通过日志换行显示,然后又通过字符的拼接,但是通过在线json发现还是出现格式化问题。
2.Textview复制粘贴
昨天晚上不知道什么时候想到用日志输出数据太麻烦还容易出错,那就用TextView来显示数据,然后通过复制粘贴的形式输出。TextView复制粘贴的方式有如下两种:
第一种
在xml中直接设置属性:android:textIsSelectable=”true”
- 这种方式要求sdk>11
第二种
直接使用TextView, 然后在代码里给TextView添加OnLongClickListener事件,长按时弹出自定义 “复制” 菜单(比如结合 PopupWindow做弹出菜单). 点击”复制” 就去获取TextView的内容.
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setText(content.trim()); //将内容放入粘贴管理器,在别的地方长按选择"粘贴"即可
cm.getText();//获取粘贴信息
还有一个问题就是系统自带的Textview不会自动换行,我从网上找到一个关于自定义TextView自动换行的,如下:
public class JustifyTextView extends TextView {
private int mLineY;
private int mViewWidth;
public static final String TWO_CHINESE_BLANK = " ";
public JustifyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
mViewWidth = getMeasuredWidth();
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
Layout layout = getLayout();
// layout.getLayout()在4.4.3出现NullPointerException
if (layout == null) {
return;
}
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout.getSpacingAdd());
for (int i = 0; i < layout.getLineCount(); i++) {
int lineStart = layout.getLineStart(i);
int lineEnd = layout.getLineEnd(i);
float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());
String line = text.substring(lineStart, lineEnd);
if (needScale(line) && i < layout.getLineCount() - 1) {
drawScaledText(canvas, lineStart, line, width);
} else {
canvas.drawText(line, 0, mLineY, paint);
}
mLineY += textHeight;
}
}
private void drawScaledText(Canvas canvas, int lineStart, String line, float lineWidth) {
float x = 0;
if (isFirstLineOfParagraph(lineStart, line)) {
String blanks = " ";
canvas.drawText(blanks, x, mLineY, getPaint());
float bw = StaticLayout.getDesiredWidth(blanks, getPaint());
x += bw;
line = line.substring(3);
}
int gapCount = line.length() - 1;
int i = 0;
if (line.length() > 2 && line.charAt(0) == 12288 && line.charAt(1) == 12288) {
String substring = line.substring(0, 2);
float cw = StaticLayout.getDesiredWidth(substring, getPaint());
canvas.drawText(substring, x, mLineY, getPaint());
x += cw;
i += 2;
}
float d = (mViewWidth - lineWidth) / gapCount;
for (; i < line.length(); i++) {
String c = String.valueOf(line.charAt(i));
float cw = StaticLayout.getDesiredWidth(c, getPaint());
canvas.drawText(c, x, mLineY, getPaint());
x += cw + d;
}
}
private boolean isFirstLineOfParagraph(int lineStart, String line) {
return line.length() > 3 && line.charAt(0) == ' ' && line.charAt(1) == ' ';
}
private boolean needScale(String line) {
if (line == null || line.length() == 0) {
return false;
} else {
return line.charAt(line.length() - 1) != '\n';
}
}
}
通过TextView方式获取的string数据,还需要粘贴操作配合输出数据,我试过几种方式,在此分享一下,因为数据过长,普通QQ还有其他软件都不能粘贴全部数据,如果手机里面有wps的可以直接把数据粘贴输出,第二种是office,我手机的office不支持粘贴,不过因为小米手机的搜狗输入法自带粘贴板,通过粘贴板粘贴数据输出。
3.Txt文件写入
思前想后,总感觉前面的方式都不是特别好,过程都比较繁琐,因为我本来是要输出txt文件,所以想到能不能直接把string字符串直接转为txt文本。如下有两种写入方式:
第一种写入:
/**
* string转换txt
*
* @param filePath 文件路径
* @param fileName 文件名
* @param str 输出文本
*/
public void stringToTxt(String filePath, String fileName, String str) {
try {
//首先要去创建文件
makeFilePath(filePath, fileName);
FileWriter fw = new FileWriter(filePath + fileName);
//SD卡中的路径
fw.flush();
fw.write(str);
fw.close();
Log.e("TAG", "写入成功");
} catch (Exception e) {
Log.e("TAG", "异常:" + e.getMessage());
e.printStackTrace();
}
}
第二种写入:
/**
* 写入文件
*
* @param strcontent 字符串
* @param filePath 路径
* @param fileName 文件名
*/
public void writeTxtToFile(String strcontent, String filePath, String fileName) {
//生成文件夹之后,再生成文件,不然会出错
makeFilePath(filePath, fileName);
String strFilePath = filePath + fileName;
// 每次写入时,都换行写
String strContent = strcontent + "\r\n";
try {
File file = new File(strFilePath);
if (!file.exists()) {
Log.d("TestFile", "Create the file:" + strFilePath);
file.getParentFile().mkdirs();
file.createNewFile();
}
RandomAccessFile raf = new RandomAccessFile(file, "rwd");
raf.seek(file.length());
raf.write(strContent.getBytes());
raf.close();
} catch (Exception e) {
Log.e("TestFile", "Error on write File:" + e);
}
}
下面是创建文件夹以及文件的方法:
- 创建文件夹
/**
* 创建文件夹
*
* @param filePath
*/
public static void makeRootDirectory(String filePath) {
File file = null;
try {
file = new File(filePath);
if (!file.exists()) {
file.mkdir();
}
} catch (Exception e) {
Log.i("error:", e + "");
}
}
- 创建文件
/**
* 创建文件
*
* @param filePath
* @param fileName
* @return
*/
public File makeFilePath(String filePath, String fileName) {
File file = null;
makeRootDirectory(filePath);
try {
file = new File(filePath + fileName);
if (!file.exists()) {
file.createNewFile();
}
} catch (Exception e) {
e.printStackTrace();
}
return file;
}