前言
開發(fā)過程中村刨,發(fā)測了峭火,如果遇到崩潰情況,想記錄下來有哪幾個方法樱拴?一馍悟、用bugly畔濒,設置是開發(fā)模式,崩潰了會馬上上報锣咒。二侵状、收集崩潰信息發(fā)送到郵箱。那現在再試一種方式宠哄,就是推送崩潰信息到釘釘壹将。
釘釘機器人了解
我們參考釘釘的開發(fā)文檔:自定義機器人 ,先要登錄pc版或者網頁版的釘釘毛嫉,然后在聊天群頁面增加一個機器人:
記住這個hook地址诽俯,這個其實就是相當于一個請求接口。
開始使用機器人
獲取到Webhook地址后承粤,用戶可以使用任何方式向這個地址發(fā)起HTTP POST 請求暴区,即可實現給該群組發(fā)送消息。注意辛臊,發(fā)起POST請求時仙粱,必須將字符集編碼設置成UTF-8。
當前自定義機器人支持文本(text)彻舰、連接(link)伐割、markdown(markdown)三種消息類型候味,大家可以根據自己的使用場景選擇合適的消息類型,達到最好的展示樣式隔心。具體的消息類型參考下一節(jié)內容白群。
自定義機器人發(fā)送消息時,可以通過手機號碼指定“被@人列表”硬霍。在“被@人列表”里面的人員帜慢,在收到該消息時,會有@消息提醒(免打擾會話仍然通知提醒唯卖,首屏出現“有人@你”)
比如粱玲,我想推送文本信息:
{
"msgtype": "text",
"text": {
"content": "應用崩潰了, @1825718XXXX 快去看看是什么回事"
},
"at": {
"atMobiles": [
"1825718XXXX"
],
"isAtAll": false
}
}
我們請求一個接口拜轨,接口地址就是上面的hook地址抽减,請求方式為post,然后設置post的內容為上面這段撩轰。那釘釘里面就會收到信息胯甩。
崩潰信息收集
知道釘釘的推送原理后,其實我們只要把崩潰信息保存下來堪嫂,然后請求一下偎箫,就可以把崩潰信息推送到釘釘了。我們在網上找到一個收集異常信息的類:
public class CrashHandler implements Thread.UncaughtExceptionHandler {
//系統(tǒng)默認的異常處理器
private Thread.UncaughtExceptionHandler defaultCrashHandler;
private static CrashHandler crashHandler = new CrashHandler();
private Context mContext;
//私有化構造函數
private CrashHandler() {
}
//獲取實例
public static CrashHandler getInstance() {
return crashHandler;
}
public void init(Context context) {
if (L.Debug) {
mContext = context;
defaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
//設置系統(tǒng)的默認異常處理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
}
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
//把錯誤信息保存在sp中皆串,然后在下次進入頁面的時候再上傳錯誤信息
saveErrorInfo(throwable);
if (defaultCrashHandler != null) {
//如果在自定義異常處理器之前淹办,系統(tǒng)有自己的默認異常處理器的話,調用它來處理異常信息
defaultCrashHandler.uncaughtException(thread, throwable);
} else {
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
}
public void sendError() {
if (L.Debug) {
final SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
String data = sp.getString("data", "");
if (!data.equals("")) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("msgtype", "text");
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("content", data);
jsonObject.put("text", jsonObject1.toString());
MMCHttp.<String>post("https://oapi.dingtalk.com/robot/send?access_token=a02fce3ced263e2272dc93867e56394dfe3bf4b44104b6e06b660953cc5a").upJson(jsonObject.toString()).execute(new StringCallback() {
@Override
public void onSuccess(Response<String> response) {
Log.i("---", response.body());
sp.edit().putString("data", "").commit();
}
@Override
public void onError(Response<String> response) {
super.onError(response);
Log.i("---", response.body());
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
private void saveErrorInfo(Throwable throwable) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(getAppInfo(mContext));
stringBuffer.append("崩潰時間:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append("\n");
stringBuffer.append("手機系統(tǒng):").append(Build.VERSION.RELEASE).append("\n");
stringBuffer.append("手機型號:").append(Build.MODEL).append("\n");
stringBuffer.append("崩潰信息:").append(throwable.getMessage());
SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
sp.edit().putString("data", stringBuffer.toString()).commit();
}
/**
* 獲取應用程序信息
*/
public String getAppInfo(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
return "應用包名:" + packageInfo.packageName + "\n應用版本:" + packageInfo.versionName + "\n";
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
就這樣完成了推送應用崩潰信息到釘釘群的功能恶复。
拓展
可以利用bugly的異常報告功能怜森,直接推送崩潰異常情況到釘釘。bugly那里可以設置谤牡,每天早上9點副硅,會推送一段json信息到你的接口。但這個接口翅萤,你要處理一下恐疲,不能直接填上面hook的地址,因為bugly推送的json套么,和上面釘釘發(fā)送的json不是一樣的培己。所以,你需要寫一個php胚泌,例如:
<?php
try {
$response = $HTTP_RAW_POST_DATA ;
$objContent = json_decode($response,true);
$appName = $objContent['eventContent']['appName'];
$num = count($objContent['eventContent']["datas"]);
$crashCount = $objContent['eventContent']["datas"][$num-1]["crashCount"];
$crashUser = $objContent['eventContent']["datas"][$num-1]["crashUser"];
$accessUser = $objContent['eventContent']["datas"][$num-1]["accessUser"];
$version = $objContent['eventContent']["datas"][$num-1]["version"];
$crashCount2 = 0;
$crashUser2 = 0;
$accessUser2 = 0;
$version2 = "";
if($num>1){
$crashCount2 = $objContent['eventContent']["datas"][$num-2]["crashCount"];
$crashUser2 = $objContent['eventContent']["datas"][$num-2]["crashUser"];
$accessUser2 = $objContent['eventContent']["datas"][$num-2]["accessUser"];
$version2 = $objContent['eventContent']["datas"][$num-2]["version"];
}
if($appName!=""){
$webhook = "https://oapi.dingtalk.com/robot/send?access_token=a02fce3ced263e2272dc93867e56394dfe3bf4b44104b6e06b660953cc5";
if($accessUser>$accessUser2){
$message="應用:".$appName."省咨,版本:".$version.",聯網用戶:".$accessUser."玷室,崩潰用戶:".$crashUser."零蓉,崩潰數:".$crashCount;
}else{
$message="應用:".$appName."笤受,版本:".$version2.",聯網用戶:".$accessUser2."壁公,崩潰用戶:".$crashUser2."感论,崩潰數:".$crashCount2;
}
$data = array ('msgtype' => 'text','text' => array ('content' => $message));
$data_string = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $webhook);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 線下環(huán)境不用開啟curl證書驗證, 未調通情況可嘗試添加該代碼
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
echo $data;
}else{
echo "請輸入正確的內容";
}
} catch (Exception $e) {
echo $e;
}
這個php其實就是做了一個中轉的功能,把bugly傳過來的數據紊册,進行解析,然后整理出你想發(fā)到釘釘群的內容快耿,再調用釘釘那個接口囊陡,把數據推送到釘釘。整個流程大概就這樣掀亥。