前言
最近公司接入一個項目,紅外遙控,就是用手機去控制機頂盒播放節目,截圖所示。領導讓我去對接歌華有線機頂盒一個紅外數據。
問題
我拿着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;
}