Android 应用中社交网络集成的初学者指南:与 Twitter 和 Facebook 合作





5.00/5 (5投票s)
Android 中社交网络集成的简单分步指南
- 下载 Testing-Facebook-Integration-App.zip - 2.4 MB
- 下载 facebookIntegrationEssentials.zip - 653 KB
- 下载 SocialIntegration_TWITTER_PART.zip - 2.2 MB
目录
1. 背景
如果你是一名有抱负的 Android 应用开发者,那么你应该学习的第一件事就是应用的社交网络集成。事实上,用户非常喜欢在社交网络上分享他们在应用中获得的分数、编辑过的照片或完成的任务。如果你正在开发一个“步行应用”,用户会喜欢分享他们走过的距离。如果你正在开发一个卡路里计算应用,那么分享一个超重者减掉了多少卡路里对用户来说总是很直观的。
但是,社交集成不仅限于应用用户的愉悦感或只是应用的另一个功能。它极大地提高了应用的可见性,并通过社交网络帮助你推广你的应用。换句话说,这是应用的免费广告。
尽管有许多关于 Android 平台社交集成的教程和“操作方法”,但我还没有找到任何一篇文章能够从一个单一的界面详细介绍 Twitter 和 Facebook。
在本教程中:
1) 我们将学习 Twitter 集成和获取推文
2) 我们将学习 Facebook 集成和访问 Facebook 的内容
3) 我们将最终应用我们的意见挖掘技术来分析内容,告诉用户内容的积极性。
2. Android Twitter 集成
Twitter 是一个最令人惊叹且功能强大的社交网络,它赋予了人们前所未有的权力。客户可以发布他们的投诉,粉丝可以向他们的明星发送加油和祝福信息,人们可以公开批评公众人物和政府官员,相关人员可以从推文中了解民众的情绪。因此,我们将学习如何从我们的应用发布推文,以及通过我们的账户从 Twitter 获取内容。
2.1 设置 Twitter API
Twitter 与大多数社交网络和热门网站一样,使用 128 位 SSL 加密数据。因此,与服务器之间的数据交换是安全的。因此,与 Twitter 合作需要 Twitter 对应用进行身份验证。此身份验证与应用开发者的账户绑定。
所以第一步是创建一个新应用并授予它必要的权限。打开以下地址:
https://dev.twitter.com/apps/new
图 2.1 Twitter 中的新应用注册
填写具有唯一应用名称的表单。网站和回调网站应与您的网站地址相同。另外一点要确保的是 URL 字段必须以“http://”开头。
如果您没有网站,您可以创建一个Blogger 博客,只需大约两分钟。虽然我强烈建议您拥有自己的网站。如果您想认真对待应用开发,这确实是一个重要的要求。
2.2 Twitter 应用创建成功
如您所见,默认情况下,应用创建时具有只读访问权限。您需要点击修改应用权限链接,并将权限更改为读、写和访问直接消息 。如果您的应用不发布任何内容,您可以保持原样。在大多数情况下,读写权限就足够了,应用无需访问直接消息。用户实际上讨厌那些尝试这样做的应用。但这是一个学习应用,我们将尝试所有选项。
图 2.3:更改应用权限
更新权限后,就可以获取密钥了。点击 API 密钥选项卡,您将看到密钥。(注意:出于安全原因,请勿公开分享您的 API 密钥和密钥)
图 2.4 Twitter 应用 API 密钥生成中的 API 密钥选项卡
在成功满足了初步要求后,是时候进入我们的 Android 平台并将 Twitter 应用集成到 Android 中了。
2.2 Twitter 集成的 Android 应用设置
幸运的是,有一个很棒的 Java 平台 Twitter 操作库,名为 **Twitter 4j**。它几乎可以用于所有 Java 平台,如 Swing、Applet,当然还有 Android。从这里>>下载该库。
在 Eclipse 中创建一个名为 SocialIntegration 的 Android 应用(您可以使用任何您喜欢的项目名称。由于本教程中使用 SocialIntegration,因此使用此项目名称可能会让步骤稍微容易一些),并将 Twitter 4j Core 库拖放到您项目的 lib 文件夹中,如下图 2.5 所示。
图 2.5:在 Android 项目中设置 Twitter 4j 库
现在,您可以进入 MainActivity.java 的导入部分,输入 **import twitter4j;**。如果一切正常,您将看到 twitter4j 包中的一列包。
2.3 应用布局
图 2.6 充分说明了我们应用的目标。a) 我们将提供一个登录按钮,该按钮应触发身份验证过程。一旦身份验证成功,用户就可以从应用发布推文。他还可以搜索 Twitter 中的某个词,结果会显示在 ListView 中。
图 2.6 Twitter 集成的应用布局
您可以设计布局,因为所有变量(控件)都可以在右上角面板中看到。另一方面,您可以使用以下现成的 XML 布局文件来快速拥有自己的布局。如果您正在复制 XML,请不要忘记清理并构建您的项目。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.integratedideas.socialintegration.MainActivity$PlaceholderFragment"
tools:ignore="HardcodedText" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp"
android:layout_below="@+id/edSearch" >
</ListView>
<EditText
android:id="@+id/edPublish"
android:layout_width="match_parent"
android:layout_marginRight="80dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/btnLoginNPublish"
android:layout_alignLeft="@+id/edSearch"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/edSearch"
android:layout_width="match_parent"
android:layout_marginRight="80dp"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/listView1"
android:layout_below="@+id/edPublish"
android:layout_marginTop="17dp"
android:ems="10" />
<TextView
android:id="@+id/tvMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignRight="@+id/edPublish"
android:layout_marginRight="64dp"
android:layout_marginTop="14dp"
android:text="TextView" />
<Button
android:id="@+id/btnSearch"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/listView1"
android:layout_alignRight="@+id/btnLoginNPublish"
android:text="Search" />
<Button
android:id="@+id/btnLoginNPublish"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvMessage"
android:layout_toRightOf="@+id/tvMessage"
android:text="Login" />
</RelativeLayout>
我们还将保持 edSearch、edPublish、btnSearch 在登录前不可见,并在登录后更改它们的可见性。其次,一旦登录成功,我们将把 btnLoginNPublish 的文本从初始文本“login”更改为“publish”。但这一切都通过代码完成。
首先,即身份验证应用并提取用户信息。
2.4 使用 oAuth 进行身份验证
为了理解身份验证如何工作,您应该首先查看图 2.7。它将阐明身份验证的概念。
图 2.7 是对包括 Twitter 和 Facebook 在内的任何社交网站应用进行身份验证的通用序列图。
所以让我们来理解我们将要做什么:我们将首先在我们的主应用中构建一个 URL,其中包含调用 Twitter 身份验证的 URL,该 URL 使用我们在图 2.4 中获得的 ApiSecret 和 ApiKey 进行解析,然后启动一个浏览器活动。
该浏览器页面将询问用户是否要授权该应用,如果用户同意,则将 URL 传递给 Twitter 服务器,Twitter 服务器成功验证 ApiKey 和 ApiSecret 以及通过浏览器 cookie 提取的用户凭据后,将返回访问令牌和访问密钥。如果用户尚未登录 Twitter,则会提示其输入用户名和密码,并且新提交的 URL 包含 api 密钥、api 密钥、用户名和密码。显然,由于 Twitter 使用 SSL,所有数据将在提交前被加密,因此可以认为足够安全。
一旦 AccessToken 或 Simple Token 从服务器返回到浏览器,它会附带一个用于重定向的简单 JavaScript,该 JavaScript 会强制应用使用包含 Access Token 和 Access Secret 的新数据重新加载。
现在,应用使用此令牌以及通过访问令牌获得的用户 ID 来进一步请求推文或进行发布。
2.5 oAuth 代码使用
您应该已经从我们 Android 数据处理教程的从 Web 获取数据部分了解了,要访问 Internet,您必须通过 Manifest 提供 INTERNET 权限。
因此,在您的 AndroidManifest.xml 的 <application> 标签之前添加以下两行:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
现在我们也知道网络相关的操作不允许在主线程中进行。为了解决这个问题,我们需要使用 AsyncTask。但是为了简单起见,我将通过在 `onCreate` 方法中调用 `super` 后添加以下代码行来 hack 它,以便您的应用可以访问网络操作。
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
让您的 MainActivity 类实现 OnClickListener。将按钮的点击监听器设置到重写的 `onClick` 方法中。在 `onClick` 方法中,使用 Executor 调用 Twitter 登录方法。
@Override
public void onClick(View v)
{
Button b=(Button)v;
if(b.getText().toString().trim().equals("Login"))
{
Executor exe=new Executor()
{
@Override
public void execute(Runnable command)
{
// TODO Auto-generated method stub
try
{
//loginToTwitter();
MyTwitterLogin();
}
catch(Exception ex)
{
Log.i("Exception:",ex.getMessage());
}
}
};
exe.execute(null);
}
}
以下是 **MyTwitterLogin()** 方法:
static final String TWITTER_CALLBACK_URL = "oauth://t4jSample";
static String PREFERENCE_NAME = "twitter_oauth";
static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
static final String PREF_KEY_OAUTH_SECRET = "oauth_token_secret";
static final String PREF_KEY_TWITTER_LOGIN = "isTwitterLogedIn";
static final String URL_TWITTER_AUTH = "auth_url";
static final String URL_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
static final String URL_TWITTER_OAUTH_TOKEN = "oauth_token";
public void MyTwitterLogin()
{
try {
twitter.setOAuthConsumer(ApiKey, ApiSecret);
requestToken = twitter
.getOAuthRequestToken(TWITTER_CALLBACK_URL);
MainActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse(requestToken.getAuthenticationURL())));
Log.i("Request Toke.....=>",requestToken.toString());
// twitter.setOAuthAccessToken(requestToken.getToken());
}
catch (Exception e)
{
Log.i("In getting Authentication",e.getMessage());
}
}
其中 ApiKey 和 ApiSecrets 是您从 Twitter 应用设置中获得的(参见图 2.4)。其他参数不得更改。请注意,我们正在启动一个 Intent,该 Intent 理想情况下会显示您的浏览器以及身份验证选项,如下图 2.9 所示,当点击登录按钮时(如图 2.8 所示)。
图 2.8:应用的初始屏幕
另请参阅图 2.10 中的请求令牌结构。这是 Twitter 响应的依据。
图 2.10:在图 2.9 的 URL 中传递的请求令牌
用户身份验证应用后,浏览器将显示身份验证成功,同时会再次打开主活动。
图 2.11:身份验证成功后的浏览器
重定向后,您的应用将重新加载,但其数据中会包含响应令牌。因此,当应用加载时,哪个方法会被调用?显然是 `onCreate`。因此,在 `onCreate` 方法中,我们将添加一个 if 循环,该循环在 MainActivity 的数据中包含响应令牌时触发。
Uri uri = getIntent().getData();
if(uri!=null && uri.toString().startsWith(TWITTER_CALLBACK_URL))
{
uri = getIntent().getData();
//URL_TWITTER_OAUTH_TOKEN
final String verifier = uri.getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);
final String token = uri.getQueryParameter(URL_TWITTER_OAUTH_TOKEN);
try {
MainActivity.this.accessToken = twitter.getOAuthAccessToken(requestToken, verifier);
long userID = accessToken.getUserId();
User user = twitter.showUser(userID);
uname = user.getName();
screenName=accessToken.getScreenName();
// Log.i(uname+" "+userID+" "+accessToken.getScreenName(),response.getText());
tvMessage.setText("Welcome "+uname+"("+screenName+")");
btnLoginNPublish.setText("Publish");
edSearch.setVisibility(View.VISIBLE);
edPublish.setVisibility(View.VISIBLE);
btnSearch.setVisibility(View.VISIBLE);
}
catch(Exception ex1)
{
Log.i("Fetching Access token Error",ex1.getMessage());
}
正如您从 `requestToken` 和 `verifier`(来自 Twitter 服务器的响应)中可以看到的,我们构建了一个 `accessToken`。此令牌包含所有用户相关信息。我们提取信息,然后使其他表单组件可见。
图 2.12:身份验证成功后的表单
其他初始化如下:
listView1=(ListView)findViewById(R.id.listView1);
tvMessage=(TextView)findViewById(R.id.tvMessage);
edSearch=(EditText)findViewById(R.id.edSearch);
tvMessage.setText("Please Login ");
btnLoginNPublish=(Button)findViewById(R.id.btnLoginNPublish);
btnLoginNPublish.setOnClickListener(this);
btnLoginNPublish.setText("Login");
btnSearch=(Button)findViewById(R.id.btnSearch);
btnSearch.setOnClickListener(this);
edPublish=(EditText)findViewById(R.id.edPublish);
if(twitter==null)
twitter = new TwitterFactory().getInstance();
edSearch.setVisibility(View.INVISIBLE);
edPublish.setVisibility(View.INVISIBLE);
btnSearch.setVisibility(View.INVISIBLE);
请记住,所有这些都必须出现在“if 循环”之前。否则,重定向后您将收到 NullPointerException,因为任何控件都不会被初始化。
更新
在处理此概念时,我意识到这种 oAuth 方法存在一些小问题。当我们尝试将此概念纳入其他应用时,Twitter 不会正确重定向。为了避免这个问题,请在您的 AndroidManifest.xml 中 MainActivity 的 intent-filter 之后添加以下 intent 过滤器:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="x-oauthflow-twitter" android:host="callback" />
</intent-filter>
现在将 Callback URL 更改为:
static final String TWITTER_CALLBACK_URL = "x-oauthflow-twitter://callback";
这应该可以解决重定向问题。
2.6 获取内容
我提供了一个简单的搜索选项。您可以搜索主题或用户名,它会显示所有结果。您需要做的就是传递一个查询字符串并调用搜索方法。搜索方法返回一个 **Status** 类的列表,其中每个 status 都包含推文、转推计数、收藏计数、提及、推文创建日期/时间等。我将使用一个简单的 StringArrayAdapter 来获取 status 并将其分配给列表框。您可以使用复杂 ListView 的概念来更愉快地呈现信息。
if(b.getText().toString().trim().equals("Search"))
{
ArrayList<String>tweetString=new ArrayList<String>();
try{
Query query = new Query(edSearch.getText().toString().trim());
List list = twitter.search(query).getTweets();
for (int i=0;i<list.size();i++)
{
twitter4j.Status each = (twitter4j.Status) list.get(i);
tweetString.add(each.getUser().getScreenName()+":" + each.getText()+" [Retweet:"+each.getRetweetCount()+", Favourites: "+ each.getFavoriteCount()+"]");
}
String [] tweets=tweetString.toArray(new String[1]);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, tweets);
listView1.setAdapter(adapter);
}catch(Exception ex)
{
}
}
图 2.13:搜索结果
2.7 发布推文
您可以通过调用 **updateStatus** 方法并以最简单的形式传递字符串来发布推文。
if(b.getText().toString().trim().equals("Publish"))
{
try{
StatusUpdate su=new StatusUpdate("");
su.
twitter4j.Status response = twitter.updateStatus(edPublish.getText().toString());
alert.showAlertDialog(this, "Posting Successfull", "Your Tweet is Posted In your Timeline", true);
}catch(Exception ex)
{
alert.showAlertDialog(this, "Posting Successfull", ex.getMessage(), false);
}
}
但是,如果您打算开发一个更完整的 Twitter 应用,那么您应该使用 StatusUpdate 对象。它提供了很多字段,包括回复其他推文的选项等等。图 2.15 显示了一些重要可能性。
图 2.14:状态更新成功(发布推文)
下载 SocialIntegration_TWITTER_PART.zip 并玩转这个应用。
在成功完成 Twitter 部分后,是时候研究 Facebook 集成技术了。
3. Facebook 集成
Facebook 集成比 Twitter 集成要棘手一些。Facebook 要求一个**签名应用**与其联系以进行授权。因此,集成并不直接。首先,您需要在 Eclipse 中生成一个密钥库,然后用该密钥库签名您的应用。您需要在注册您的应用到 Facebook 时提供签名密钥。因此,我们将首先从 Eclipse 获取密钥库,然后用它来签名您的应用。
3.1 在 Eclipse 中生成密钥库
点击 **Windows->Preferences->Debug**,如下所示。
记下默认调试密钥库的路径。现在打开您的命令提示符。您需要两个工具来为 Eclipse 生成密钥:1)**keytool** 2)**openssl**
keytool 始终位于您 Java 安装的 jre 目录中。如果 Java 的类路径已添加到您的系统中,那么您应该可以从任何地方访问它。
首先在命令提示符中输入 **keytool** 并回车。如果看到“命令未找到”,那么您需要手动更改到 jre 目录。现在输入 keytool 命令,您将看到它的用法。
图 3.2:定位并切换到 keytool 所在的 jre 目录。
您需要的下一个工具是 openssl。再次输入命令 **openssl**。如果您的命令提示符再次显示“命令未找到”,那么您需要从这里下载 openssl 软件>>。
将 zip 文件解压到任何目录,但最好选择一个您可以记住的目录用于未来的工作。
现在在命令提示符中输入以下命令:
引用keytool -exportcert -alias androiddebugkey -keystore C:\Users\Rupam\.android\debug.keystore | E:\openssl-0.9.8k_WIN32\bin\openssl
sha1 -binary | E:\openssl-0.9.8k_WIN32\bin\openssl base64
其中粗体部分是您的密钥库位置,如图 3.1所示,下划线部分 E:\openssl-... 是您刚下载的 openssl 的完整路径。输入并回车命令后,它会要求您输入密码。输入一个您可以记住的密码。这将在您签名应用以发布到 Google Play 时有所帮助。
生成密钥后,让我们直接进入在 Facebook 中创建和验证应用。
3.2 在 Facebook 中创建和验证应用
打开
https://developers.facebook.com/
在“应用”部分选择“创建新应用”。
图 3.4 选择在 Facebook 中创建新应用
选择 Android。
图 3.5 创建具有新应用 ID 的新 Android 应用
完成所有步骤。您将看到以下屏幕,其中包含将应用安装到模拟器以及将 SDK 导入您的应用的所有分步指南。
**从本页提到的链接下载 SDK。** Facebook 经常更改其 API、访问技术等。因此,本教程不提供任何 SDK 链接。下载最新版本总是明智的,该版本始终可以在此页面上找到。
图 3.6 在 Facebook 中创建新应用后的屏幕,指导用户进行后续操作
我建议您此时不要将 Facebook SDK 导入您的项目。我们只使用其中的一小部分,为此您不需要示例。但如果您想在 Facebook 应用开发方面有所成就,您可以随时将整个 SDK 导入您的 Eclipse 工作区并玩转示例。
向下滚动此页面,您将看到该应用正在询问您的 Android 应用包名和活动名。按照下图所示填写。
图 3.7:在 Facebook 应用中填写 Android 项目详细信息
现在,通过图 3.3获得的密钥应提供给下一个屏幕,如下所示:
图 3.8:将 Eclipse 密钥输入 Facebook 应用
为发布版也提及相同的密钥哈希。然后点击下一步。这应该完成了 Facebook 集成所需的所有步骤。
3.3 将 Facebook SDK 集成到你的项目中
实际上有两种方法可以做到:使用 Facebook 建议的方法,即导入 SDK 然后使用示例等。还有一个简单的方法:下载 facebookIntegrationEssentials.zip。
解压缩文件夹。您可以看到其中的 src、libs、res 文件夹。将 src/com/facebook 文件夹上传到您 Eclipse 项目的 src 文件夹。将 libs 文件夹中的 jar 文件上传到您项目的 libs 文件夹,并将 res/drawable-xhdpi 文件上传到您项目的相应文件夹,如下图所示:
3.9 为 Facebook 集成做准备
一旦您成功完成这些步骤,您的项目应该看起来与下图类似:
图 3.10:Facebook SDK 集成后的项目视图
清理并构建您的项目,您就可以开始使用 Facebook 了。在下一节中,我们将介绍编码部分。
3.4 Facebook SDK 代码使用
当您进入 Facebook 开发者仪表板并选择您的应用时,您将看到应用 ID,如下所示:
图 3.11:从 Facebook 开发者仪表板看到的 App ID
与 Twitter 不同,我们不需要传递应用密钥来与 Facebook 交互。此 ID 将用于初始化一个 Facebook 类实例,该实例最终用于从 Facebook 发布或获取数据。
private Facebook facebook;
private static final String APP_ID = "YOUR_APP_ID_HERE";
private static final String[] PERMISSIONS = new String[] { "publish_stream","read_stream"};
现在 Facebook 应用需要在身份验证请求时提供权限列表。如果您想知道合适的请求是什么,哪些权限是您已获得的,以及您还可以寻求哪些其他权限,您可以打开 Facebook 的在线 Graph API 测试工具:
https://developers.facebook.com/tools/explorer/145634995501895/?method=GET&path=me%3Ffields%3Did%2Cname&version=v2.1
这是一个很棒的工具,不仅可以测试您的查询,还可以测试您的访问令牌、查询中的字段等。一旦您打开该工具,它就会自动为您获取一个访问令牌。您可以使用该令牌来构建可以放入代码中的查询。
图 3.12:使用 Facebook Graph API 工具资源管理器
在获得了基本知识后,让我们来完成身份验证的代码。
3.4.1 身份验证
请记住我们图 2.7中的内容:首先,应用会请求一个包含应用 ID 的请求令牌(此处不需要密钥)。Facebook 服务器在验证令牌后将响应一个访问令牌。接收访问令牌会重启表单。因此,我们需要方法来存储令牌。我们可以使用共享首选项来存储令牌。在触发登录之前,我们可以检查是否存在访问令牌,如果存在,则检查其过期时间,然后打开身份验证对话框。在本教程中,我绕过了此逻辑,以便在点击登录按钮时始终打开身份验证对话框!
public boolean saveCredentials(Facebook facebook) {
Editor editor = getApplicationContext().getSharedPreferences(KEY,
Context.MODE_PRIVATE).edit();
editor.putString(TOKEN, facebook.getAccessToken());
editor.putLong(EXPIRES, facebook.getAccessExpires());
return editor.commit();
}
public boolean restoreCredentials(Facebook facebook) {
SharedPreferences sharedPreferences = getApplicationContext()
.getSharedPreferences(KEY, Context.MODE_PRIVATE);
facebook.setAccessToken(sharedPreferences.getString(TOKEN, null));
facebook.setAccessExpires(sharedPreferences.getLong(EXPIRES, 0));
return facebook.isSessionValid();
}
最后,登录方法如下:
public void LoginToFacebook()
{
facebook.authorize(this, PERMISSIONS, Facebook.FORCE_DIALOG_AUTH,new LoginDialogListener());
}
可以看到,我们传递了一个 `LoginDialogListener` 类的实例,该类是 `MainActivity` 的内部类,它定义了身份验证过程完成后要执行的操作。
最后,我们从 `onClick` 调用此方法以通过 Facebook 验证用户登录。
3.4.2 发布到动态
您可以将消息、照片等发布到您的动态。
public void postToWall(String msg) {
Log.d("Tests", "Testing graph API wall post");
try {
String response = facebook.request("me");
Bundle parameters = new Bundle();
parameters.putString("message", msg);
parameters.putString("description", "test test test");
response = facebook.request("me/feed", parameters,
"POST");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")|| response.contains("error")) {
Log.v("Error", response.toString());
}
} catch(Exception e) {
e.printStackTrace();
}
}
在查询中使用 **/me/feed** 可以发布到您的动态。您还需要将消息作为额外的参数传递。默认情况下,请求类型为“Get”。但在发布时,必须明确指定为“Post”。您也可以从 Facebook Graph API 工具资源管理器测试该查询。
如果一切顺利,您将看到您的应用成功进行了身份验证和发布。
图 3.13:Facebook 动态中的身份验证和发布
3.4.3 从 Facebook 获取信息
图 3.12 清楚地表明,查询结果始终是一个 JSON 对象。因此,您可以使用 JSON 解析响应来获取信息。我提供了一些实用方法,这些方法将有助于您基本了解查询结构。
public void fetchFacebookFriends()
{
try {
String response = facebook.request("me");
response = facebook.request("me/friends");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")|| response.contains("error")) {
Log.v("Error", response.toString());
}
else
{
JSONObject jsonObject = new JSONObject(response);
try {
JSONArray array = jsonObject.getJSONArray("data");
for (int i = 0; i < array.length(); i++) {
JSONObject object = (JSONObject) array.get(i);
Log.d( "id = "+object.get("id"),"Name = "+object.get("name"));
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}catch(Exception ex1)
{
}
}
public void fetchMyFacebookStatuses()
{
try {
String response = facebook.request("me");
response = facebook.request("me/statuses");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")) {
Log.v("Error", response.toString());
}
else
{
JSONObject jsonObject = new JSONObject(response);
try {
JSONArray array = jsonObject.getJSONArray("data");
for (int i = 0; i < array.length(); i++) {
JSONObject object = (JSONObject) array.get(i);
Log.d( "Message id = "+object.get("id"),"Message = "+object.get("message"));
}
}
catch (Exception e)
{
Log.i("Error in Statuses:",e.getMessage());
}
}
}catch(Exception ex1)
{
Log.i("Error in Statuses:",ex1.getMessage());
}
}
您可以首先在 Graph API 资源管理器中测试您的查询,以设计要作为 JSON 对象标识符传递的字段。另一方面,您也可以使用断点和调试选项来跟踪字段,如下图所示:
图 3.14:字符串响应和 JSON 对象解析
图 3.15 获取用户状态更新
您可以直接使用示例项目并开始集成。
所有获取和发布方法都可以在 `LoginDialogListener` 中进行测试,它是 `MainActivity` 的内部类。在身份验证任务成功完成后,您可以调用这些方法进行测试。此外,您可以根据您的逻辑在代码中使用它们。
class LoginDialogListener implements DialogListener {
public void onComplete(Bundle values) {
saveCredentials(facebook);
showToast( "Login Successfull in Facebook");
//fetchFacebookFriends();
//postToWall("Another post from Eclipse...");
fetchMyFacebookStatuses();
//fetchFriendsFacebookStatuses();
}
`showToast` 是一个创建简单 Toast 的方法,Toast 只是一个弹出对话框,会在几秒钟后消失。这是一种向用户传达消息的简洁方式。
private void showToast(String message)
{
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT)
.show();
}
下载 Testing-Facebook-Integration-App.zip 并测试这些方法。
4. 快速解决方案:使用 Android 的 Intent
这是跨不同平台(包括 Twitter、Facebook、LinkedIn、Gmail、蓝牙等)共享数据的最简单、最有效的方法。此方法既不需要通过网站进行应用身份验证,也不需要任何其他外部库或 JSON。**但是请注意,这仅适用于共享数据,无法使用此方法获取数据。**
因此,如果您的应用唯一的功能是共享数据(文本、图像),那么就使用此方法。我们将提供两个菜单选项:一个用于浏览图像,另一个用于使用 Android 的 Intent 进行共享。
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menuBrowse"
android:title="Browse Photos" />
<item android:id="@+id/menuShare"
android:title="Share"
android:actionProviderClass=
"android.widget.ShareActionProvider"/>
</menu>
相应地,我们需要在 MainActivity 中编写方法来处理新修改的菜单。
正如您所见,我们添加了一个名为“共享”的新菜单项,其中使用了 `ShareActionProvider` 小部件。因此,每当单击此项时,在进入常规菜单处理部分后,都会出现一个该小部件。
现在我们需要处理的不仅是我们主菜单,还要初始化 `ShareActionProvider` 实例并将其关联到菜单选项项。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
//getMenuInflater().inflate(R.menu.share_menu, menu);
MenuItem item = menu.findItem(R.id.menuShare);
ShareActionProvider myShareActionProvider = (ShareActionProvider) item.getActionProvider();
return super.onCreateOptionsMenu(menu);
}
如果用户选择浏览选项,我们将提供文件选择器 Intent,并收集所选文件的 Uri。
当用户选择“共享”按钮时,我们将首先通过查询 Media content provider 将文件 Uri 转换为绝对路径。将从文件路径创建一个位图图像,并加载到图像视图中。
Uri fileUri=null;
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
Intent myIntent;
switch (item.getItemId())
{
case R.id.menuShare:
try{
Log.d("Ok this is pressed","In the share menu");
myIntent = new Intent(Intent.ACTION_SEND);
myIntent.setType("image/jpeg");
try{
myIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
}catch(Exception ex)
{
}
myIntent.putExtra(Intent.EXTRA_SUBJECT, "Sharing Example: Codeproject Tutorial");
myIntent.putExtra(Intent.EXTRA_TEXT, "Shared SocialIntegration app written by Rupam Das");
startActivity(Intent.createChooser(myIntent, "Share Image"));
}catch(Exception ex)
{
}
break;
case R.id.menuBrowse:
try{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"),1);
}catch(Exception ex)
{
}
break;
}
return true;
}
仔细观察 `menuShare` 部分。观察 `ACTION.SEND` Intent 的使用。您可以直接将 `fileUri` 传递给 `EXTRA_STREAM` 字段。您可以使用 `putExtra` 方法添加更多信息。
获取绝对路径仅用于在我们的图像视图中显示所选图像。
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
//This method was deprecated in API level 11
//Cursor cursor = managedQuery(contentUri, proj, null, null, null);
CursorLoader cursorLoader = new CursorLoader(
this,
contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
int column_index =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
最后,这是输出:
图 4.1:通过 Intent 共享的结果
当您选择一个选项时,主题和描述字段将得到很好的对齐。
图 4.2:选择共享选项后的数据
请注意,此选项显示的是设备上安装的共享选项。例如,我的设备上未安装 Facebook 应用。因此,它不显示 Facebook 选项。如果您安装了 Facebook、LinkedIn,所有这些选项都会出现在共享 Intent 视图中。