[转载]Android上利用Facebook SDK的开发——上传图文到涂鸦墙 – lingyun1120 – 博客园.
由于众所周知的原因,国内不能上脸书,但是由于公司产品需要在M国发布,所以在Facebook的共享功能成了我最近的主要任务。写下这篇文章,希望帮助到大家。
一、如何登录到的Facebook方便开发?
登录FB当然是进行翻墙,在进行开发之前,我先介绍一个比较好的工具——VPN。这个东西的强大之处是无论PC,还是手机都可以十分方便地进行翻墙。国内较好的VPN是greenvpn,它的地址是:https://www.green002.com/index.php?option=com_user&task=register&affid=98670。它的优势有免费的VPN可以使用,而且速度不错,但是由于免费的,每20分钟就会需要重新登录VPN一次。注册之后里面有详细的教程(PC有客户端,Android手机有设置教程),这次不再赘述,开始进入正题。
二、Facebook API简介
在介绍 Facebook SDK for Android 之前,有必要了解一下 Facebook Platform 及其 API。据 Facebook 声称,Facebook Platform 允许任何人 “在 Facebook 和 Web 上构建社交应用程序”。为了允许您构建此类应用程序,Facebook 提供广泛的一组核心且高级的 API 和 SDK。
核心 Facebook Platform API 是 Graph API,它允许您从 Facebook 读写数据。Facebook 也具有 Old Rest API。新的 Graph API 将 API 范型从面向方法的 从 Facebook 读写数据的方式更改为一种新的方式,即使用对象(比如说用户简介、好友、帖子、照片,诸如此类)及其相互之间的关系或连接。该方法简化了 Facebook API,使之处理对象时更加一致。注意,尽管 Graph API 是首选的 Facebook API,但是 Old REST API 仍然是活跃且受支持的。Graph 和 REST API 都适用于移动应用程序(包括原生和移动 web 应用程序),它们通过使用 WebViews 在原生应用程序中包含移动 web 内容。
Graph API 对象被分配一个惟一的 ID,很容易使用一个 URL 访问它,此 URL 可被进一步限定,以寻址一个特定的对象/连接。对象 URL 的一般结构类似如下: https://graph.facebook.com/OBJECT_ID/CONNECTION_TYPE,其中 OBJECT_ID 是对象的惟一 ID,CONNECTION_TYPE 是对象支持的一种连接类型。例如,一个页面支持以下连接:feed/wall、photos、notes、posts、members,等等。
利用 Graph API,您可以检索对象,删除对象和发布对象。您可以搜索、更新对象、过滤结果,甚至动态地发现对象的连接/关系。
默认情况下,应用程序对用户的公共数据具有访问权限。要访问私有数据,应用程序必须首先请求用户的权限(被称之为扩展权限)。Facebook 定义了大量权限,您可以在 Extended Permissions 页面了解它们。
三、导入Facebook SDK
把facebook sdk所提供的工程导入到Eclipse了,所以要让我们的工程拥有与facebook沟通的能力,就必须将该工程以library的方式参考到新建工程 当中,在工程名称上点击右键,选择”Properties”,选择第二项”Android”,并於library框中利用”Add”加进 com_facebook_android该工程。
四、Facebook的登录与发布文字消息
1 //这里的APPID是你在Facebook申请的APPKEY 2 private Facebook mFacebook = new Facebook(FACEBOOK_APP_ID); 3 private static final String[] PERMISSIONS = new String[] { 4 "publish_stream", "read_stream", "offline_access","user_photos" }; 5 6 7 AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(mFacebook); 8 mFacebook.authorize(AAuthTestActivity.this, 9 PERMISSIONS, new LoginDialogListener()); 10 11 12 //我是在完成登录之后马上就发布文字消息,这点大家可以灵活修改 13 private final class LoginDialogListener implements 14 com.facebook.android.Facebook.DialogListener { 15 public void onComplete(Bundle values) { 16 Log.e("FB Sample App", "LoginDialogListener.onComplete()"); 17 refreshListView(); 18 postToWall(values.getString(Facebook.TOKEN)); 19 } 20 21 public void onFacebookError(FacebookError error) { 22 Log.d("FB Sample App", "LoginDialogListener.onFacebookError()"); 23 } 24 25 public void onError(DialogError error) { 26 Log.d("FB Sample App", "LoginDialogListener.onError()"); 27 } 28 29 public void onCancel() { 30 Log.d("FB Sample App", "LoginDialogListener.onCancel()"); 31 } 32 33 private void postToWall(String string) { 34 Bundle params = new Bundle(); 35 params.putString(Facebook.TOKEN, accessToken); 36 try { 37 params.putString("message", "Test!!!!"); 38 mFacebook.request("me/feed", params, "POST"); 39 } catch (FileNotFoundException e) { 40 e.printStackTrace(); 41 } catch (MalformedURLException e) { 42 e.printStackTrace(); 43 } catch (IOException e) { 44 e.printStackTrace(); 45 } 46 } 47 }
这里需要注意的是:PERMISSIONS 字符串,这里是在登录授权时把哪些权限进行了说明,其中比如publish_stream为是否可以发布消息到涂鸦墙,read_stream为读取涂鸦墙,user_photos为图片相关的权限。(官方文件的詳細權限列表)
五、 发布图片到涂鸦墙(Wall)
这是困扰我最久的问题。传送图片都不是问题,主要是如何把照片发布到涂鸦墙上去,如同新浪微博一样——发送带图的微博,我们需要的是如何发送带图的文字信息到涂鸦墙上去。这里简述一下上传图片几个方法以及我最终的解决方法,主要是参考了网上的几个帖子。
我想要实现的效果:
效果应该是:1这儿的文字消息用来告诉朋友我的这个软件在哪儿可以找到。
2这儿的图片就是展示这个软件最后做到了怎样一个效果,用来吸引其他的用户。
第一种:
1 Bundle params = new Bundle(); 2 params.putString("message", "Uploaded on!!!!!!"); 3 params.putByteArray("picture", bytes); //bytes contains photo bytes, no problem here 4 asyncRunner.request("me/photos", params, "POST", new PostPhotoRequestListener(), null);
产生的效果:我只是把图片发送到了自己的相册,涂鸦墙上也显示了“某某把若干图片加入到XX相册”。但我想分享的文字消息在涂鸦墙上看不到,这就大大削弱了分享的效果。
第二种:
1 Bundle params = new Bundle(); 2 params.putString("message", "Uploaded on " + now()); 3 params.putString("link", "http://i1114.photobucket.com/albums/k538/tom_rada/bota2.jpg"); 4 asyncRunner.request("me/feed", params, "POST", new PostPhotoRequestListener(), null);
产生的效果:可以在涂鸦墙看到文字与图片,可是由于项目希望是本地上传显示,而不是利用连接显示某一图片,所以这个方案放弃。
第三种:
1 Bundle params = new Bundle(); 2 params.putString("message", "Uploaded on " + now()); 3 params.putByteArray("picture", bytes); //bytes contains photo bytes, no problem here 4 asyncRunner.request("me/feed", params, "POST", new PostPhotoRequestListener(), null);
产生的效果:利用me/feed接口其实只能展示文字,所以图片完全不能上传,失败
解决办法:
1 String wallAlbumID = null; 2 String response = facebook.request("me/albums"); 3 JSONObject json = Util.parseJson(response); 4 JSONArray albums = json.getJSONArray("data"); 5 for (int i =0; i < albums.length(); i++) { 6 JSONObject album = albums.getJSONObject(i); 7 if (album.getString("type").equalsIgnoreCase("wall")) { 8 wallAlbumID = album.getString("id"); 9 Log.d("JSON", wallAlbumID); 10 break; 11 } 12 } 13 14 if (wallAlbumID != null) { 15 Bundle params = new Bundle(); 16 params.putString("message", "Uploaded on " + now()); 17 params.putByteArray("source", bytes); 18 asyncRunner.request(wallAlbumID+"/photos", params, "POST", new PostPhotoRequestListener(), null); 19 }
产生的效果:其实我们在facebook网页上直接发送带图文字消息,FB将图片放在了一个type属性是wall的 特定相册中,所以我们的思路是找的这个相册,然后上传图片加文字消息,这样涂鸦墙上就可以完整地显示我们的文字加图片的消息。但是这里也存在一个隐患,如 果用户从来没有发不过带图文字消息的话,相册中就不会有wall这个相册,所以接下来要做的就是新建这么一个相册,在传入图片,这里就不再赘述。
最后希望对大家有所帮助,虽然知道国内开发这个FB的不多,重在分享么。有什么问题在下面留言啊。
P.S.本来是有一篇关于利用(新浪、腾讯、开心、空间、豆瓣……)API发送消息这么一篇文章的,但是由于本人实在懒惰,所以一直放在草稿箱,没有完成#_#,最近尽可能发布。