我正在制作一个简单的 Android Wear 应用来控制我的恒温器,我正在使用 Volley 发送 POST 请求来控制它们。在 Android Wear 模拟器中一切都运行良好(请求有效),但是,当应用程序在我的 Moto 360 上加载时,调用了截击请求但总是超时。
为什么我的 volley 请求在我的 watch 上失败了但在模拟器上工作?其他应用在我的 watch 上请求成功(例如,内置的天气应用可以在大约 3 秒内加载天气数据)。而且,最奇怪的部分是:我的 watch 上的应用工作(成功发出截击请求),大约一天后,我从 Android Studio 将它安装到我的 watch 上,它突然停止加载数据没有明显的原因。
到目前为止我尝试了什么:
manifest.xml 中请求互联网许可。这是我的代码(来 self 的主视图的适配器):
public void refreshThermostatsRecyclerView(RequestQueue queue) {
String url = "https://mobile.skyport.io:9090/login"; // login call to the thermostats server Skyport
Log.w("myApp", "Starting /login call to Skyport"); // this gets called on simulator and watch
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the response string.
Log.w("myApp", "Response is: " + response); // this gets called on the simulator but not the watch
try {
// there's some code to parse the data.
} catch (JSONException e) {
Log.w("myApp", "catching an error parsing the json."); // never gets called.
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.w("myApp", "Skyport request didn't work! " + error); // this always gets called on the watch, with the error being a timeout error (com.Android.Volley.timeouterror) but never gets called in the simulator
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> m = new HashMap<>();
m.put("Referer", "app:/VenstarCloud.swf");
// here I put some more headers
return m;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> m = new HashMap<>();
m.put("version", "3.0.5");
m.put("email", userEmail);
m.put("password", userToken);
return m;
}
};
// Add the request to the RequestQueue.
int socketTimeout1 = 30000; // times out 30 seconds after the request starts on the watch
RetryPolicy policy1 = new DefaultRetryPolicy(socketTimeout1, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy1);
queue.add(stringRequest);
}
使用以下代码从我的主 Activity 中的 onCreate() 方法调用:
RequestQueue queue = Volley.newRequestQueue(this);
refreshThermostatsRecyclerView(queue);
如果您想在模拟器和 watch 上查看通过运行此命令创建的日志,它们是 on Google Drive here .
编辑 1: 重启我的 watch 可以暂时解决问题并允许 watch 再次发出 HTTP 请求,但是一旦 watch 与蓝牙断开连接、连接到 WiFi、与 WiFi 断开连接,它就会再次中断,并重新连接到蓝牙(因此每次我不带手机穿过我的公寓然后返回时它都会中断)。
编辑 2: 我将 volley 请求全部切换到异步线程中的 HTTPURLConnection 请求,出现与 volley 相同的问题。
tl;dr: 我的应用程序的 Volley 请求在模拟器中有效,但在我的 Android Wear watch 上不再有效(尽管从 Play 商店下载的应用程序的类似请求有效),我怎样才能获得 Volley请求在 watch 上再次处理我的应用程序?
最佳答案
根据下面这两个对话,WiFi 连接似乎只允许 Android Wear 通过 WiFi 连接到手机,而不是直接连接到互联网。但是,Android Wear 2.0 允许您使用常规网络 API。
Direct internet connection on Android Wear?
Does Android Wear support direct access to the Internet?
因此,对于 Android Wear 2.0+,来自可穿戴应用的 Volley 请求应该可以工作。
如果你想使用 Android Wear <>
在 Wearable 上,在 onCreate() 中添加一个键,指示手机是否应开始收集数据。
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/shouldStart");
putDataMapReq.getDataMap().putBoolean(SHOULD_START_KEY, true);
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
PendingResult pendingResult = Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
在手机上,在 onDataChanged 中,检查可穿戴设备是否要开始收集数据。如果是,则启动Volley请求。
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo("/shouldStart") == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
boolean shouldStart = dataMap.getBoolean(SHOULD_START_KEY));
if(shouldStart) {
Volley.newRequestQueue(this).add(request);
}
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
然后,您的 Volley 请求的 onResponse 应该将数据传回 Wearable。
public void onResponse(String response) {
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/data");
putDataMapReq.getDataMap().putString(DATA_KEY, true);
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
PendingResult pendingResult = Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
}
最后,您可以使用 onDataChanged 访问您的 Wearable 中的数据并将其存储在您的模型中以将其传递给适配器:
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo("/data") == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
parseAndpassToAdapter(dataMap.getString(DATA_KEY));
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
您需要 Wearable.API 来实现它,并且您的类应该实现 DataApi.DataListener。有关入门的更多信息,请参阅 Accessing the Wearable Data Layer和 Syncing Data Items
希望这对您有所帮助。
关于java - Android HTTP 请求在模拟器中工作但不在磨损设备上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41770992/
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/