OffLineLogUtils.uploadFirstLine(this);
在MainActivity的onCreate中 加入这个方法
/**
* 获取网络连接状态
*
* @param context
* @return 网络是否连接
*/
public static boolean checkedNetwork(Context context) {
try {
ConnectivityManager con = (ConnectivityManager) context
.getSystemService(Activity.CONNECTIVITY_SERVICE);
if(null != con.getActiveNetworkInfo())
return con.getActiveNetworkInfo().isAvailable();
return false;
// boolean wifi = con.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
// .isConnectedOrConnecting();
// NetworkInfo netinfo = con
// .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
// boolean internet = false;
// if (netinfo != null) {
// internet = netinfo.isConnectedOrConnecting();
// }
// if (wifi | internet) {
// return true;
// } else {
// return false;
// }
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public class OffLineLogUtils {
//当上传初心啊错误的时候保存信息
public static void saveObjectjson(String saveJson) {
File dir = new File(Constants.SECTION_LOG_PATH);
if (!dir.exists()) {
dir.mkdirs();
}
File path = new File(dir, "log.txt");
if (!path.exists()) {
try {
path.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileUtils.addTxtToFileBuffered(path, AesUtil.encrypt(saveJson));
//追加内容上去
}
private static OkHttpClient okHttpClient;
//递归上传每一行,直到上传结束
//每上传成功一次 那么久接着继续上传
public static void uploadFirstLine(final Context context) {
LogUtils.e("uploadFirstLine: 开始上传");
//网络是否可用
if (!NetworkUtils.checkedNetwork(context)) {
return;
}
//文件是否存在
File dir = new File(Constants.SECTION_LOG_PATH);
if (!dir.exists()) {
dir.mkdirs();
}
final File path = new File(dir, "log.txt");
if (!path.exists()) {
return;
}
//第一行数据不为空
String lineForText = FileUtils.getLineForText(path, 1);
if (TextUtils.isEmpty(lineForText)) {
path.delete();
return;
}
final String foodJson = AesUtil.decrypt(lineForText);
//partId 生命周期 在app卸载的时候换新的
if (SpUtils.getString("partId", "").equals("")) {
SpUtils.putString("partId", getSeesionOrPartId());
}
final String logUrl = Constants.LOG_HOST + "?p=" + SpUtils.getString("partId", "");
RequestBody requestBody = FormBody.create(MediaType.parse("Content-Type: application/json;")
, foodJson);
Request request = new Request.Builder()
.url(logUrl)//请求的url
.addHeader("Content-Type", "application/json")
.post(requestBody)
.build();
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build();
}
//创建/Call
Call call = okHttpClient.newCall(request);
//加入队列 异步操作
call.enqueue(new Callback() {
//请求错误回调方法
@Override
public void onFailure(Call call, IOException e) {
LogUtils.e("onFailure: " + "上传失败" + e.getMessage());
//上传失败 程序就中止了
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.code() <= 204) {
FileUtils.deleteLineForText(path, 1);
uploadFirstLine(context);
}
}
});
}
}
//文件操作工具类 主要方法 删除1行 添加一行
public class FileUtils {
public static void addTxtToFileBuffered(File file, String content) {
//在文本文本中追加内容
BufferedWriter out = null;
try {
//FileOutputStream(file, true),第二个参数为true是追加内容,false是覆盖
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
out.write(content);
out.newLine();//换行
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 使用FileWriter进行文本内容的追加
*
* @param file
* @param content
*/
public static void addTxtToFileWrite(File file, String content) {
FileWriter writer = null;
try {
//FileWriter(file, true),第二个参数为true是追加内容,false是覆盖
writer = new FileWriter(file, true);
writer.write("\r\n");//换行
writer.write(content);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void deleteLineForText(File f, int deleteLine) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f.getAbsolutePath()));
StringBuffer sb = new StringBuffer();
String temp = null;
int line = 0;
while ((temp = br.readLine()) != null) {
line++;
if (line == deleteLine) continue;
sb.append(temp).append("\r\n");
}
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter(f.getAbsolutePath(),false));
bw.write(sb.toString());
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getLineForText(File f, int deleteLine) {
String text = "";
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f.getAbsolutePath()));
String temp = null;
int line = 0;
while ((temp = br.readLine()) != null) {
line++;
if (line == deleteLine) {
text = temp;
break;
}
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return text;
}
}
//加密工具类 防止用户看到日志信息
public class AesUtil {
private static final String Algorithm = "AES";
private final static String HEX = "0123456789ABCDEF";
private final static String key = "gxb";
//加密函数,key为密钥
private static String encrypt(String key, String src) throws Exception {
byte[] rawKey = getRawKey(key.getBytes());
byte[] result = encrypt(rawKey, src.getBytes());
return toHex(result);
}
//加密函数,key为密钥
public static String encrypt( String src) {
byte[] result = new byte[0];
try {
byte[] rawKey = getRawKey(key.getBytes());
result = encrypt(rawKey, src.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return toHex(result);
}
//解密函数。key值必须和加密时的key一致
private static String decrypt(String key, String encrypted) throws Exception {
byte[] rawKey = getRawKey(key.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
} //解密函数。key值必须和加密时的key一致
public static String decrypt( String encrypted) {
byte[] result = new byte[0];
try {
byte[] rawKey = getRawKey(key.getBytes());
byte[] enc = toByte(encrypted);
result = decrypt(rawKey, enc);
} catch (Exception e) {
e.printStackTrace();
}
return new String(result);
}
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance(Algorithm);
// SHA1PRNG 强随机种子算法, 要区别Android 4.2.2以上版本的调用方法
SecureRandom sr = null;
if (android.os.Build.VERSION.SDK_INT >= 17) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
sr.setSeed(seed);
kgen.init(256, sr); // 256位或128位或192位
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] key, byte[] src) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(key, Algorithm);
Cipher cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(src);
return encrypted;
}
private static byte[] decrypt(byte[] key, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(key, Algorithm);
Cipher cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
private static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++) {
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
}
return result;
}
private static String toHex(byte[] buf) {
if (buf == null) {
return "";
}
StringBuffer result = new StringBuffer(2 * buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
}
这样一个简单的日志离线上传就处理完毕了!~