WeiboSDKPlugin.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. package me.vanpan.weibosdk;
  2. import android.content.Intent;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.util.Base64;
  6. import android.webkit.URLUtil;
  7. import com.sina.weibo.sdk.WbSdk;
  8. import com.sina.weibo.sdk.WeiboAppManager;
  9. import com.sina.weibo.sdk.api.ImageObject;
  10. import com.sina.weibo.sdk.api.TextObject;
  11. import com.sina.weibo.sdk.api.WeiboMultiMessage;
  12. import com.sina.weibo.sdk.auth.AccessTokenKeeper;
  13. import com.sina.weibo.sdk.auth.AuthInfo;
  14. import com.sina.weibo.sdk.auth.Oauth2AccessToken;
  15. import com.sina.weibo.sdk.auth.WbAppInfo;
  16. import com.sina.weibo.sdk.auth.WbConnectErrorMessage;
  17. import com.sina.weibo.sdk.auth.sso.SsoHandler;
  18. import com.sina.weibo.sdk.share.WbShareCallback;
  19. import com.sina.weibo.sdk.share.WbShareHandler;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.net.HttpURLConnection;
  23. import java.net.URL;
  24. import org.apache.cordova.CallbackContext;
  25. import org.apache.cordova.CordovaArgs;
  26. import org.apache.cordova.CordovaPlugin;
  27. import org.apache.cordova.PluginResult;
  28. import org.json.JSONException;
  29. import org.json.JSONObject;
  30. public class WeiboSDKPlugin extends CordovaPlugin implements WbShareCallback {
  31. private static final String SCOPE = "email,direct_messages_read,direct_messages_write,"
  32. + "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
  33. + "follow_app_official_microblog," + "invitation_write";
  34. private static final String WEBIO_APP_ID = "weibo_app_id";
  35. private static final String WEBIO_REDIRECT_URL = "redirecturi";
  36. private static final String DEFAULT_URL = "https://api.weibo.com/oauth2/default.html";
  37. private static final String CANCEL_BY_USER = "cancel by user";
  38. private static final String WEIBO_EXCEPTION = "weibo exception";
  39. private static final String PARAM_ERROR = "param error";
  40. private static final String ONLY_GET_CODE = "only get code";
  41. private static final String SHARE_FAIL ="sharefail";
  42. private static final String WEIBO_CLIENT_NOT_INSTALLED = "weibo client is not installed";
  43. public static CallbackContext currentCallbackContext;
  44. public static String APP_KEY;
  45. public static WbShareHandler shareHandler = null;
  46. private Oauth2AccessToken mAccessToken;
  47. private String REDIRECT_URL;
  48. private SsoHandler mSsoHandler;
  49. @Override
  50. protected void pluginInitialize() {
  51. super.pluginInitialize();
  52. APP_KEY = webView.getPreferences().getString(WEBIO_APP_ID, "");
  53. REDIRECT_URL = webView.getPreferences().getString(WEBIO_REDIRECT_URL, DEFAULT_URL);
  54. WbSdk.install(WeiboSDKPlugin.this.cordova.getActivity(),new AuthInfo(WeiboSDKPlugin.this.cordova.getActivity(), APP_KEY, REDIRECT_URL, SCOPE));
  55. }
  56. @Override
  57. public boolean execute(String action, final CordovaArgs args,
  58. final CallbackContext callbackContext) throws JSONException {
  59. if (action.equalsIgnoreCase("ssoLogin")) {
  60. return ssoLogin(callbackContext);
  61. } else if (action.equalsIgnoreCase("logout")) {
  62. return logout(callbackContext);
  63. } else if (action.equalsIgnoreCase("shareToWeibo")) {
  64. return shareToWeibo(callbackContext, args);
  65. } else if (action.equalsIgnoreCase("checkClientInstalled")) {
  66. return checkClientInstalled(callbackContext);
  67. } else if (action.equalsIgnoreCase("shareImageToWeibo")) {
  68. return shareImageToWeibo(callbackContext,args);
  69. } else if (action.equalsIgnoreCase("shareTextToWeibo")) {
  70. return shareTextToWeibo(callbackContext,args);
  71. }
  72. return super.execute(action, args, callbackContext);
  73. }
  74. /**
  75. * weibo sso 登录
  76. *
  77. * @param callbackContext
  78. * @return
  79. */
  80. private boolean ssoLogin(CallbackContext callbackContext) {
  81. currentCallbackContext = callbackContext;
  82. mSsoHandler = new SsoHandler(WeiboSDKPlugin.this.cordova.getActivity());
  83. Runnable runnable = new Runnable() {
  84. public void run() {
  85. if (mSsoHandler != null) {
  86. mSsoHandler.authorize(new SelfWbAuthListener());
  87. }
  88. }
  89. };
  90. this.cordova.setActivityResultCallback(this);
  91. this.cordova.getActivity().runOnUiThread(runnable);
  92. return true;
  93. }
  94. /**
  95. * 检查微博客户端是否安装
  96. *
  97. * @param callbackContext
  98. * @return
  99. */
  100. private boolean checkClientInstalled(CallbackContext callbackContext) {
  101. WbAppInfo wbAppInfo = WeiboAppManager.getInstance(WeiboSDKPlugin.this.cordova.getActivity()).getWbAppInfo();
  102. Boolean installed = (wbAppInfo != null && wbAppInfo.isLegal());
  103. if (installed) {
  104. callbackContext.success();
  105. } else {
  106. callbackContext.error(WEIBO_CLIENT_NOT_INSTALLED);
  107. }
  108. return true;
  109. }
  110. /**
  111. * 微博登出
  112. *
  113. * @param callbackContext
  114. * @return
  115. */
  116. private boolean logout(CallbackContext callbackContext) {
  117. AccessTokenKeeper.clear(this.cordova.getActivity());
  118. mAccessToken = new Oauth2AccessToken();
  119. callbackContext.success();
  120. return true;
  121. }
  122. /**
  123. * 微博分享网页
  124. *
  125. * @param callbackContext
  126. * @param args
  127. * @return
  128. */
  129. private boolean shareToWeibo(final CallbackContext callbackContext,
  130. final CordovaArgs args) {
  131. currentCallbackContext = callbackContext;
  132. if (shareHandler == null) {
  133. shareHandler = new WbShareHandler(WeiboSDKPlugin.this.cordova.getActivity());
  134. }
  135. shareHandler.registerApp();
  136. cordova.getThreadPool().execute(new Runnable() {
  137. @Override
  138. public void run() {
  139. sendMultiMessage(callbackContext,args);
  140. }
  141. });
  142. return true;
  143. }
  144. /**
  145. * 微博图片分享
  146. * @param callbackContext
  147. * @param args
  148. * @return
  149. */
  150. private boolean shareImageToWeibo(final CallbackContext callbackContext,
  151. final CordovaArgs args) {
  152. currentCallbackContext = callbackContext;
  153. if (shareHandler == null) {
  154. shareHandler = new WbShareHandler(WeiboSDKPlugin.this.cordova.getActivity());
  155. }
  156. shareHandler.registerApp();
  157. cordova.getThreadPool().execute(new Runnable() {
  158. @Override
  159. public void run() {
  160. sendImageMessage(callbackContext,args);
  161. }
  162. });
  163. return true;
  164. }
  165. /**
  166. * 分享文字到微博
  167. * @param callbackContext
  168. * @param args
  169. * @return
  170. */
  171. private boolean shareTextToWeibo(final CallbackContext callbackContext,
  172. final CordovaArgs args) {
  173. currentCallbackContext = callbackContext;
  174. if (shareHandler == null) {
  175. shareHandler = new WbShareHandler(WeiboSDKPlugin.this.cordova.getActivity());
  176. }
  177. shareHandler.registerApp();
  178. cordova.getThreadPool().execute(new Runnable() {
  179. @Override
  180. public void run() {
  181. sendTextMessage(callbackContext,args);
  182. }
  183. });
  184. return true;
  185. }
  186. @Override
  187. public void onActivityResult(int requestCode, int resultCode, Intent intent) {
  188. super.onActivityResult(requestCode, resultCode, intent);
  189. if (mSsoHandler != null) {
  190. mSsoHandler.authorizeCallBack(requestCode, resultCode, intent);
  191. }
  192. }
  193. /**
  194. * 第三方应用发送请求消息到微博,唤起微博分享界面。
  195. */
  196. private void sendMultiMessage(final CallbackContext callbackContext, CordovaArgs args) {
  197. // 1. 初始化微博的分享消息
  198. WeiboMultiMessage weiboMessage = new WeiboMultiMessage();
  199. final JSONObject data;
  200. try {
  201. data = args.getJSONObject(0);
  202. String title = data.has("title")? data.getString("title"): "";
  203. String url = data.has("url")? data.getString("url"): "";
  204. String description = data.has("description")? data.getString("description"): "";
  205. String image = data.has("image")? data.getString("image"): "";
  206. Bitmap imageData = processImage(image);
  207. //WebpageObject mediaObject = new WebpageObject();
  208. //mediaObject.identify = Utility.generateGUID();
  209. //mediaObject.title = title;
  210. //mediaObject.description = description;
  211. //mediaObject.actionUrl = url;
  212. if (imageData != null) {
  213. //注意:最终压缩过的缩略图大小不得超过 32kb。
  214. ImageObject imageObject = new ImageObject();
  215. imageObject.setImageObject(imageData);
  216. weiboMessage.imageObject = imageObject;
  217. // mediaObject.setThumbImage(imageData);
  218. }
  219. // weiboMessage.mediaObject = mediaObject;
  220. TextObject textObject = new TextObject();
  221. textObject.text = description + " " + url;
  222. textObject.title = title;
  223. weiboMessage.textObject = textObject;
  224. shareHandler.shareMessage(weiboMessage, false);
  225. } catch (JSONException e) {
  226. WeiboSDKPlugin.this.webView.sendPluginResult(new PluginResult(
  227. PluginResult.Status.ERROR, PARAM_ERROR),
  228. callbackContext.getCallbackId());
  229. }
  230. }
  231. /**
  232. * 组装图片分享消息
  233. * @param callbackContext
  234. * @param args
  235. */
  236. private void sendImageMessage(final CallbackContext callbackContext, CordovaArgs args) {
  237. WeiboMultiMessage weiboMessage = new WeiboMultiMessage();
  238. final JSONObject data;
  239. try {
  240. data = args.getJSONObject(0);
  241. String image = data.has("image")? data.getString("image"): "";
  242. Bitmap imageData = processImage(image);
  243. if (imageData != null) {
  244. //注意:最终压缩过的缩略图大小不得超过 32kb。
  245. ImageObject imageObject = new ImageObject();
  246. imageObject.setImageObject(imageData);
  247. weiboMessage.imageObject = imageObject;
  248. }
  249. shareHandler.shareMessage(weiboMessage, false);
  250. } catch (JSONException e) {
  251. WeiboSDKPlugin.this.webView.sendPluginResult(new PluginResult(
  252. PluginResult.Status.ERROR, PARAM_ERROR),
  253. callbackContext.getCallbackId());
  254. }
  255. }
  256. /**
  257. * 组装微博文字分享消息
  258. * @param callbackContext
  259. * @param args
  260. */
  261. private void sendTextMessage(final CallbackContext callbackContext, CordovaArgs args) {
  262. // 1. 初始化微博的分享消息
  263. WeiboMultiMessage weiboMessage = new WeiboMultiMessage();
  264. final JSONObject data;
  265. try {
  266. data = args.getJSONObject(0);
  267. String text = data.has("text")? data.getString("text"): "";
  268. TextObject textObject = new TextObject();
  269. textObject.text = text;
  270. weiboMessage.textObject = textObject;
  271. shareHandler.shareMessage(weiboMessage, false);
  272. } catch (JSONException e) {
  273. WeiboSDKPlugin.this.webView.sendPluginResult(new PluginResult(
  274. PluginResult.Status.ERROR, PARAM_ERROR),
  275. callbackContext.getCallbackId());
  276. }
  277. }
  278. /**
  279. * 组装JSON
  280. *
  281. * @param access_token
  282. * @param userId
  283. * @param expires_time
  284. * @return
  285. */
  286. private JSONObject makeJson(String access_token, String userId, long expires_time) {
  287. String json = "{\"access_token\": \"" + access_token + "\", " +
  288. " \"userId\": \"" + userId
  289. + "\", " +
  290. " \"expires_time\": \"" + String.valueOf(expires_time) + "\"" +
  291. "}";
  292. JSONObject jo = null;
  293. try {
  294. jo = new JSONObject(json);
  295. } catch (JSONException e) {
  296. e.printStackTrace();
  297. }
  298. return jo;
  299. }
  300. /**
  301. * 处理图片
  302. * @param image
  303. * @return
  304. */
  305. private Bitmap processImage(String image) {
  306. if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
  307. return getBitmapFromURL(image);
  308. } else if (isBase64(image)) {
  309. return decodeBase64ToBitmap(image);
  310. } else {
  311. return getBitmapByPath(image);
  312. }
  313. }
  314. /**
  315. * 检查图片字符串是不是Base64
  316. * @param image
  317. * @return
  318. */
  319. private boolean isBase64(String image) {
  320. try {
  321. byte[] decodedString = Base64.decode(image, Base64.DEFAULT);
  322. Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
  323. if (bitmap == null) {
  324. return false;
  325. }
  326. return true;
  327. } catch (Exception e) {
  328. return false;
  329. }
  330. }
  331. /**
  332. * 将图片的 URL 转化为 Bitmap
  333. * @param src
  334. * @return
  335. */
  336. public static Bitmap getBitmapFromURL(String src) {
  337. try {
  338. URL url = new URL(src);
  339. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  340. connection.setDoInput(true);
  341. connection.connect();
  342. InputStream input = connection.getInputStream();
  343. Bitmap bitmap = BitmapFactory.decodeStream(input);
  344. return bitmap;
  345. } catch (IOException e) {
  346. return null;
  347. }
  348. }
  349. /**
  350. * 根据文件路径生成 Bitmap
  351. * @param path
  352. * @return
  353. */
  354. public static Bitmap getBitmapByPath(String path) {
  355. if (path == null)
  356. return null;
  357. try {
  358. Bitmap bitmap = BitmapFactory.decodeFile(path);
  359. return bitmap;
  360. } catch (Exception e) {
  361. e.printStackTrace();
  362. return null;
  363. } catch (Error e) {
  364. e.printStackTrace();
  365. return null;
  366. }
  367. }
  368. /**
  369. * 将Base64解码成Bitmap
  370. */
  371. private Bitmap decodeBase64ToBitmap(String Base64String) {
  372. byte[] decode = Base64.decode(Base64String, Base64.DEFAULT);
  373. Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
  374. return bitmap;
  375. }
  376. @Override public void onWbShareSuccess() {
  377. WeiboSDKPlugin.currentCallbackContext.success();
  378. }
  379. @Override public void onWbShareCancel() {
  380. WeiboSDKPlugin.currentCallbackContext.error(CANCEL_BY_USER);
  381. }
  382. @Override public void onWbShareFail() {
  383. WeiboSDKPlugin.currentCallbackContext.error(SHARE_FAIL);
  384. }
  385. @Override
  386. public void onNewIntent(Intent intent) {
  387. super.onNewIntent(intent);
  388. WeiboSDKPlugin.shareHandler.doResultIntent(intent,this);
  389. }
  390. private class SelfWbAuthListener implements com.sina.weibo.sdk.auth.WbAuthListener{
  391. @Override
  392. public void onSuccess(final Oauth2AccessToken token) {
  393. mAccessToken = token;
  394. if (mAccessToken.isSessionValid()) {
  395. AccessTokenKeeper.writeAccessToken(
  396. WeiboSDKPlugin.this.cordova.getActivity(), mAccessToken);
  397. JSONObject jo = makeJson(mAccessToken.getToken(),
  398. mAccessToken.getUid(),mAccessToken.getExpiresTime());
  399. WeiboSDKPlugin.this.webView.sendPluginResult(new PluginResult(
  400. PluginResult.Status.OK, jo), currentCallbackContext.getCallbackId());
  401. } else {
  402. // 以下几种情况,您会收到 Code:
  403. // 1. 当您未在平台上注册的应用程序的包名与签名时;
  404. // 2. 当您注册的应用程序包名与签名不正确时;
  405. // 3. 当您在平台上注册的包名和签名与您当前测试的应用的包名和签名不匹配时。
  406. // String code = values.getString("code");
  407. WeiboSDKPlugin.this.webView.sendPluginResult(new PluginResult(
  408. PluginResult.Status.ERROR, ONLY_GET_CODE),
  409. currentCallbackContext.getCallbackId());
  410. }
  411. }
  412. @Override
  413. public void cancel() {
  414. WeiboSDKPlugin.this.webView.sendPluginResult(new PluginResult(
  415. PluginResult.Status.ERROR, CANCEL_BY_USER),
  416. currentCallbackContext.getCallbackId());
  417. }
  418. @Override
  419. public void onFailure(WbConnectErrorMessage errorMessage) {
  420. WeiboSDKPlugin.this.webView.sendPluginResult(new PluginResult(
  421. PluginResult.Status.ERROR, WEIBO_EXCEPTION),
  422. currentCallbackContext.getCallbackId());
  423. }
  424. }
  425. }