salesforce
在本文中,我们将探索构建一个简单的本机Android应用程序,该应用程序利用Salesforce平台内的Chatter REST API 。 为此,我们将使用Salesforce Mobile SDK 2.1 (充当低级HTTP函数的包装器),使我们能够轻松处理OAuth和后续的REST API调用。 SDK中提供的TemplateApp作为基础确实是您最干净的起点。 我的教程本质上使用了TemplateApp的结构,并通过从REST Explorer示例应用程序中借用和修改在此基础上进行构建; 这有助于确保事情尽可能简单。 我们不会涉及构建此应用程序的各个方面,而是涵盖了要点,为读者提供了一个很好的起点,并尝试扩展salesforce.com文档。 本教程试图对那些不太熟悉该平台的开发人员起到一定的帮助作用,因为他们可能以更熟悉的方式使用该API。 我们将介绍的许多内容将补充《 Salesforce Mobile SDK开发人员指南》 ; 在本教程中,我将参考该文档中的相关页码,而不是在此处完整地复制该信息。
设定
我在本教程中使用IntelliJ IDEA ,这是Android Studio所基于的IDE。 如果您已经在使用Android Studio,那么在进行过程中工作流程将不会有明显的不同; Eclipse用户很好。 设置好IDE后,我们就可以安装Salesforce Mobile SDK 2.1(请参阅上面段落中的链接)。 Salesforce.com建议使用节点包管理器进行基于Node.js的安装。 我们将走一条替代路线; 取而代之的是,我们将从Github克隆存储库[页16]。
完成基本环境设置后,请转到https://developer.salesforce.com/signup ,并注册您的Developer Edition(DE)帐户。 就本示例而言,即使您已经有一个帐户,我也建议注册一个Developer Edition。 这样可确保您在启用了最新功能的情况下获得干净的环境。 然后,导航到http://login.salesforce.com以登录到您的开发人员帐户。
完成注册后,请按照《 Mobile SDK指南》中的说明创建连接的应用程序[页13]。 就本教程而言,您只需要填写必填字段。
为OAuth提供的回调URL不一定是有效的URL。 它只需要匹配应用程序在此字段中的期望即可。 您可以使用任何自定义前缀,例如sfdc://。
重要说明:对于本机应用程序,您必须在所选的OAuth范围中放置“随时代表您执行请求(refresh_token)” ,否则服务器将拒绝您,没有人会喜欢拒绝。 关于这一点,《 Mobile SDK指南》有所介绍,有关更多详细信息,请参见:[ http://github.com/forcedotcom/SalesforceMobileSDK-iOS/issues/211#issuecomment-23953366 ]
完成后,应该显示一个页面,其中包含您的使用者密钥和秘密。
现在,我们已经在服务器端进行了处理,现在让我们将重点转移到设置电话应用程序上。
首先,我们将在IntelliJ中启动一个新项目。 确保选择应用程序模块而不是Gradle:Android应用程序模块,因为项目的结构方式在Gradle构建系统中不能很好地发挥作用。
随意命名,请确保取消选中创建“ Hello World!”框。 活动,因为我们不需要它。 创建项目后,转到文件->导入模块...
导航到克隆Mobile SDK存储库的目录,展开本机目录,您应该看到一个名为“ SalesforceSDK”的项目,该项目旁边带有IntelliJ徽标。
选择它,然后单击确定。 在下一个屏幕上,确保选择了从外部模型导入的选项,并且Eclipse列表项突出显示。 单击下一步,然后在以下屏幕上再次单击下一步,而不进行任何更改。 到达最后一个屏幕时,选中SalesforceSDK旁边的框,然后单击“完成”。 IntelliJ现在将作为项目将Eclipse项目(Salesforce SDK)导入您的项目中。
现在,您可以命令Salesforce Mobile SDK。 转到“文件”->“项目结构... ”,在“项目设置”下选择“ Facets”,然后选择在括号中带有Salesforce SDK的项目。 确保已选中[库模块]框[IMG]。 现在,选择另一个,然后选择“打包”选项卡,并确保选中“启用清单合并”框。
接下来,从“项目设置”列表中选择“模块”,然后选择SalesforceSDK模块。 在“依赖项”选项卡下,应该有一个带有红色文本的项目。 右键单击并将其删除。 从那里,单击<您的模块名称>; 在“依赖关系”选项卡下,单击绿色的“ +”,选择“模块依赖关系...”,Salesforce SDK应该是您唯一的选择,单击“确定”。 现在,在“项目结构”窗口中选择“应用”,然后单击“确定”。
拨打电话
在res / values /中创建一个名为bootconfig.xml的文件; 该文件的内容应如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="remoteAccessConsumerKey"> YOUR CONSUMER KEY </string>
<string name="oauthRedirectURI"> YOUR REDIRECT URI </string>
<string-array name="oauthScopes">
<item>chatter_api</item>
</string-array>
<string name="androidPushNotificationClientId"></string>
</resources>
还记得我们之前创建的连接的应用程序吗? 在这里,您将找到使用者密钥并重定向(回调)uri。
出于好奇,尽管事实上我们在OAuth Scopes服务器端指定了refresh_token ,但我们无需在此处定义它。 其背后的原因是,从本地应用程序访问平台始终需要此范围,因此Mobile SDK自动包含它。
接下来,确保您的String.xml文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="account_type">com.salesforce.samples.templateapp.login</string>
<string name="app_name"><b>Template</b></string>
<string name="app_package">com.salesforce.samples.templateapp</string>
<string name="api_version">v30.0</string>
</resources>
上述值应该是您的应用唯一的。
现在创建另一个名为KeyImpl的类。
public class KeyImpl implements KeyInterface {
@Override
public String getKey(String name) {
return Encryptor.hash(name + "12s9adpahk;n12-97sdainkasd=012", name + "12kl0dsakj4-cxh1qewkjasdol8");
}
}
完成此操作后,请使用扩展了SalesforceActivity的相应布局创建任意活动,并按如下所示进行填充:
public class TutorialApp extends Application {
@Override
public void onCreate() {
super.onCreate();
SalesforceSDKManager.initNative(getApplicationContext(), new KeyImpl(), TutorialActivity.class);
/*
* Un-comment the line below to enable push notifications in this app.
* Replace 'pnInterface' with your implementation of 'PushNotificationInterface'.
* Add your Google package ID in 'bootonfig.xml', as the value
* for the key 'androidPushNotificationClientId'.
*/
// SalesforceSDKManager.getInstance().setPushNotificationReceiver(pnInterface);
}
}
这是我们初始化SalesforceSDKManager的应用程序入口点。
从《 Salesforce Mobile SDK开发人员指南》中:
“顶级SalesforceSDKManager类为使用密码的应用程序实现密码功能,并为不使用密码的应用程序填充空白。 它还设置了登录阶段,在注销后进行清理,并提供了一个特殊的事件监视程序,该事件监视程序会在删除系统级帐户时通知您的应用程序。 OAuth协议是使用内部类自动处理的。”
对于本教程,我们的对应布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#454545"
android:id="@+id/root">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/data_display"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fetch Data"
android:id="@+id/button"
android:layout_gravity="bottom"
android:onClick="onFetchClick"/>
</LinearLayout>
正如您在上面看到的,出于本教程的目的,我们将事情变得非常简单。 一个进行呼叫的按钮和一个显示它的文本框。
在介绍实现细节之前,我想提到清单文件的关键点。
由于我们有新的应用程序入口点(在我们的案例TutorialApp中) ,我们需要通过在清单中定义它来让系统知道。
如果错过此步骤,则应用程序将因运行时错误而崩溃,并抱怨您未对SalesforceSDKManager.init()进行适当的调用
完成此操作后,您的应用程序应该可以正常运行
现在,我们将编写函数以发出实际的请求。 以下方法将进入上面创建的活动中。
private void sendRequest(RestRequest restRequest) {
client.sendAsync(restRequest, new RestClient.AsyncRequestCallback() {
@Override
public void onSuccess(RestRequest request, RestResponse result) {
try {
//Do something with JSON result.
println(result); //Use our helper function, to print our JSON response.
} catch (Exception e) {
e.printStackTrace();
}
EventsObservable.get().notifyEvent(EventsObservable.EventType.RenditionComplete);
}
@Override
public void onError(Exception e) {
e.printStackTrace();
EventsObservable.get().notifyEvent(EventsObservable.EventType.RenditionComplete);
}
});
}
上面的代码将执行我们传递给它的RestRequest对象,并异步返回结果。
让我们构造一个RestRequest对象供客户端执行:
首先,我们需要一些辅助方法来帮助构造HttpEntities
private Map<String, Object> parseFieldMap(String jsonText) {
String fieldsString = jsonText;
if (fieldsString.length() == 0) {
return null;
}
try {
JSONObject fieldsJson = new JSONObject(fieldsString);
Map<String, Object> fields = new HashMap<String, Object>();
JSONArray names = fieldsJson.names();
for (int i = 0; i < names.length(); i++) {
String name = (String) names.get(i);
fields.put(name, fieldsJson.get(name));
}
return fields;
} catch (Exception e) {
Log.e("ERROR", "Could not build request");
e.printStackTrace();
return null;
}
}
private HttpEntity getParamsEntity(String requestParamsText)
throws UnsupportedEncodingException {
Map<String, Object> params = parseFieldMap(requestParamsText);
if (params == null) {
params = new HashMap<String, Object>();
}
List<NameValuePair> paramsList = new ArrayList<NameValuePair>();
for (Map.Entry<String, Object> param : params.entrySet()) {
paramsList.add(new BasicNameValuePair(param.getKey(),
(String) param.getValue()));
}
return new UrlEncodedFormEntity(paramsList);
}
接下来,我们定义将生成所需的RestRequest对象的方法。
private RestRequest generateRequest(String httpMethod, String resource, String jsonPayloadString) {
RestRequest request = null;
if (jsonPayloadString == null) {
jsonPayloadString = "";
}
String url = String.format("/services/data/%s/" + resource, getString(R.string.api_version)); // The IDE might highlight this line as having an error. This is a bug, the code will compile just fine.
try {
HttpEntity paramsEntity = getParamsEntity(jsonPayloadString);
RestRequest.RestMethod method = RestRequest.RestMethod.valueOf(httpMethod.toUpperCase());
request = new RestRequest(method, url, paramsEntity);
return request;
} catch (UnsupportedEncodingException e) {
Log.e("ERROR", "Could not build request");
e.printStackTrace();
}
return request;
}
最后,打印我们结果的辅助方法。 这不是严格必要的,但包含在此处用于
/**
* Helper method to print object in the result_text field
*
* @param object
*/
private void println(Object object) {
if (resultText == null)
return;
StringBuffer sb = new StringBuffer(resultText.getText());
String text;
if (object == null) {
text = "null";
} else {
text = object.toString();
}
sb.append(text).append("\n");
resultText.setText(sb);
}
用法:
还记得我们之前在布局中创建的那个按钮吗? 现在我们要赋予它生命。
public void onFetchClick(View view) {
RestRequest feedRequest = generateRequest("GET", "chatter/feeds/news/me/feed-items", null);
sendRequest(feedRequest);
}
现在,运行您的应用程序,如果一切顺利,系统将要求您输入Salesforce凭据。 然后将要求您授权刚刚创建的应用程序; 点击允许,然后您将看到您的应用。
当您按下按钮时,它应该将请求中的所有JSON数据转储到文本字段中。 它不是很漂亮,但是可以完成工作并说明概念。
现在,您可以获取此数据,将其绑定到ListView或用于发出其他请求,例如“ like”或“ comment”。
这是一个可以正常运行的示例应用程序,以供参考:
注意:
我建议使用库来解析JSON,例如Gson或Jackson。 为了理解和连续性,我们这里没有这样做,因为它与您在Salesforce文档和示例中看到的所有内容都更加接近。
资源资源
请参阅这些文档,以了解您可以做的很多事情。
玩得开心!
翻译自: https://www.javacodegeeks.com/2014/06/interfacing-salesforce-with-android.html
salesforce