您的位置:首页 > 移动开发 > Android开发

Android 用户使用崩溃处理

2015-12-17 15:06 363 查看
程序异常问题:

程序因未捕获的异常而突然终止时,系统会调用处理程序的接口UncaughtExceptionHandler。如果我们想处理未被程序正常捕获的异常,只需实现这个接口里的uncaughtException方法,uncaughtException方法回传了Thread
和 Throwable两个参数。通过这两个参数,我们来对异常进行我们需要的处理

处理异常思路:

1.收集产生崩溃的手机信息,写入文件系统中。
2.崩溃的应用需要可以自动重启。
3.自动上传崩溃信息文件到自己的服务器。

1.收集手机的信息:

public void collectDeviceInfo(Context ctx) {
  try {
   PackageManager pm = ctx.getPackageManager();
   PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
     PackageManager.GET_ACTIVITIES);
   if (pi != null) {
    String versionName = pi.versionName == null ? "null"
      : pi.versionName;
    String versionCode = pi.versionCode + "";
    infos.put("versionName", versionName);
    infos.put("versionCode", versionCode);
    infos.put("crashTime", formatter.format(new Date()));
   }
  } catch (NameNotFoundException e) {
   Log.e(TAG, "an error occured when collect package info", e);
  }
  Field[] fields = Build.class.getDeclaredFields();
  for (Field field: fields) {
   try {
    field.setAccessible(true);
    infos.put(field.getName(), field.get(null).toString());
    Log.d(TAG, field.getName() + " : " + field.get(null));
   } catch (Exception e) {
    Log.e(TAG, "an error occured when collect crash info", e);
   }
  }
 }


2.崩溃和手机信息写入文件:

private void writeCrashInfoToFile(Throwable ex) {
  StringBuffer sb = new StringBuffer();
  for (Map.Entry<String, String> entry: infos.entrySet()) {
   String key = entry.getKey();
   String value = entry.getValue();
   sb.append(key + "=" + value + "\n");
  }
  Writer writer = new StringWriter();
  PrintWriter printWriter = new PrintWriter(writer);
  ex.printStackTrace(printWriter);
  Throwable cause = ex.getCause();
  while (cause != null) {
   cause.printStackTrace(printWriter);
   cause = cause.getCause();
  }
  printWriter.close();
  String result = writer.toString();
  sb.append(result);
  //这里把刚才异常堆栈信息写入SD卡的Log日志里面
  if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
  {
   String sdcardPath = Environment.getExternalStorageDirectory().getPath();
   String filePath = sdcardPath + "/cym/crash/";
   localFileUrl = writeLog(sb.toString(), filePath);
  }
 }
 /**
  *
  * @param log
  * @param name
  * @return 返回写入的文件路径
  * 写入Log信息的方法,写入到SD卡里面
  */
 private String writeLog(String log, String name)
 {
  CharSequence timestamp = new Date().toString().replace(" ", "");
  timestamp = "crash";
  String filename = name + timestamp + ".log";
  File file = new File(filename);
  if(!file.getParentFile().exists()){
   file.getParentFile().mkdirs();
  }
  try
  {
   Log.d("TAG", "写入到SD卡里面");
   //	 FileOutputStream stream = new FileOutputStream(new File(filename));
   //	 OutputStreamWriter output = new OutputStreamWriter(stream);
   file.createNewFile();
   FileWriter fw=new FileWriter(file,true);
   BufferedWriter bw = new BufferedWriter(fw);
   //写入相关Log到文件
   bw.write(log);
   bw.newLine();
   bw.close();
   fw.close();
   return filename;
  }
  catch (IOException e)
  {
   Log.e(TAG, "an error occured while writing file...", e);
   e.printStackTrace();
   return null;
  }
 }



3.重启应用:

private void restart(){
        try{
            Thread.sleep(2000);
        }catch (InterruptedException e){
            Log.e(TAG, "error : ", e);
        }
        Intent intent = new Intent(context.getApplicationContext(), MainActivity.class);
        PendingIntent restartIntent = PendingIntent.getActivity(
                context.getApplicationContext(), 0, intent,
                Intent.FLAG_ACTIVITY_NEW_TASK);
        //退出程序                                          
        AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,
                restartIntent); // 1秒钟后重启应用   
    }




4.上传崩溃


public static String uploadFile(File file,String requestUrl){
        String result = null;
        String  BOUNDARY =  UUID.randomUUID().toString();  //边界标识   随机生成 
        String PREFIX = "--" ;
        String LINE_END = "\r\n";
        String CONTENT_TYPE = "multipart/form-data";   //内容类型 
        try{
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(TIME_OUT);
            conn.setConnectTimeout(TIME_OUT);
            conn.setDoInput(true);  //允许输入流 
            conn.setDoOutput(true); //允许输出流 
            conn.setUseCaches(false);  //不允许使用缓存 
            conn.setRequestMethod("POST");  //请求方式 
            conn.setRequestProperty("Charset", CHARSET);  //设置编码 
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);

            if(file!=null)
            {
                /**
                 * 当文件不为空,把文件包装并且上传
                 */
                DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
                StringBuffer sb = new StringBuffer();
                sb.append(PREFIX);
                sb.append(BOUNDARY);
                sb.append(LINE_END);
                /**
                 * 这里重点注意:
                 * name里面的值为服务器端需要key   只有这个key 才可以得到对应的文件
                 * filename是文件的名字,包含后缀名的   比如:abc.png  
                 */

                sb.append("Content-Disposition: form-data; name=\"uploadcrash\"; filename=\""+file.getName()+"\""+LINE_END);
                sb.append("Content-Type: application/octet-stream; charset="+CHARSET+LINE_END);
                sb.append(LINE_END);
                dos.write(sb.toString().getBytes());
                InputStream is = new FileInputStream(file);
                byte[] bytes = new byte[1024];
                int len = 0;
                while((len=is.read(bytes))!=-1)
                {
                    dos.write(bytes, 0, len);
                }
                is.close();
                dos.write(LINE_END.getBytes());
                byte[] end_data = (PREFIX+BOUNDARY+PREFIX+LINE_END).getBytes();
                dos.write(end_data);
                dos.flush();
                /**
                 * 获取响应码  200=成功
                 * 当响应成功,获取响应的流  
                 */
                int res = conn.getResponseCode();
                Log.e(TAG, "response code:" + res);
                //              if(res==200) 
                //              { 
                Log.e(TAG, "request success");
                InputStream input =  conn.getInputStream();
                StringBuffer sb1= new StringBuffer();
                int ss ;
                while((ss=input.read())!=-1)
                {
                    sb1.append((char)ss);
                }
                result = sb1.toString();
                Log.e(TAG, "result : "+ result);
                //              } 
                //              else{ 
                //                  Log.e(TAG, "request error"); 
                //              } 
            }
        }catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: