安卓 獲取重定向Url最終地址
阿新 • • 發佈:2018-12-21
String Url = "http://suo.im/5phIx5"; // 重定向url
WebTool.GetRedirectUrl(context, Url, new CallBackUrl()
{
@Override
public void F(String lastUrl)
{
// lastUrl為重定向的最終地址
}
});
package sci.tool; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONObject; import sci.tool.ThreadTool.ThreadPram; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.Log; import android.net.Uri; import android.webkit.WebView; import android.webkit.WebViewClient; /** WebTool.java: 網頁資訊獲取,可在主執行緒中呼叫 * 1、byte[] GetBytes(final String url) * 2、String GetString(String dataUrl) * 3、JSONObject GetJSONObject(String jsonUrl) * 4、BitmapGetBitmap(String imgUrl) * 5、Drawable GetDrawable(String imgUrl) * * 6、GetRedirectUrl(final Context context, final String url, final CallBackUrl call) —— 獲取重定向url最終的地址資訊,支援所有網址 * 7、GetUrlHref(String url) —— 獲取url載入後頁面中的href資訊 * 8、OpenRedirectUrl(final Context context, String Url) —— 直接開啟重定向後的地址 * * ----- 2018-6-7 上午11:00:03 scimence */ public class WebTool { // 快取Drawable影象 private static HashMap<String, Drawable> DrawableDic = new HashMap<String, Drawable>(); /** 從網路上下載圖片,轉為Drawable */ public static Drawable GetDrawable(String imgUrl) { Drawable drawable = null; if (DrawableDic.containsKey(imgUrl)) drawable = DrawableDic.get(imgUrl); // 從快取讀取影象 else { Bitmap bmp = GetBitmap(imgUrl); // 從伺服器端下載影象 if (bmp != null) drawable = Bitmap2Drawable(bmp); // 轉化為Drawable if (drawable != null) DrawableDic.put(imgUrl, drawable); // 記錄影象 } return drawable; } /** 從網路上下載圖片資源 */ public static Bitmap GetBitmap(String imgUrl) { Bitmap bmp = null; try { byte[] data = GetBytes(imgUrl); // 下載資料 bmp = BitmapFactory.decodeByteArray(data, 0, data.length); // 載入Bitmap } catch (Exception e) { e.printStackTrace(); } return bmp; } /** Bitmap轉化為Drawable */ public static Drawable Bitmap2Drawable(Bitmap bitmap) { BitmapDrawable drawable = new BitmapDrawable(bitmap); return drawable; } /** Drawable轉化為Bitmap */ public static Bitmap Drawable2Bitmap(Drawable drawable) { BitmapDrawable bitDrawable = (BitmapDrawable) drawable; return bitDrawable.getBitmap(); } /** 獲取url最終跳轉的herf資訊 */ public static String GetUrlHref(String url) { // if (url.contains("t.seoniao.com")) // http://t.seoniao.com/to.php?t=ONOERIC8Z1 { String data = GetString(url); // 獲取網址資訊 // <script>if(/baiduboxapp/i.test(navigator.userAgent)){window.location.href="bdbox://utils?action=sendIntent&minver=7.4¶ms=%7B%22intent%22%3A%22weixin://dl/business/?ticket=tc27384c6af2fb995e18de2cbc27a0da3%23Intent%3Bend%22%7D";}else{window.location.href="weixin://dl/business/?ticket=tc27384c6af2fb995e18de2cbc27a0da3";} // </script> ArrayList<String> herfList = new ArrayList<String>(); int start = 0; String hrefKey = "window.location.href=\""; while (data.contains(hrefKey)) { int index = data.indexOf(hrefKey, start); if (index != -1) { int end = data.indexOf("\"", index + hrefKey.length()); if (end != -1) { start = end + 1; String herf = data.substring(index + hrefKey.length(), end).trim(); if (!herfList.contains(herf)) { herfList.add(herf); if (herf.startsWith("weixin://")) { url = herf; break; } } } } } } Log.d("WebTool", "GetWeixinUrl -> " + url); return url; } /** 獲取指定網址的資料 */ public static String GetString(String dataUrl) { String Str = ""; try { byte[] data = GetBytes(dataUrl); // 下載資料 Str = new String(data); // 轉化為字串 } catch (Exception e) { e.printStackTrace(); } return Str; } /** 獲取指定網址的資料為JSON */ public static JSONObject GetJSONObject(String jsonUrl) { String webData = WebTool.GetString(jsonUrl); JSONObject webJson = null; try { webJson = new JSONObject(webData); } catch (Exception ex) { ex.printStackTrace(); } return webJson; } // ------------------------ // 直接開啟連結url的重定向地址 // ------------------------ /** 開啟連結url的重定向地址 */ public static void OpenRedirectUrl(final Context context, String Url) { OpenRedirectUrl(context, Url, true); } /** 開啟連結Url */ private static void OpenRedirectUrl(final Context context, String Url, boolean reditect) { try { if (reditect) { WebTool.GetRedirectUrl(context, Url, new CallBackUrl() { @Override public void F(String fUrl) { OpenRedirectUrl(context, fUrl, false); } }); return; } Uri uri = Uri.parse(Url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } catch (Exception ex) { Log.d("WebTool", "連結地址配置有誤:" + Url); } } // ------------------------ // 獲取重定向後的url // ------------------------ public static interface CallBackUrl { // 回撥處理邏輯 public void F(String url); } static final class UrlData { public List<String> StartList = new ArrayList<String>(); public List<String> FinishList = new ArrayList<String>(); public String CallUrl = ""; public long currrentTimeMillion = System.currentTimeMillis(); public boolean isClicked = false; public String url = ""; public UrlData(String url) { this.url = url; } } // static List<String> StartList = new ArrayList<String>(); // static List<String> FinishList = new ArrayList<String>(); // static String CallUrl = ""; // static long currrentTimeMillion = System.currentTimeMillis(); // static boolean isClicked = false; static HashMap<String, UrlData> urlDic = new HashMap<String, UrlData>(); /** 獲取指定網址的資料 */ public static void GetRedirectUrl(final Context context, final String url, final CallBackUrl call) { String LowerUrl = url.trim().toLowerCase(); if (!LowerUrl.startsWith("http://") && !LowerUrl.startsWith("https://")) // 非網頁地址,則直接返回 { call.F(url); return; } // 在非主執行緒中執行網路請求,獲取資料 ThreadTool.RunInMainThread(new ThreadPram() { @Override public void Function() { if (!urlDic.containsKey(url)) { urlDic.put(url, new UrlData(url)); } final UrlData data = urlDic.get(url); if (data.isClicked && System.currentTimeMillis() - data.currrentTimeMillion > 3 * 1000) data.isClicked = false; if (!data.isClicked) { data.StartList.clear(); data.FinishList.clear(); } final WebView webView = new WebView(context); webView.loadUrl(url); webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new WebViewClient() { // 頁面載入開始 @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.d("WebTool", "Start-> " + url); if (!data.StartList.contains(url)) { data.StartList.add(url); // 記錄重定向的url資訊 waitCallBack(url); // } // super.onPageStarted(view, url, favicon); } // 頁面載入完成 @Override public void onPageFinished(WebView view, String url) { Log.d("WebTool", "Finish -> " + url); if (data.StartList.contains(url)) { if (!data.FinishList.contains(url)) { data.FinishList.add(url); waitCallBack(url); } } } public void waitCallBack(String paramUrl) { data.CallUrl = paramUrl; data.currrentTimeMillion = System.currentTimeMillis(); // 重置當前時間值,延時等待後續重定向 ThreadTool.RunInMainThread(new ThreadPram() { @Override public void Function() { if (!data.isClicked) { if (call != null && System.currentTimeMillis() >= data.currrentTimeMillion + 700) { data.isClicked = true; call.F(data.CallUrl); Log.d("WebTool", "CallUrl -> " + data.CallUrl); } } } }, 700); } }); } }); } // ------------------------ // 網路資料載入 // ------------------------ static HashMap<Long, byte[]> GetBytesDic = new HashMap<Long, byte[]>(); /** 獲取指定網址的資料,函式可在任意執行緒中執行,包括主執行緒 */ public static byte[] GetBytes(final String url) { final long KEY = System.currentTimeMillis(); if (!GetBytesDic.containsKey(KEY)) GetBytesDic.put(KEY, null); // 在非主執行緒中執行網路請求,獲取資料 ThreadTool.RunInCachedThread(new ThreadPram() { @Override public void Function() { byte[] data = GetBytes_process(url); GetBytesDic.put(KEY, data); } }); // 等待非同步執行緒中的網路請求邏輯執行完成 while (GetBytesDic.get(KEY) == null) // 未獲取到資料則 { if (System.currentTimeMillis() > KEY + 1000 * 3) break; // 超出3秒則終止 Sleep(50); // 延時等待非同步執行緒邏輯執行完成 } byte[] data = GetBytesDic.get(KEY); GetBytesDic.remove(KEY); return data; } /** 獲取指定網址的資料 */ public static byte[] GetBytes_process(String url) { byte[] data = new byte[0]; try { URL webUrl = new URL(url); URLConnection con = webUrl.openConnection(); // 開啟連線 InputStream in = con.getInputStream(); // 獲取InputStream data = InputStreamToByte(in); // 讀取輸入流資料 } catch (Exception e) { e.printStackTrace(); } return data; } /** InputStream -> Byte */ public static final byte[] InputStreamToByte(InputStream in) { byte[] bytes = {}; try { ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); byte[] data = new byte[1024]; int count = 0; while ((count = in.read(data, 0, 1024)) > 0) { byteOutStream.write(data, 0, count); } bytes = byteOutStream.toByteArray(); } catch (Exception ex) { ex.printStackTrace(); } return bytes; } /** 當前執行緒延時毫秒 */ private static void Sleep(long timeMillion) { try { Thread.sleep(timeMillion); } catch (InterruptedException e) { e.printStackTrace(); } } }
執行緒輔助類:
package sci.tool; import java.util.concurrent.Executors; import android.os.Handler; import android.os.Looper; /** 執行緒輔助處理類,用於在主執行緒和其他執行緒中執行邏輯 */ public class ThreadTool { // 呼叫示例 public static void Example() { ThreadTool.RunInMainThread(new ThreadPram() { @Override public void Function() { // TODO Auto-generated method stub // 在主執行緒執行邏輯 } }); } // --------------------------------------------- /** 執行緒輔助處理類物件引數 */ public static abstract class ThreadPram { /** 需要線上程中執行的邏輯 */ public abstract void Function(); } /** 在主執行緒執行Function —— UI介面相關控制元件邏輯需在主執行緒中執行 */ public static void RunInMainThread(final ThreadPram param) { getMainHandler().post(new Runnable() { @Override public void run() { param.Function(); } }); } /** 在主執行緒中延時delayMillis毫秒,執行Function —— UI介面相關控制元件邏輯需在主執行緒中執行 */ public static void RunInMainThread(final ThreadPram param, long delayMillis) { getMainHandler().postDelayed(new Runnable() { @Override public void run() { param.Function(); } }, delayMillis); } /** 在其他執行緒執行Function —— 網路請求需在主執行緒之外的其他執行緒執行 */ public static void RunInCachedThread(final ThreadPram param) { Executors.newCachedThreadPool().execute(new Runnable() { @Override public void run() { param.Function(); } }); } /** 當前執行緒是否為主執行緒 */ public static boolean isUiThread() { return Thread.currentThread() == Looper.getMainLooper().getThread(); } /** 獲取主執行緒Handler */ public static Handler getMainHandler() { return new Handler(Looper.getMainLooper()); } /** 獲取當前執行緒Handler */ public static Handler getCurrentHandler() { return new Handler(Looper.myLooper()); } }