- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个应用程序,该应用程序应该从我的Thingspeak channel 接收数据。
首先,我只是使用了webview小部件,但我想走得更远,并使用Thingspeak Java api自己处理数据。
在MainActivity中,我只是输入以下代码:
Channel channel = new Channel(1234,"writeKey");
try {
Entry entry = channel.getLastChannelEntry();
} catch (UnirestException e) {
e.printStackTrace();
} catch (ThingSpeakException e) {
e.printStackTrace();
}
out.println("entry");
java.lang.RuntimeException: Unable to start activity ComponentInfo{de.babytemp.babytempapp2/de.babytemp.babytempapp2.MainActivity}: java.lang.IllegalArgumentException: Unknown pattern character 'X'
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.IllegalArgumentException: Unknown pattern character 'X'
at java.text.SimpleDateFormat.validatePatternCharacter(SimpleDateFormat.java:314)
at java.text.SimpleDateFormat.validatePattern(SimpleDateFormat.java:303)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:356)
at com.google.gson.DefaultDateTypeAdapter.<init>(DefaultDateTypeAdapter.java:49)
at com.google.gson.GsonBuilder.addTypeAdaptersForDate(GsonBuilder.java:555)
at com.google.gson.GsonBuilder.create(GsonBuilder.java:543)
at de.babytemp.babytempapp2.Channel.<init>(Channel.java:46)
at de.babytemp.babytempapp2.MainActivity.onCreate(MainActivity.java:41)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
最佳答案
package de.babytemp.babytempapp2;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.GetRequest;
import java.util.HashMap;
public class Channel {
private String APIURL = "http://api.thingspeak.com";
private static final String APIHEADER = "XXXXXXXXX";
private final Integer channelId;
private String readAPIKey;
private String writeAPIKey;
private final Boolean isPublic;
private final HashMap<String, Object> fields = new HashMap<>();
private final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create();
/**
* Constructor for a public, read-only, Thingspeak channel. This type of
* channel cannot be updated.
*
* @param channelId Channel Id.
*/
public Channel(Integer channelId) {
this.isPublic = true;
this.channelId = channelId;
}
/**
* Constructor for a public, writeable, Thingspeak channel.
*
* @param channelId Channel Id.
* @param writeKey API Key for the channel. See
* https://thingspeak.com/channels/<channelId>#apikeys
*/
public Channel(Integer channelId, String writeKey) {
this.isPublic = true;
this.channelId = channelId;
this.writeAPIKey = writeKey;
}
/**
* Constructor for a private, writeable, Thingspeak channel.
*
* @param channelId Channel Id.
* @param writeKey Write API Key. See
* https://thingspeak.com/channels/<channelId>#apikeys.
* @param readKey Read API Key. See
* https://thingspeak.com/channels/<channelId>#apikeys.
*/
public Channel(Integer channelId, String writeKey, String readKey) {
this.channelId = channelId;
this.readAPIKey = readKey;
this.writeAPIKey = writeKey;
this.isPublic = false;
}
/**
* Make GET requests to the Thingspeak API without additional feed
* parameters.
*
* @param url The API url.
* @return JSON string.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
private String thingRequest(String url) throws UnirestException, ThingSpeakException {
GetRequest request = Unirest.get(url);
if (!this.isPublic) {
request.field("key", this.readAPIKey);
}
HttpResponse<JsonNode> response = request.asJson();
if (response.getCode() != 200) {
throw new ThingSpeakException("Request failed with code " + response.getCode());
}
return response.getBody().toString();
}
/**
* Make GET requests to the Thingspeak API with additional feed parameters.
*
* @param url The API url.
* @param options Optional feed parameters.
* @return JSON string.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
private String thingRequest(String url, FeedParameters options) throws UnirestException, ThingSpeakException {
GetRequest request = Unirest.get(url);
if (!this.isPublic) {
request.field("key", this.readAPIKey);
}
request.fields(options.fields);
HttpResponse<JsonNode> response = request.asJson();
if (response.getCode() != 200) {
throw new ThingSpeakException("Request failed with code " + response.getCode());
}
return response.getBody().toString();
}
/**
* Use a server other than thingspeak.com. If you are hosting your own
* Thingspeak server, set the url of the server here. The url of the public
* Thingspeak server is http://api.thingspeak.com
*
* @param url eg. http://localhost, http://thingspeak.local:3000, etc.
*/
public void setUrl(String url) {
this.APIURL = url;
}
/**
* Update channel with new data.
*
* @param entry The new data to be posted.
* @return The id of the new entry.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Integer update(Entry entry) throws UnirestException, ThingSpeakException {
HttpResponse<String> response = Unirest.post(APIURL + "/update")
.header(APIHEADER, this.writeAPIKey)
.header("Connection", "close")
.fields(entry.getUpdateMap())
.asString();
if (response.getCode() != 200) {
throw new ThingSpeakException("Request failed with code " + response.getCode());
} else if (response.getBody().equals("0")) {
throw new ThingSpeakException("Update failed.");
}
return Integer.parseInt(response.getBody());
}
/**
* Get a channel feed with default feed options. Does not include location or status info. Only fields that
* have been named in the channel's settings (via the web) will be returned.
*
* @return Feed for this channel.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Feed getChannelFeed() throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/feed.json";
return gson.fromJson(thingRequest(url), Feed.class);
}
/**
* Get a channel feed with additional feed options. Only fields that have been named in
* the channel's settings (via the web) will be returned.
*
* @param options Additional feed parameters.
* @return Feed for this channel.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Feed getChannelFeed(FeedParameters options) throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/feed.json";
return gson.fromJson(thingRequest(url, options), Feed.class);
}
/**
* Get last entry in this channel with default feed options. This is a
* faster alternative to getting a Channel Feed and then calling
* {@link Feed#getChannelLastEntry()}.
*
* @return Entry.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Entry getLastChannelEntry() throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/feed/last.json";
return gson.fromJson(thingRequest(url), Entry.class);
}
/**
* Get last entry in this channel with additional feed options. This is a
* faster alternative to getting a Channel Feed and then calling
* {@link Feed#getChannelLastEntry()}
*
* @param options
* @return Entry.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Entry getLastChannelEntry(FeedParameters options) throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/feed/last.json";
return gson.fromJson(thingRequest(url, options), Entry.class);
}
/**
* Get a field feed with default feed options.
*
* @param fieldId The field to include in the field (1-8).
* @return Feed.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Feed getFieldFeed(Integer fieldId) throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/field/" + fieldId + ".json";
return gson.fromJson(thingRequest(url), Feed.class);
}
/**
* Get a field feed with additional feed options.
*
* @param fieldId The field to include in the field (1-8).
* @param options Optional parameters that control the format of the feed.
* @return Feed.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Feed getFieldFeed(Integer fieldId, FeedParameters options) throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/field/" + fieldId + ".json";
return gson.fromJson(thingRequest(url, options), Feed.class);
}
/**
* Get the last entry in a field feed with default feed options.
*
* @param fieldId The field to return (0-8).
* @return Last entry for the specified field.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Entry getLastFieldEntry(Integer fieldId) throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/field/" + fieldId + "/last.json";
return gson.fromJson(thingRequest(url), Entry.class);
}
/**
* Get the last entry in a field feed with additional feed options.
*
* @param fieldId The field to return (0-8).
* @param options Supported options: offset, status, and location.
* @return Last entry for the specified field.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Entry getLastFieldEntry(Integer fieldId, FeedParameters options) throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/field/" + fieldId + "/last.json";
return gson.fromJson(thingRequest(url, options), Entry.class);
}
/**
* Get channel status updates. Uses the default feed options.
*
* @return Status feed.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Feed getStatusFeed() throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/status.json";
return gson.fromJson(thingRequest(url), Feed.class);
}
/**
* Get channel status updates.
*
* @param options Only {@link FeedParameters#offset(java.lang.Integer)} is
* supported.
* @return Status feed.
* @throws UnirestException The request cannot be made.
* @throws ThingSpeakException The request is invalid.
*/
public Feed getStatusFeed(FeedParameters options) throws UnirestException, ThingSpeakException {
String url = APIURL + "/channels/" + this.channelId + "/status.json";
return gson.fromJson(thingRequest(url, options), Feed.class);
}
关于java - Android应用-无法启动 Activity ComponentInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34826242/
我对 Android 很陌生,如果问题重复,请避免并发送链接。有三个 Activity A、B 和 C。 Activity A 获取一个用户名,我想在 Activity C 中显示该用户名,但我想先运
我正在尝试制作记事本应用程序,因此每次打开新笔记时,布局都会相同。另外, Activity 的数量(新注释)不应定义得尽可能多 最佳答案 如果 Activity 始终相同,您可能应该创建一个适配器,允
我有 3 个 Activity 。 主窗口 5 个按钮 在按钮的主窗口中按下此窗口打开(将其称为父窗口) 在父窗口按钮上按下此窗口打开调用它作为结束子窗口。 现在从子窗口我从父窗口获取值如下:
我遇到了一个 Activity backstack 问题。假设我的后台有 5 个 Activity :比如 Activity A、 Activity B、 Activity C、 Activity D
我正在寻找必须具有以下附加特征的 JMS 提供程序: 采用多代理,所有代理都必须处于事件状态(无单点故障) 仅在两台机器上进行扩展就足以满足我们的需求 能够保证订购(如果 1 个生产者 + 1 个消费
假设,我有一个由 TabHost 组成的选项卡 Activity 。 TabHost 包含 2 个选项卡,每两个选项卡都有一个 Activity 组。每个 Activity 组包含一项 Activit
我正在开发一个应用程序,我需要根据某些操作导航到特定 Activity 。这是一张图片 我的第一个 Activity 是 ReadingActivity。基于某些操作,用户将被带到 NewProjec
我创建了一个与服务器异步通信的应用程序。当应用程序发出服务器请求时,将创建一个带有“正在加载”通知的新对话框( Activity )。主要 Activity 实现了处理服务器响应的方法,我想在主要 A
我想在我的所有应用程序 Activity 中显示相同的选项菜单。我创建了一个实现菜单的通用 Activity ,并且我所有的进一步 Activity 都扩展了它。 问题:当我需要扩展其他特定 Acti
我有四个 Activity ,即 java 文件 - Activity1.java、activity2.java、activity3.java、activity4.java 和 xml 文件 - Ac
我有两个 Activity 。我想将数据从第二个 Activity 发送到上一个 Activity 。第一个 Activity 有自定义 ListView 和 bean 类。当我点击第二个 Activ
根 Activity 是堆栈中当前的第一个 Activity 还是 list 中指定为启动 Activity 的 Activity ? 支持应用程序 P 在启动时启动 Activity A。然后 A
你好 我想知道您在绘制 Activity 图选择“Activity ”时考虑了哪些关键点? 您如何从要建模的问题中选择 Activity ? 谢谢 最佳答案 Activity 图用于对正在开发的系统和
如何从主 Activity 启动 Activity 并在子 Activity 返回主 Activity 中退出操作后返回主 Activity ? 我已将子 Activity 作为启动器 Intent
我的工作流程如下: 登录 Activity -> ActivityB -> ActivityC -> ActivityD 我想将数据从LoginActivity传递到ActivityD,但不直接传递到
我之前曾尝试获得此问题的答案,但找不到可以解决我的问题的答案。我正在制作保存圆盘高尔夫球分数的应用程序。我的 MainActivity 有 4 个按钮。新比赛、恢复比赛、类(class)和球员。 At
我有一个 tts 非 UI 类和 Activity 类。现在在 Activity 类中,我有一个按钮,用户可以从中选择男声或女声,具体取决于我想要将字符串传递给 tts 类的选择,然后一次tts 类根
问题有点复杂,首先, Activity A 和 Activity B 的 list 中都有 android:noHistory = true 。我有一个自定义 serialized 类,假设 MyCl
在我的应用程序中,我有两个 Activity (AuthenticationActivity 和 MainActivity),每个 Activity 都有一个导航图和大量 fragment 。我创建了
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How can i use compose email activity in tabView? 我想在选项
我是一名优秀的程序员,十分优秀!