it = mWindows.iterator();
182 | while (it.hasNext()) {
183 | WebView window = it.next();
184 | it.remove();
185 |
186 | detachFromParent(window);
187 | window.destroy();
188 | }
189 | }
190 |
191 | private String generateContent() {
192 | String url = getIntent().getStringExtra(PAGE_URL);
193 | if (url == null) {
194 | return null;
195 | }
196 |
197 | try {
198 | new java.net.URL(url);
199 | } catch (MalformedURLException ex) {
200 | if (LOGGING) {
201 | Log.wtf(LOG_TAG, ex);
202 | }
203 |
204 | return null;
205 | }
206 |
207 | String title = getIntent().getStringExtra(PAGE_TITLE);
208 | String text = getIntent().getStringExtra(PAGE_TEXT);
209 | String appId = getIntent().getStringExtra(APP_ID);
210 | FacebookLikeOptions options = getIntent().getParcelableExtra(OPTIONS);
211 | if (options == null) {
212 | options = new FacebookLikeOptions();
213 | }
214 |
215 | StringBuilder sb = new StringBuilder();
216 | sb.append("");
217 | sb.append("");
218 | sb.append("");
219 |
220 | if (title != null) {
221 | sb.append(options.titleOpen);
222 | sb.append(escapeHtml(title));
223 | sb.append(options.titleClose);
224 | }
225 |
226 | appendImg(options, sb);
227 |
228 | if (text != null) {
229 | sb.append(options.textOpen);
230 | sb.append(escapeHtml(text));
231 | sb.append(options.textClose);
232 | }
233 |
234 | appendUrl(url, appId, options, sb);
235 |
236 | sb.append("");
237 | sb.append("");
238 |
239 | try {
240 | return sb.toString();
241 | } catch (OutOfMemoryError ex) {
242 | if (LOGGING) {
243 | Log.wtf(LOG_TAG, ex);
244 | }
245 |
246 | return null;
247 | }
248 | }
249 |
250 | private void appendImg(FacebookLikeOptions options, StringBuilder sb) {
251 | int[] size = null;
252 |
253 | CharSequence imgSrc = getIntent().getStringExtra(PAGE_PICTURE_URL);
254 | if (imgSrc == null) {
255 | Bitmap picture = null;
256 |
257 | int pictureId = getIntent().getIntExtra(PAGE_PICTURE_ID, 0);
258 | if (pictureId != 0) {
259 | picture = BitmapFactory.decodeResource(getResources(), pictureId);
260 | }
261 |
262 | if (picture == null) {
263 | //noinspection deprecation
264 | picture = getIntent().getParcelableExtra(PAGE_PICTURE);
265 | }
266 |
267 | if (picture != null) {
268 | StringBuilder tmp = new StringBuilder("data:image/png;base64,");
269 | String base64 = bitmapToBase64(picture, getPictureSize(), size = new int[2]);
270 | if (base64 != null) {
271 | tmp.append(base64);
272 | imgSrc = tmp;
273 | }
274 | }
275 | }
276 |
277 | if (imgSrc != null) {
278 | sb.append("
");
291 | }
292 | }
293 |
294 | private void appendUrl(String url, String appId, FacebookLikeOptions options, StringBuilder sb) {
295 | sb.append("");
319 | }
320 |
321 | private View createRoot() {
322 | View result = null;
323 |
324 | int contentViewId = getIntent().getIntExtra(CONTENT_VIEW_ID, 0);
325 | if (contentViewId != 0) {
326 | result = getLayoutInflater().inflate(contentViewId, null);
327 | }
328 |
329 | if (result != null) {
330 | View container = result.findViewById(R.id.com_shamanland_facebook_like_container);
331 | if (container instanceof ViewGroup) {
332 | mContainer = (ViewGroup) container;
333 | }
334 | }
335 |
336 | if (mContainer == null) {
337 | mContainer = new FrameLayout(getContext());
338 | result = mContainer;
339 | }
340 |
341 | return result;
342 | }
343 |
344 | @SuppressLint("SetJavaScriptEnabled")
345 | @SuppressWarnings("deprecation")
346 | protected WebView createWindow() {
347 | FrameLayout wrapper = new FrameLayout(getContext());
348 | WebView window = new WebView(getContext());
349 | window.getSettings().setJavaScriptEnabled(true);
350 | window.getSettings().setSupportMultipleWindows(true);
351 | window.getSettings().setSavePassword(false);
352 | window.setWebChromeClient(mWebChromeClient);
353 | window.setWebViewClient(mWebViewClient);
354 |
355 | wrapper.addView(window);
356 | mWindows.add(window);
357 | mContainer.addView(wrapper);
358 | return window;
359 | }
360 |
361 | protected View createProgressBar(WebView window) {
362 | ViewParent parent = window.getParent();
363 | if (parent instanceof ViewGroup) {
364 | ViewGroup wrapper = (ViewGroup) parent;
365 |
366 | View result = getLayoutInflater().inflate(R.layout.com_shamanland_facebook_like_activity_progress, wrapper, false);
367 | if (result != null) {
368 | wrapper.addView(result, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
369 | result.setOnTouchListener(SKIP_TOUCH);
370 | return result;
371 | }
372 | }
373 |
374 | return null;
375 | }
376 |
377 | protected boolean removeWindow(WebView window) {
378 | if (mWindows.size() > 1) {
379 | mWindows.remove(window);
380 |
381 | ViewParent parent = window.getParent();
382 | if (parent instanceof View) {
383 | mContainer.removeView((View) parent);
384 | }
385 |
386 | detachFromParent(window);
387 | window.destroy();
388 | return true;
389 | } else {
390 | window.stopLoading();
391 | window.loadDataWithBaseURL("about:blank", "", "text/html", "utf-8", null);
392 | return false;
393 | }
394 | }
395 |
396 | public static String escapeHtml(String unsecure) {
397 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
398 | return Html.fromHtml(unsecure).toString();
399 | } else {
400 | return Html.escapeHtml(unsecure);
401 | }
402 | }
403 |
404 | public static String bitmapToBase64(Bitmap picture, int size, int[] outSize) {
405 | try {
406 | int w = picture.getWidth();
407 | int h = picture.getHeight();
408 |
409 | int max = Math.max(w, h);
410 | if (max > size) {
411 | float factor = max / (float) size;
412 | w = (int) (w / factor);
413 | h = (int) (h / factor);
414 |
415 | picture = Bitmap.createScaledBitmap(picture, w, h, false);
416 | }
417 |
418 | outSize[0] = w;
419 | outSize[1] = h;
420 |
421 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
422 | picture.compress(Bitmap.CompressFormat.PNG, 100, baos);
423 | return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
424 | } catch (Throwable ex) {
425 | if (LOGGING) {
426 | Log.wtf(LOG_TAG, ex);
427 | }
428 |
429 | return null;
430 | }
431 | }
432 |
433 | public static void detachFromParent(View view) {
434 | if (view != null) {
435 | ViewParent parent = view.getParent();
436 | if (parent instanceof ViewGroup) {
437 | ((ViewGroup) parent).removeView(view);
438 | }
439 | }
440 | }
441 |
442 | @SuppressWarnings("deprecation")
443 | public int getPictureSize() {
444 | return Math.min(
445 | getWindowManager().getDefaultDisplay().getWidth(),
446 | getWindowManager().getDefaultDisplay().getHeight()
447 | ) / 8;
448 | }
449 | }
450 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikeBox.java:
--------------------------------------------------------------------------------
1 | package com.shamanland.facebook.likebutton;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Paint;
7 | import android.graphics.drawable.Drawable;
8 | import android.graphics.drawable.LayerDrawable;
9 | import android.graphics.drawable.ShapeDrawable;
10 | import android.graphics.drawable.shapes.PathShape;
11 | import android.os.Build;
12 | import android.os.Handler;
13 | import android.os.HandlerThread;
14 | import android.os.Looper;
15 | import android.os.Message;
16 | import android.os.Process;
17 | import android.util.AttributeSet;
18 | import android.util.Log;
19 | import android.widget.Button;
20 |
21 | import com.shamanland.facebook.likebutton.FacebookLinkStatProcessor.Result;
22 |
23 | import static com.shamanland.facebook.likebutton.BuildConfig.LOGGING;
24 | import static com.shamanland.facebook.likebutton.CalloutPath.MARKER_BOTTOM;
25 | import static com.shamanland.facebook.likebutton.CalloutPath.MARKER_LEFT;
26 | import static com.shamanland.facebook.likebutton.CalloutPath.MARKER_NONE;
27 | import static com.shamanland.facebook.likebutton.CalloutPath.MARKER_RIGHT;
28 | import static com.shamanland.facebook.likebutton.CalloutPath.MARKER_TOP;
29 | import static com.shamanland.facebook.likebutton.CalloutPath.factor;
30 |
31 | public class FacebookLikeBox extends Button {
32 | private static final String LOG_TAG = FacebookLikeBox.class.getSimpleName();
33 | private static final Looper BACKGROUND;
34 |
35 | static {
36 | HandlerThread thread = new HandlerThread(FacebookLikeBox.class.getSimpleName(), Process.THREAD_PRIORITY_LOWEST);
37 | thread.start();
38 | BACKGROUND = thread.getLooper();
39 | }
40 |
41 | private Handler mHandler;
42 | private FacebookLinkStatProcessor mProcessor;
43 | private String mUrl;
44 | private boolean mAttachedToWindow;
45 |
46 | private CalloutPath mPath;
47 | private ShapeDrawable mFill;
48 | private ShapeDrawable mStroke;
49 | private float mCornerRadius;
50 | private int mCalloutMarker;
51 |
52 | public void setProcessor(FacebookLinkStatProcessor processor) {
53 | mProcessor = processor;
54 | }
55 |
56 | public void setPageUrl(String url) {
57 | String old = mUrl;
58 | mUrl = url;
59 |
60 | if (old == null && url != null || old != null && !old.equals(url)) {
61 | onUrlChanged(old, url);
62 | }
63 | }
64 |
65 | @Override
66 | public boolean isAttachedToWindow() {
67 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
68 | return mAttachedToWindow;
69 | } else {
70 | return super.isAttachedToWindow();
71 | }
72 | }
73 |
74 | public FacebookLikeBox(Context context) {
75 | super(context);
76 | init(null);
77 | }
78 |
79 | public FacebookLikeBox(Context context, AttributeSet attrs) {
80 | super(context, attrs);
81 | init(attrs);
82 | }
83 |
84 | public FacebookLikeBox(Context context, AttributeSet attrs, int defStyle) {
85 | super(context, attrs, defStyle);
86 | init(attrs);
87 | }
88 |
89 | private void init(AttributeSet attrs) {
90 | mProcessor = new FacebookLinkStatProcessor();
91 |
92 | mHandler = new Handler(BACKGROUND, new Handler.Callback() {
93 | @Override
94 | public boolean handleMessage(Message msg) {
95 | processUrl((String) msg.obj);
96 | return true;
97 | }
98 | });
99 |
100 | if (attrs == null) {
101 | return;
102 | }
103 |
104 | Context c = getContext();
105 | if (c == null) {
106 | return;
107 | }
108 |
109 | TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.FacebookLikeBox);
110 | if (a == null) {
111 | return;
112 | }
113 |
114 | Resources r = getResources();
115 | if (r == null) {
116 | return;
117 | }
118 |
119 | try {
120 | mPath = new CalloutPath();
121 | mFill = new ShapeDrawable();
122 | mFill.getPaint().setStyle(Paint.Style.FILL);
123 | mFill.getPaint().setColor(a.getColor(R.styleable.FacebookLikeBox_boxFillColor, r.getColor(R.color.com_shamanland_facebook_like_box_background_color)));
124 | mStroke = new ShapeDrawable();
125 | mStroke.getPaint().setStyle(Paint.Style.STROKE);
126 | mStroke.getPaint().setColor(a.getColor(R.styleable.FacebookLikeBox_boxStrokeColor, r.getColor(R.color.com_shamanland_facebook_like_box_text_color)));
127 | mStroke.getPaint().setAntiAlias(true);
128 | mStroke.getPaint().setStrokeWidth(a.getDimension(R.styleable.FacebookLikeBox_boxStrokeWidth, r.getDimension(R.dimen.com_shamanland_facebook_like_box_stroke_width)));
129 | mCornerRadius = a.getDimension(R.styleable.FacebookLikeBox_boxCornersRadius, r.getDimension(R.dimen.com_shamanland_facebook_like_corners_radius));
130 | mCalloutMarker = a.getInt(R.styleable.FacebookLikeBox_calloutMarker, MARKER_NONE);
131 |
132 | initBackground();
133 | } finally {
134 | a.recycle();
135 | }
136 | }
137 |
138 | @SuppressWarnings("deprecation")
139 | private void initBackground() {
140 | int pl = (int) (getPaddingLeft() + factor(mCalloutMarker, MARKER_LEFT) * mCornerRadius);
141 | int pt = (int) (getPaddingTop() + factor(mCalloutMarker, MARKER_TOP) * mCornerRadius);
142 | int pr = (int) (getPaddingRight() + factor(mCalloutMarker, MARKER_RIGHT) * mCornerRadius);
143 | int pb = (int) (getPaddingBottom() + factor(mCalloutMarker, MARKER_BOTTOM) * mCornerRadius);
144 |
145 | Drawable drawable = new LayerDrawable(new Drawable[]{mFill, mStroke});
146 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
147 | setBackgroundDrawable(drawable);
148 | } else {
149 | setBackground(drawable);
150 | }
151 |
152 | setPadding(pl, pt, pr, pb);
153 | }
154 |
155 | @Override
156 | protected void onAttachedToWindow() {
157 | super.onAttachedToWindow();
158 | mAttachedToWindow = true;
159 | }
160 |
161 | @Override
162 | protected void onDetachedFromWindow() {
163 | super.onDetachedFromWindow();
164 | mAttachedToWindow = false;
165 | }
166 |
167 | @Override
168 | protected void onSizeChanged(int w, int h, int oldW, int oldH) {
169 | mPath.build(mCalloutMarker, w, h, mStroke.getPaint().getStrokeWidth(), mCornerRadius);
170 | PathShape shape = new PathShape(mPath, w, h);
171 | mFill.setShape(shape);
172 | mStroke.setShape(shape);
173 | }
174 |
175 | protected void onUrlChanged(String oldValue, String newValue) {
176 | setText(R.string.com_shamanland_facebook_like_box_text_default);
177 |
178 | if (oldValue != null) {
179 | mHandler.removeMessages(0, oldValue);
180 | }
181 |
182 | if (newValue != null) {
183 | Message msg = Message.obtain();
184 | if (msg != null) {
185 | msg.obj = newValue;
186 | mHandler.sendMessage(msg);
187 | }
188 | }
189 | }
190 |
191 | /**
192 | * Background thread
193 | */
194 | protected void processUrl(final String url) {
195 | try {
196 | final Result result = mProcessor.processUrl(url);
197 | post(new Runnable() {
198 | @Override
199 | public void run() {
200 | if (isAttachedToWindow()) {
201 | postProcessUrl(url, result);
202 | }
203 | }
204 | });
205 | } catch (Throwable ex) {
206 | if (LOGGING) {
207 | Log.wtf(LOG_TAG, ex);
208 | }
209 | }
210 | }
211 |
212 | protected void postProcessUrl(String url, Result result) {
213 | if (url.equals(mUrl)) {
214 | onUrlProcessed(result);
215 | }
216 | }
217 |
218 | protected void onUrlProcessed(Result result) {
219 | setText(prettyNumber(result.shares));
220 | }
221 |
222 | protected String prettyNumber(long number) {
223 | if (number > 1000000000L) {
224 | return number / 1000000000L + "." + (number % 1000000000L) / 100000000L + "b";
225 | } else if (number > 1000000L) {
226 | return number / 1000000L + "." + (number % 1000000L) / 100000L + "m";
227 | } else if (number > 1000L) {
228 | return number / 1000L + "." + (number % 1000L) / 100L + "k";
229 | } else {
230 | return String.valueOf(number);
231 | }
232 | }
233 | }
234 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikeButton.java:
--------------------------------------------------------------------------------
1 | package com.shamanland.facebook.likebutton;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Bitmap;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.Button;
10 |
11 | public class FacebookLikeButton extends Button {
12 | public interface OnPageUrlChangeListener {
13 | void onPageUrlChanged(String newValue);
14 | }
15 |
16 | private String mPageUrl;
17 | private String mPageTitle;
18 | private String mPageText;
19 | @Deprecated
20 | private Bitmap mPagePicture;
21 | private String mPagePictureUrl;
22 | private int mPagePictureId;
23 | private String mAppId;
24 | private int mContentViewId;
25 | private FacebookLikeOptions mOptions;
26 |
27 | private OnPageUrlChangeListener mOnPageUrlChangeListener;
28 |
29 | public String getPageUrl() {
30 | return mPageUrl;
31 | }
32 |
33 | public void setPageUrl(String pageUrl) {
34 | mPageUrl = pageUrl;
35 |
36 | if (mOnPageUrlChangeListener != null) {
37 | mOnPageUrlChangeListener.onPageUrlChanged(mPageUrl);
38 | }
39 | }
40 |
41 | public String getPageTitle() {
42 | return mPageTitle;
43 | }
44 |
45 | public void setPageTitle(String pageTitle) {
46 | mPageTitle = pageTitle;
47 | }
48 |
49 | public String getPageText() {
50 | return mPageText;
51 | }
52 |
53 | public void setPageText(String pageText) {
54 | mPageText = pageText;
55 | }
56 |
57 | @Deprecated
58 | public Bitmap getPagePicture() {
59 | //noinspection deprecation
60 | return mPagePicture;
61 | }
62 |
63 | @Deprecated
64 | public void setPagePicture(Bitmap pagePicture) {
65 | //noinspection deprecation
66 | mPagePicture = pagePicture;
67 | }
68 |
69 | public String getPagePictureUrl() {
70 | return mPagePictureUrl;
71 | }
72 |
73 | public void setPagePictureUrl(String pagePictureUrl) {
74 | mPagePictureUrl = pagePictureUrl;
75 | }
76 |
77 | public int getPagePictureId() {
78 | return mPagePictureId;
79 | }
80 |
81 | public void setPagePictureId(int pagePictureId) {
82 | mPagePictureId = pagePictureId;
83 | }
84 |
85 | public String getAppId() {
86 | return mAppId;
87 | }
88 |
89 | public void setAppId(String appId) {
90 | mAppId = appId;
91 | }
92 |
93 | public int getContentViewId() {
94 | return mContentViewId;
95 | }
96 |
97 | public void setContentViewId(int contentViewId) {
98 | mContentViewId = contentViewId;
99 | }
100 |
101 | public FacebookLikeOptions getOptions() {
102 | return mOptions;
103 | }
104 |
105 | public void setOptions(FacebookLikeOptions options) {
106 | mOptions = options;
107 | }
108 |
109 | public void setOnPageUrlChangeListener(OnPageUrlChangeListener listener) {
110 | mOnPageUrlChangeListener = listener;
111 |
112 | if (mOnPageUrlChangeListener != null) {
113 | mOnPageUrlChangeListener.onPageUrlChanged(mPageUrl);
114 | }
115 | }
116 |
117 | public FacebookLikeButton(Context context) {
118 | super(context);
119 | init(null);
120 | }
121 |
122 | public FacebookLikeButton(Context context, AttributeSet attrs) {
123 | super(context, attrs);
124 | init(attrs);
125 | }
126 |
127 | public FacebookLikeButton(Context context, AttributeSet attrs, int defStyle) {
128 | super(context, attrs, defStyle);
129 | init(attrs);
130 | }
131 |
132 | private void initAttrs(AttributeSet attrs) {
133 | if (attrs == null) {
134 | return;
135 | }
136 |
137 | Context c = getContext();
138 | if (c == null) {
139 | return;
140 | }
141 |
142 | TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.FacebookLikeButton, 0, 0);
143 | if (a == null) {
144 | return;
145 | }
146 |
147 | try {
148 | mPageUrl = a.getString(R.styleable.FacebookLikeButton_pageUrl);
149 | mPageTitle = a.getString(R.styleable.FacebookLikeButton_pageTitle);
150 | mPageText = a.getString(R.styleable.FacebookLikeButton_pageText);
151 |
152 | mPagePictureUrl = a.getString(R.styleable.FacebookLikeButton_pagePictureUrl);
153 | mPagePictureId = a.getResourceId(R.styleable.FacebookLikeButton_pagePictureId, 0);
154 | if (mPagePictureId == 0) {
155 | mPagePictureId = a.getResourceId(R.styleable.FacebookLikeButton_pagePicture, 0);
156 | }
157 |
158 | mAppId = a.getString(R.styleable.FacebookLikeButton_appId);
159 | mContentViewId = a.getResourceId(R.styleable.FacebookLikeButton_contentViewId, 0);
160 |
161 | mOptions = new FacebookLikeOptions();
162 | mOptions.titleOpen = getString(a, R.styleable.FacebookLikeButton_optTitleOpen, mOptions.titleOpen);
163 | mOptions.titleClose = getString(a, R.styleable.FacebookLikeButton_optTitleClose, mOptions.titleClose);
164 | mOptions.textOpen = getString(a, R.styleable.FacebookLikeButton_optTextOpen, mOptions.textOpen);
165 | mOptions.textClose = getString(a, R.styleable.FacebookLikeButton_optTextClose, mOptions.textClose);
166 | mOptions.pictureAttrs = getString(a, R.styleable.FacebookLikeButton_optPictureAttrs, mOptions.pictureAttrs);
167 | mOptions.layout = FacebookLikeOptions.Layout.values()[a.getInt(R.styleable.FacebookLikeButton_optLayout, 0)];
168 | mOptions.action = FacebookLikeOptions.Action.values()[a.getInt(R.styleable.FacebookLikeButton_optAction, 0)];
169 | mOptions.showFaces = a.getBoolean(R.styleable.FacebookLikeButton_optShowFaces, mOptions.showFaces);
170 | mOptions.share = a.getBoolean(R.styleable.FacebookLikeButton_optShare, mOptions.share);
171 | } finally {
172 | a.recycle();
173 | }
174 | }
175 |
176 | private String getString(TypedArray a, int index, String defValue) {
177 | String read = a.getString(index);
178 | return read != null ? read : defValue;
179 | }
180 |
181 | private void init(AttributeSet attrs) {
182 | if (attrs != null) {
183 | initAttrs(attrs);
184 | }
185 |
186 | setOnClickListener(new OnClickListener() {
187 | @Override
188 | public void onClick(View v) {
189 | performLike();
190 | }
191 | });
192 | }
193 |
194 | public void performLike() {
195 | Context c = getContext();
196 | if (c == null) {
197 | return;
198 | }
199 |
200 | Intent intent = new Intent(c, FacebookLikeActivity.class);
201 | intent.putExtra(FacebookLikeActivity.PAGE_URL, mPageUrl);
202 | intent.putExtra(FacebookLikeActivity.PAGE_TITLE, mPageTitle);
203 | intent.putExtra(FacebookLikeActivity.PAGE_TEXT, mPageText);
204 | intent.putExtra(FacebookLikeActivity.PAGE_PICTURE_URL, mPagePictureUrl);
205 | intent.putExtra(FacebookLikeActivity.PAGE_PICTURE_ID, mPagePictureId);
206 |
207 | //noinspection deprecation
208 | if (mPagePictureUrl == null && mPagePictureId == 0 && mPagePicture != null) {
209 | //noinspection deprecation
210 | intent.putExtra(FacebookLikeActivity.PAGE_PICTURE, mPagePicture);
211 | }
212 |
213 | intent.putExtra(FacebookLikeActivity.APP_ID, mAppId);
214 | intent.putExtra(FacebookLikeActivity.CONTENT_VIEW_ID, mContentViewId);
215 | intent.putExtra(FacebookLikeActivity.OPTIONS, mOptions);
216 | c.startActivity(intent);
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikeOptions.java:
--------------------------------------------------------------------------------
1 | package com.shamanland.facebook.likebutton;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import java.util.Locale;
7 |
8 | public final class FacebookLikeOptions implements Parcelable {
9 | public enum Layout {
10 | STANDARD, BOX_COUNT, BUTTON_COUNT, BUTTON
11 | }
12 |
13 | public enum Action {
14 | LIKE, RECOMMEND
15 | }
16 |
17 | public String titleOpen = "";
18 | public String titleClose = "
";
19 | public String textOpen = "";
20 | public String textClose = "
";
21 | public String pictureAttrs = "style='float:left;margin:4px;'";
22 | public Layout layout = Layout.STANDARD;
23 | public Action action = Action.LIKE;
24 | public boolean showFaces = true;
25 | public boolean share = true;
26 |
27 | public String getLayoutString() {
28 | return (layout != null ? layout : Layout.STANDARD).name().toLowerCase(Locale.US);
29 | }
30 |
31 | public String getActionString() {
32 | return (action != null ? action : Action.LIKE).name().toLowerCase(Locale.US);
33 | }
34 |
35 | public FacebookLikeOptions setTitleOpen(String titleOpen) {
36 | this.titleOpen = titleOpen;
37 | return this;
38 | }
39 |
40 | public FacebookLikeOptions setTitleClose(String titleClose) {
41 | this.titleClose = titleClose;
42 | return this;
43 | }
44 |
45 | public FacebookLikeOptions setTextOpen(String textOpen) {
46 | this.textOpen = textOpen;
47 | return this;
48 | }
49 |
50 | public FacebookLikeOptions setTextClose(String textClose) {
51 | this.textClose = textClose;
52 | return this;
53 | }
54 |
55 | public FacebookLikeOptions setPictureAttrs(String pictureAttrs) {
56 | this.pictureAttrs = pictureAttrs;
57 | return this;
58 | }
59 |
60 | public FacebookLikeOptions setLayout(Layout layout) {
61 | this.layout = layout;
62 | return this;
63 | }
64 |
65 | public FacebookLikeOptions setAction(Action action) {
66 | this.action = action;
67 | return this;
68 | }
69 |
70 | public FacebookLikeOptions setShowFaces(boolean showFaces) {
71 | this.showFaces = showFaces;
72 | return this;
73 | }
74 |
75 | public FacebookLikeOptions setShare(boolean share) {
76 | this.share = share;
77 | return this;
78 | }
79 |
80 | public FacebookLikeOptions() {
81 | super();
82 | }
83 |
84 | @Override
85 | public boolean equals(Object o) {
86 | if (this == o) return true;
87 | if (o == null || ((Object) this).getClass() != o.getClass()) return false;
88 |
89 | FacebookLikeOptions that = (FacebookLikeOptions) o;
90 |
91 | if (share != that.share) return false;
92 | if (showFaces != that.showFaces) return false;
93 | if (action != that.action) return false;
94 | if (layout != that.layout) return false;
95 | if (pictureAttrs != null ? !pictureAttrs.equals(that.pictureAttrs) : that.pictureAttrs != null)
96 | return false;
97 | if (textClose != null ? !textClose.equals(that.textClose) : that.textClose != null)
98 | return false;
99 | if (textOpen != null ? !textOpen.equals(that.textOpen) : that.textOpen != null)
100 | return false;
101 | if (titleClose != null ? !titleClose.equals(that.titleClose) : that.titleClose != null)
102 | return false;
103 | if (titleOpen != null ? !titleOpen.equals(that.titleOpen) : that.titleOpen != null)
104 | return false;
105 |
106 | return true;
107 | }
108 |
109 | @Override
110 | public int hashCode() {
111 | int result = titleOpen != null ? titleOpen.hashCode() : 0;
112 | result = 31 * result + (titleClose != null ? titleClose.hashCode() : 0);
113 | result = 31 * result + (textOpen != null ? textOpen.hashCode() : 0);
114 | result = 31 * result + (textClose != null ? textClose.hashCode() : 0);
115 | result = 31 * result + (pictureAttrs != null ? pictureAttrs.hashCode() : 0);
116 | result = 31 * result + (layout != null ? layout.hashCode() : 0);
117 | result = 31 * result + (action != null ? action.hashCode() : 0);
118 | result = 31 * result + (showFaces ? 1 : 0);
119 | result = 31 * result + (share ? 1 : 0);
120 | return result;
121 | }
122 |
123 | public int describeContents() {
124 | return 0;
125 | }
126 |
127 | public void writeToParcel(Parcel out, int flags) {
128 | out.writeString(titleOpen);
129 | out.writeString(titleClose);
130 | out.writeString(textOpen);
131 | out.writeString(textClose);
132 | out.writeString(pictureAttrs);
133 | out.writeInt(layout != null ? layout.ordinal() : 0);
134 | out.writeInt(action != null ? action.ordinal() : 0);
135 | out.writeInt(showFaces ? 1 : 0);
136 | out.writeInt(share ? 1 : 0);
137 | }
138 |
139 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
140 | public FacebookLikeOptions createFromParcel(Parcel in) {
141 | return new FacebookLikeOptions(in);
142 | }
143 |
144 | public FacebookLikeOptions[] newArray(int size) {
145 | return new FacebookLikeOptions[size];
146 | }
147 | };
148 |
149 | private FacebookLikeOptions(Parcel in) {
150 | titleOpen = in.readString();
151 | titleClose = in.readString();
152 | textOpen = in.readString();
153 | textClose = in.readString();
154 | pictureAttrs = in.readString();
155 | layout = Layout.values()[in.readInt()];
156 | action = Action.values()[in.readInt()];
157 | showFaces = in.readInt() == 1;
158 | share = in.readInt() == 1;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikePlugin.java:
--------------------------------------------------------------------------------
1 | package com.shamanland.facebook.likebutton;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.os.Build;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.LinearLayout;
10 |
11 | import com.shamanland.facebook.likebutton.FacebookLikeButton.OnPageUrlChangeListener;
12 |
13 | public class FacebookLikePlugin extends LinearLayout {
14 | private int mLikeId;
15 | private int mBoxId;
16 |
17 | public FacebookLikePlugin(Context context) {
18 | super(context);
19 | init(null);
20 | }
21 |
22 | public FacebookLikePlugin(Context context, AttributeSet attrs) {
23 | super(context, attrs);
24 | init(attrs);
25 | }
26 |
27 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
28 | public FacebookLikePlugin(Context context, AttributeSet attrs, int defStyle) {
29 | super(context, attrs, defStyle);
30 | init(attrs);
31 | }
32 |
33 | private void init(AttributeSet attrs) {
34 | if (attrs == null) {
35 | return;
36 | }
37 |
38 | Context c = getContext();
39 | if (c == null) {
40 | return;
41 | }
42 |
43 | TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.FacebookLikePlugin);
44 | if (a == null) {
45 | return;
46 | }
47 |
48 | try {
49 | mLikeId = a.getResourceId(R.styleable.FacebookLikePlugin_likeId, R.id.com_shamanland_facebook_like);
50 | mBoxId = a.getResourceId(R.styleable.FacebookLikePlugin_boxId, R.id.com_shamanland_facebook_like_box);
51 | } finally {
52 | a.recycle();
53 | }
54 | }
55 |
56 | @Override
57 | protected void onFinishInflate() {
58 | super.onFinishInflate();
59 |
60 | final View like = findViewById(mLikeId);
61 | final View box = findViewById(mBoxId);
62 |
63 | if (like instanceof FacebookLikeButton && box instanceof FacebookLikeBox) {
64 | ((FacebookLikeButton) like).setOnPageUrlChangeListener(new OnPageUrlChangeListener() {
65 | @Override
66 | public void onPageUrlChanged(String newValue) {
67 | ((FacebookLikeBox) box).setPageUrl(newValue);
68 | }
69 | });
70 |
71 | box.setOnClickListener(new OnClickListener() {
72 | @Override
73 | public void onClick(View v) {
74 | like.performClick();
75 | }
76 | });
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLinkStatProcessor.java:
--------------------------------------------------------------------------------
1 | package com.shamanland.facebook.likebutton;
2 |
3 | import android.util.Log;
4 |
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.IOException;
10 | import java.io.InputStreamReader;
11 | import java.net.HttpURLConnection;
12 | import java.net.URL;
13 | import java.net.URLConnection;
14 |
15 | import static com.shamanland.facebook.likebutton.BuildConfig.LOGGING;
16 |
17 | public class FacebookLinkStatProcessor {
18 | private static final String LOG_TAG = FacebookLinkStatProcessor.class.getSimpleName();
19 |
20 | public static class Result {
21 | public String url;
22 | public long shares;
23 | public long comments;
24 | }
25 |
26 | protected String getRequestUrl(String url) {
27 | return "https://graph.facebook.com/" + url;
28 | }
29 |
30 | protected Result getResult(String url, JSONObject json) {
31 | Result result = new Result();
32 | result.url = url;
33 | result.shares = getShares(json);
34 | result.comments = getComments(json);
35 | return result;
36 | }
37 |
38 | protected long getShares(JSONObject json) {
39 | return json.optLong("shares", 0);
40 | }
41 |
42 | protected long getComments(JSONObject json) {
43 | return json.optLong("comments", 0);
44 | }
45 |
46 | public Result processUrl(String url) throws IOException, JSONException {
47 | if (LOGGING) {
48 | Log.v(LOG_TAG, "processUrl: openConnection: " + url);
49 | }
50 |
51 | URLConnection connection = new URL(getRequestUrl(url)).openConnection();
52 | BufferedReader reader = null;
53 |
54 | try {
55 | reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
56 |
57 | StringBuilder sb = new StringBuilder();
58 | String line;
59 | while ((line = reader.readLine()) != null) {
60 | sb.append(line);
61 | }
62 |
63 | return getResult(url, new JSONObject(sb.toString()));
64 | } finally {
65 | if (reader != null) {
66 | reader.close();
67 | }
68 |
69 | if (connection instanceof HttpURLConnection) {
70 | ((HttpURLConnection) connection).disconnect();
71 | }
72 |
73 | if (LOGGING) {
74 | Log.v(LOG_TAG, "processUrl: disconnect: " + url);
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLinkStatTask.java:
--------------------------------------------------------------------------------
1 | package com.shamanland.facebook.likebutton;
2 |
3 | import android.os.AsyncTask;
4 |
5 | import com.shamanland.facebook.likebutton.FacebookLinkStatProcessor.Result;
6 |
7 | import java.lang.ref.WeakReference;
8 |
9 | public class FacebookLinkStatTask extends AsyncTask {
10 | public interface Listener {
11 | void onPostExecute(Result result);
12 | }
13 |
14 | private final FacebookLinkStatProcessor mProcessor;
15 | private final WeakReference mListener;
16 |
17 | public FacebookLinkStatTask(FacebookLinkStatProcessor processor, Listener listener) {
18 | mProcessor = processor;
19 | mListener = new WeakReference(listener);
20 | }
21 |
22 | @Override
23 | protected Result doInBackground(String... params) {
24 | try {
25 | return mProcessor.processUrl(params[0]);
26 | } catch (Throwable ex) {
27 | return null;
28 | }
29 | }
30 |
31 | @Override
32 | protected void onPostExecute(Result result) {
33 | Listener listener = mListener.get();
34 | if (listener != null) {
35 | listener.onPostExecute(result);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-hdpi/com_shamanland_facebook_inverse_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamanland/facebook-like-button/1aed39f8d7f2a9870b6d81f4c4a0f2526d344ca1/lib/src/main/res/drawable-hdpi/com_shamanland_facebook_inverse_icon.png
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-mdpi/com_shamanland_facebook_inverse_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamanland/facebook-like-button/1aed39f8d7f2a9870b6d81f4c4a0f2526d344ca1/lib/src/main/res/drawable-mdpi/com_shamanland_facebook_inverse_icon.png
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-xhdpi/com_shamanland_facebook_inverse_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shamanland/facebook-like-button/1aed39f8d7f2a9870b6d81f4c4a0f2526d344ca1/lib/src/main/res/drawable-xhdpi/com_shamanland_facebook_inverse_icon.png
--------------------------------------------------------------------------------
/lib/src/main/res/drawable/com_shamanland_facebook_button_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
7 |
8 |
9 |
13 |
17 |
18 |
19 | -
23 |
24 |
25 |
29 |
30 |
31 | -
34 |
35 |
36 |
40 |
44 |
45 |
46 | -
50 |
51 |
52 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/lib/src/main/res/layout/com_shamanland_facebook_like_activity_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/lib/src/main/res/values-hdpi/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/src/main/res/values-xhdpi/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #5975b0
4 | #50699e
5 | #7a90bf
6 | #6982b7
7 | #375196
8 | #3b538e
9 | #425d9e
10 | #344a7e
11 | #898f9c
12 | #8fff
13 | #fff
14 |
15 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 28sp
4 | 4sp
5 | 0sp
6 | 4sp
7 | 0sp
8 | 2sp
9 | 14sp
10 | 3sp
11 | 40dp
12 | 1dp
13 | 6sp
14 | 3sp
15 | 6sp
16 | 3sp
17 |
18 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Facebook
4 | Like
5 | Share
6 | Recommend
7 | 0
8 | Action \'like\' could not be done
9 |
10 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/styleable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
26 |
40 |
41 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | Facebook Like Button
2 | ====
3 |
4 | [](https://travis-ci.org/shamanland/facebook-like-button)
5 |
6 | Implementation of [Facebook 'Like' social plugin][8] for Android.
7 |
8 | Official [Facebook SDK][12] does not provide such component for Android.
9 |
10 | This library uses ``WebView`` to display ``