Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android使用UncaughtExceptionHandler捕獲全局異常

Android使用UncaughtExceptionHandler捕獲全局異常

編輯:關於Android編程

1. 前言

Android應用出現crash時,會出現“程序異常退出”的提示,隨後應用關閉,用戶體驗非常不好。一般為了捕獲應用運行時異常後做出適當處理,給出合理提示時,我們開發中可以繼承UncaughtExceptionHandler類來處理,提升用戶體驗。

2.使用方法

(1)定義CrashHandler處理類,如果發生異常,則在本地文件中記錄堆棧信息,代碼如下所示:

package com.broadengate.cloudcentral.util;

import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.broadengate.cloudcentral.constant.Global;

/**
 * 
 * 
 * <功能詳細描述>
 * 
 * @author cyf
 * @version  [版本號, 2014-6-17]
 * @see  [相關類/方法]
 * @since  [產品/模塊版本]
 */
public class CrashHandler implements UncaughtExceptionHandler
{
    public static final String TAG = "CrashHandler";

    //CrashHandler 實例
    private static CrashHandler INSTANCE = new CrashHandler();

    //context 
    private Context mContext;

    private Thread.UncaughtExceptionHandler mDefaultHandler;

    private Map infos = new HashMap();

    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    private CrashHandler()
    {
    };

    public static CrashHandler getInstance()
    {
        return INSTANCE;
    }

    public void init(Context context)
    {
        mContext = context;
        // 獲取系統默認的 UncaughtException 處理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        // 設置該 CrashHandler 為程序的默認處理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 當 UncaughtException 發生時會轉入該函數來處理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex)
    {
        if (!handleException(ex) && mDefaultHandler != null)
        {
            // 如果用戶沒有處理則讓系統默認的異常處理器來處理
            mDefaultHandler.uncaughtException(thread, ex);
        }
        else
        {
            try
            {
                thread.sleep(4000);
            }
            catch (InterruptedException e)
            {
                Log.e(TAG, "error:", e);
            }
            // 退出程序,注釋下面的重啟啟動程序代碼
            Global.logoutApplication(mContext);
        }
    }

    /**
     * 
     * <自定義錯誤處理,收集錯誤信息,發送錯誤報告等操作均在此完成>
     * <功能詳細描述>
     * @param ex
     * @return
     * @see [類、類#方法、類#成員]
     */
    private boolean handleException(Throwable ex)
    {
        if (ex == null)
        {
            return false;
        }
        //使用Toast 來顯示異常信息
        new Thread()
        {
            @Override
            public void run()
            {
                Looper.prepare();
                Toast.makeText(mContext, "很抱歉,程序出現異常,即將退出", Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();
        collectDeviceInfo(mContext);
        saveCrashInfo2File(ex);
        return true;
    }

    /**
     * 
     * <手機設備參數信息-收集設備信息>
     * <功能詳細描述>
     * @param ctx
     * @see [類、類#方法、類#成員]
     */
    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);
            }
        }
        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);
            }
        }

    }

    /**
     * 
     * <保存錯誤信息到文件中>
     * <功能詳細描述>
     * @param ex
     * @return
     * @see [類、類#方法、類#成員]
     */
    private void saveCrashInfo2File(Throwable ex)
    {
        StringBuffer sb = new StringBuffer();
        for (Map.Entry 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);
        try
        {
            String time = formatter.format(new Date());
            String fileName = FileSystemManager.getCrashPath(mContext) + time + ".log";
            FileOutputStream fos = new FileOutputStream(fileName);
            fos.write(sb.toString().getBytes());
            fos.close();
        }
        catch (Exception e)
        {
            Log.e(TAG, "an error occured while writing file...", e);
        }
    }
}

可以看出String fileName = FileSystemManager.getCrashPath(mContext) + time + “.log”;文件名用時間戳作為關鍵字段,並保存在本地,等待上傳。
收集錯誤信息,發送錯誤報告等操作均在handleException中完成,通過上面的代碼可以看到,一旦應用發生崩潰,就會自動調用uncaughtException方法,然後調用handleException方法完成收集手機信息,保存崩潰堆棧至本地,並且清理當前應用activity堆棧,最後自動關閉應用,並給出toast提示。

(2)Application中配置是否打開全局補獲異常

package com.broadengate.cloudcentral;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import cn.jpush.android.api.JPushInterface;

import com.broadengate.cloudcentral.constant.Global;
import com.broadengate.cloudcentral.sharepref.SharePref;
import com.broadengate.cloudcentral.util.CMLog;
import com.broadengate.cloudcentral.util.CrashHandler;
import com.broadengate.cloudcentral.util.FileSystemManager;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;

/**
 * 
 * <應用初始化> <功能詳細描述>
 * 
 * @author cyf
 * @version [版本號, 2014-3-24]
 * @see [相關類/方法]
 * @since [產品/模塊版本]
 */
public class CCApplication extends Application
{
    /**
     * app實例
     */
    public static CCApplication ccApplication = null;

    /**
     * 本地activity棧
     */
    public static List activitys = new ArrayList();

    /**
     * 加解密密鑰
     */
    public static String key = "";

    @Override
    public void onCreate()
    {
        super.onCreate();
        ccApplication = this;
        new SharePref(ccApplication).saveAppOpenOrClose(true);
        loadData(getApplicationContext());
        JPushInterface.setDebugMode(false); // 設置開啟日志,發布時請關閉日志
        JPushInterface.init(this); // 初始化 JPush
        CrashHandler crashHandler = CrashHandler.getInstance();//打開全局異常捕獲
        crashHandler.init(getApplicationContext());
    }

    public static void loadData(Context context)
    {
        // This configuration tuning is custom. You can tune every option, you may tune some of them,
        // or you can create default configuration by
        //  ImageLoaderConfiguration.createDefault(this);
        // method.
        ImageLoaderConfiguration config =
            new ImageLoaderConfiguration.Builder(context).threadPriority(Thread.NORM_PRIORITY - 2)
                .threadPoolSize(4)
                .tasksProcessingOrder(QueueProcessingType.FIFO)
                .denyCacheImageMultipleSizesInMemory()
                .memoryCache(new LruMemoryCache(4 * 1024 * 1024))
                .discCacheSize(50 * 1024 * 1024)
                .denyCacheImageMultipleSizesInMemory()
                .discCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .discCache(new UnlimitedDiscCache(new File(FileSystemManager.getCacheImgFilePath(context))))
                .build();
        ImageLoader.getInstance().init(config);
    }

    @Override
    public void onTerminate()
    {
        super.onTerminate();
        try
        {
            CCApplication.key = "";
            Global.setUserId("");
            Global.setStore("");
            Global.setLogin(false);
            //保存到配置文件
            SharePref preference = new SharePref(ccApplication);
            preference.saveInitFlag(false);
            preference.saveIsLogin(false);
            preference.saveAppOpenOrClose(false);
            for (Activity activity : activitys)
            {
                activity.finish();
            }
        }
        catch (Exception e)
        {
            CMLog.e("", "finish activity exception:" + e.getMessage());
        }
        finally
        {
            ImageLoader.getInstance().clearMemoryCache();
            System.exit(0);
        }
    }

    /**
     * 
     * <添加> <功能詳細描述>
     * 
     * @param activity
     * @see [類、類#方法、類#成員]
     */
    public void addActivity(Activity activity)
    {
        activitys.add(activity);
    }   
}

(3)下一次啟動後,上傳上次保存在本地的奔潰文件,上傳成功後,刪除,避免重復上傳。

 /**
     * 
     * <上傳崩潰日志文件到服務器>
     * <功能詳細描述>
     * @see [類、類#方法、類#成員]
     */
    private void uploadCrashFile()
    {
        File root = new File(FileSystemManager.getCrashPath(HomeFragmentActivity.this));
        File[] listFiles = root.listFiles();
        if (listFiles.length > 0)
        {
            ArrayList files = new ArrayList();
            for (File file : listFiles)
            {
                files.add(file);
            }
            Map> fileParameters = new HashMap>();
            fileParameters.put("file", files);
            ConnectService.instance().connectServiceUploadCrashFile(HomeFragmentActivity.this,
                null,
                fileParameters,
                HomeFragmentActivity.this,
                UploadCrashFileResponse.class,
                URLUtil.UPLOAD_CRASH_FILE);
        }
    }

上傳成功後的代碼

 /**
         * 向服務器上傳崩潰文件
         */
        else if (ob instanceof UploadCrashFileResponse)
        {
            UploadCrashFileResponse uploadCrashFileResponse = (UploadCrashFileResponse)ob;
            if (GeneralUtils.isNotNullOrZeroLenght(uploadCrashFileResponse.getRetcode()))
            {
                if (Constants.SUCESS_CODE.equals(uploadCrashFileResponse.getRetcode()))
                {
                    //發送成功後刪除本地文件
                    FileUtil.deleteDirectory(FileSystemManager.getCrashPath(HomeFragmentActivity.this));
                }
            }
        }

(4)文件夾公共類

package com.broadengate.cloudcentral.util;

import java.io.File;

import android.content.Context;

/**
 * 
 * <管理本地文件目錄>
 * <功能詳細描述>
 * 
 * @author  cyf
 * @version  [版本號, 2014-6-30]
 * @see  [相關類/方法]
 * @since  [產品/模塊版本]
 */
public class FileSystemManager
{
    /**
     * 根目錄緩存目錄
     */
    private static String cacheFilePath;

    /**
     * 列表頁面圖片緩存目錄
     */
    private static String cacheImgFilePath;

    /**
     * 用戶頭像緩存目錄
     */
    private static String userHeadPath;

    /**
     * 省市區數據庫緩存目錄
     */
    private static String dbPath;

    /**
     * 投訴維權圖片緩存目錄
     */
    private static String mallComplaintsPicPath;

    /**
     * 投訴維權語音緩存目錄
     */
    private static String mallComplaintsVoicePath;

    /**
     * 崩潰日志緩存目錄(上傳成功則刪除)
     */
    private static String crashPath;

    /**
     * 圈子發帖緩存目錄(刪除上次發帖緩存,保存本次發帖紀錄)
     */
    private static String postPath;

    /**
     * 臨時目錄
     */
    private static String temporaryPath;

    /**
     * 
     * <根目錄緩存目錄>
     * <功能詳細描述>
     * @param context
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getCacheFilePath(Context context)
    {
        cacheFilePath = FileUtil.getSDPath(context) + File.separator + "cloudcentral" + File.separator;
        return cacheFilePath;
    }

    /**
     * 
     * <列表頁面圖片緩存目錄>
     * <功能詳細描述>
     * @param context
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getCacheImgFilePath(Context context)
    {
        String path = getCacheFilePath(context) + "img" + File.separator;
        cacheImgFilePath = FileUtil.createNewFile(path);
        FileUtil.createNewFile(path + ".nomedia");
        return cacheImgFilePath;
    }

    /**
     * 
     * <用戶頭像緩存目錄>
     * <功能詳細描述>
     * @param context
     * @param userId
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getUserHeadPath(Context context, String userId)
    {
        userHeadPath =
            FileUtil.createNewFile(getCacheFilePath(context) + "head" + File.separator + userId + File.separator);
        return userHeadPath;
    }

    /**
     * 
     * <省市區數據庫緩存目錄>
     * <功能詳細描述>
     * @param context
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getDbPath(Context context)
    {
        dbPath = FileUtil.createNewFile(getCacheFilePath(context) + "database" + File.separator);
        return dbPath;
    }

    /**
     * 
     * <投訴維權圖片緩存目錄>
     * <功能詳細描述>
     * @param context
     * @param userId
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getMallComplaintsPicPath(Context context, String userId)
    {
        mallComplaintsPicPath =
            FileUtil.createNewFile(getCacheFilePath(context) + "mallcomplaints" + File.separator + userId
                + File.separator + "pic" + File.separator);
        return mallComplaintsPicPath;
    }

    /**
     * 
     * <投訴維權語音緩存目錄>
     * <功能詳細描述>
     * @param context
     * @param userId
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getMallComplaintsVoicePath(Context context, String userId)
    {
        mallComplaintsVoicePath =
            FileUtil.createNewFile(getCacheFilePath(context) + "mallcomplaints" + File.separator + userId
                + File.separator + "voice" + File.separator);
        return mallComplaintsVoicePath;
    }

    /**
     * 
     * <崩潰日志緩存目錄(上傳成功則刪除)>
     * <功能詳細描述>
     * @param context
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getCrashPath(Context context)
    {
        crashPath = FileUtil.createNewFile(getCacheFilePath(context) + "crash" + File.separator);
        return crashPath;
    }

    /**
     * 
     * <圈子發帖緩存目錄(刪除上次發帖緩存,保存本次發帖紀錄)>
     * <功能詳細描述>
     * @param context
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getPostPath(Context context)
    {
        postPath = FileUtil.createNewFile(getCacheFilePath(context) + "post" + File.separator);
        return postPath;
    }

    /**
     * 
     * <臨時圖片緩存目錄>
     * <功能詳細描述>
     * @param context
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getTemporaryPath(Context context)
    {
        temporaryPath = FileUtil.createNewFile(getCacheFilePath(context) + "temp" + File.separator);
        return temporaryPath;
    }
}
package com.broadengate.cloudcentral.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.util.EncodingUtils;


import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.Parcelable;

public class FileUtil
{

    // 獲取sdcard的目錄
    public static String getSDPath(Context context)
    {
        // 判斷sdcard是否存在
        if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
        {
            // 獲取根目錄
            File sdDir = Environment.getExternalStorageDirectory();
            return sdDir.getPath();
        }
        return "/data/data/" + context.getPackageName();
    }

    public static String createNewFile(String path)
    {
        File dir = new File(path);
        if (!dir.exists())
        {
            dir.mkdirs();
        }
        return path;
    }

    // 復制文件
    public static void copyFile(InputStream inputStream, File targetFile)
        throws IOException
    {
        BufferedOutputStream outBuff = null;
        try
        {

            // 新建文件輸出流並對它進行緩沖
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));

            // 緩沖數組
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inputStream.read(b)) != -1)
            {
                outBuff.write(b, 0, len);
            }
            // 刷新此緩沖的輸出流
            outBuff.flush();
        }
        finally
        {
            // 關閉流
            if (inputStream != null)
                inputStream.close();
            if (outBuff != null)
                outBuff.close();
        }
    }

    /**
     * 文件是否已存在
     * 
     * @param file
     * @return
     */
    public static boolean isFileExit(File file)
    {
        if (file.exists())
        {
            return true;
        }
        return false;
    }

    /**
     * 判斷指定目錄是否有文件存在
     * 
     * @param path
     * @param fileName
     * @return
     */
    public static File getFiles(String path, String fileName)
    {
        File f = new File(path);
        File[] files = f.listFiles();
        if (files == null)
        {
            return null;
        }

        if (null != fileName && !"".equals(fileName))
        {
            for (int i = 0; i < files.length; i++)
            {
                File file = files[i];
                if (fileName.equals(file.getName()))
                {
                    return file;
                }
            }
        }
        return null;
    }

    /**
     * 根據文件路徑獲取文件名
     * 
     * @return
     */
    public static String getFileName(String path)
    {
        if (path != null && !"".equals(path.trim()))
        {
            return path.substring(path.lastIndexOf("/"));
        }

        return "";
    }

    // 從asset中讀取文件
    public static String getFromAssets(Context context, String fileName)
    {
        String result = "";
        try
        {
            InputStreamReader inputReader = new InputStreamReader(context.getResources().getAssets().open(fileName));
            BufferedReader bufReader = new BufferedReader(inputReader);
            String line = "";

            while ((line = bufReader.readLine()) != null)
                result += line;
            return result;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return result;
    }

    public static String FileInputStreamDemo(String path)
    {
        try
        {
            File file = new File(path);
            if (!file.exists() || file.isDirectory())
                ;
            FileInputStream fis = new FileInputStream(file);
            byte[] buf = new byte[1024];
            StringBuffer sb = new StringBuffer();
            while ((fis.read(buf)) != -1)
            {
                sb.append(new String(buf));
                buf = new byte[1024];// 重新生成,避免和上次讀取的數據重復
            }
            return sb.toString();

        }
        catch (Exception e)
        {
        }
        return "";
    }

    public static String FileInputStreamDemo(String fileName, Context context)
    {
        try
        {

            AssetManager aManager = context.getResources().getAssets();
            InputStream in = aManager.open(fileName); // 從Assets中的文件獲取輸入流
            int length = in.available(); // 獲取文件的字節數
            byte[] buffer = new byte[length]; // 創建byte數組
            in.read(buffer); // 將文件中的數據讀取到byte數組中
            String result = EncodingUtils.getString(buffer, "UTF-8");

            return result;

        }
        catch (Exception e)
        {
            // Log.e("", "error:" + e.getMessage());
        }
        return "";
    }

    /**
     * 刪除目錄(文件夾)下的文件
     * 
     * @param sPath
     *            被刪除目錄的文件路徑
     * @return 目錄刪除成功返回true,否則返回false
     */
    public static void deleteDirectory(String path)
    {
        File dirFile = new File(path);
        File[] files = dirFile.listFiles();
        if (files != null && files.length > 0)
        {
            for (int i = 0; i < files.length; i++)
            {
                // 刪除子文件
                if (files[i].isFile())
                {
                    files[i].delete();
                }
                // 刪除子目錄
                else
                {
                    deleteDirectory(files[i].getAbsolutePath());
                }
            }
        }
    }

    // 保存序列化的對象到app目錄
    public static void saveSeriObj(Context context, String fileName, Object o)
        throws Exception
    {

        String path = context.getFilesDir() + "/";

        File dir = new File(path);
        dir.mkdirs();

        File f = new File(dir, fileName);

        if (f.exists())
        {
            f.delete();
        }
        FileOutputStream os = new FileOutputStream(f);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(os);
        objectOutputStream.writeObject(o);
        objectOutputStream.close();
        os.close();
    }

    // 讀取序列化的對象
    public static Object readSeriObject(Context context, String fileName)
        throws Exception
    {
        String path = context.getFilesDir() + "/";

        File dir = new File(path);
        dir.mkdirs();
        File file = new File(dir, fileName);
        InputStream is = new FileInputStream(file);

        ObjectInputStream objectInputStream = new ObjectInputStream(is);

        Object o = objectInputStream.readObject();

        return o;

    }

    /**
     * 保存camera capture到file
     * @return 是否成功
     */
    public static boolean savePhoto(Parcelable data, String path)
    {
        boolean rs = false;
        //        Bitmap photo = new Intent().getExtras().getParcelable("data");
        if (null == data)
        {
            return rs;
        }

        try
        {
            Bitmap photo = (Bitmap)data;
            CMLog.w("FileUtil.save", "orign size:"+ photo.getByteCount());

            File file = new File(path);
            file.createNewFile();

            FileOutputStream out = new FileOutputStream(file);
            //            photo.compress(Bitmap.CompressFormat.PNG, 100, out);
            //            ByteArrayOutputStream out = new ByteArrayOutputStream();

            //TODO 調用BimmapUtil壓縮
            rs = photo.compress(Bitmap.CompressFormat.JPEG, 100, out);//PNG

            out.flush();
            out.close();
            rs &= true;
            CMLog.w("FileUtil.save", "file size:"+ file.length());
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
            rs = false;
        }
        catch (IOException e)
        {
            e.printStackTrace();
            rs = false;
        }
        return rs;
    }

    /**
     * 下載音頻文件,先從本地獲得,本地沒有 再從網絡獲得
     * <一句話功能簡述>
     * <功能詳細描述>
     * @param url
     * @param context
     * @param userId
     * @return
     * @see [類、類#方法、類#成員]
     */
    public static String getAudiaFile(String url, Context context, String userId)
    {
        String audioName = url.substring(url.lastIndexOf("/") + 1, url.length());
        File file = new File(FileSystemManager.getMallComplaintsVoicePath(context, userId), audioName);
        if (file.exists())
        {
            return file.getPath();
        }
        return loadImageFromUrl(context,url,file);
    }

    public static String loadImageFromUrl(Context context,String imageURL, File file)
    {
        try
        {
            URL url = new URL(imageURL);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setConnectTimeout(5*1000);
            con.setDoInput(true);
            con.connect();
            if (con.getResponseCode() == 200)
            {
                InputStream inputStream = con.getInputStream();

                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024*20];
                int length = -1;
                while((length = inputStream.read(buffer)) != -1)
                {
                    byteArrayOutputStream.write(buffer,0,length);
                }
                byteArrayOutputStream.close();
                inputStream.close();

                FileOutputStream outputStream = new FileOutputStream(file);
                outputStream.write(byteArrayOutputStream.toByteArray());
                outputStream.close();
                return file.getPath();
            }
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return "";
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved