I'm building an Android wear app that uses HTTPUrlConnection() to gather some data from a webpage. This works all perfectly fine in the Emulator, but does not on a real device (Moto 360 i use for testing). I ran the server on both the local network and external network, but somehow the real device ends up with a Connection timeout. It's not the server either, as i tried different computers, different software, and different networks with different routers. The Android manifest seems also fine. Am i doing something wrong, or could this be a bug?
try {
// create the HttpURLConnection
HttpURLConnection connection;
connection = (HttpURLConnection) url.openConnection();
// just want to do an HTTP GET here
connection.setRequestMethod("GET");
// uncomment this if you want to write output to this url
//connection.setDoOutput(true);
// give it 15 seconds to respond
connection.setReadTimeout(15 * 1000);
connection.connect();
// read the output from the server
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
bodyHtml = stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
//throw e;
} finally {
// close the reader; this can throw an exception too, so
// wrap it in another try/catch block.
if (reader != null) {
try {
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vendor.atestapp" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.type.watch" />
<service android:name=".WearMessageListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Log output:
09-09 00:50:50.177 3664-8913/vendor.atestapp W/System.err﹕ java.net.ConnectException: failed to connect to /192.168.1.39 (port 8080): connect failed: ETIMEDOUT (Connection timed out)
09-09 00:50:50.177 3664-8913/vendor.atestapp W/System.err﹕ at libcore.io.IoBridge.connect(IoBridge.java:124)
09-09 00:50:50.177 3664-8913/vendor.atestapp W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
09-09 00:50:50.177 3664-8913/vendor.atestapp W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
09-09 00:50:50.177 3664-8913/vendor.atestapp W/System.err﹕ at java.net.Socket.connect(Socket.java:882)
Found the problem! HTTPUrlConnection doesn't work on Wear. Google disabled it, yet you can perfectly code it. Apparently this is some sort of policy by Google, yet they forgot to disable it in their emulator.
Alternative (this is how i do it now): Use HTTPUrlConnection on your phone, and use the MessageApi to communicate with your Wear device.
Android watch will not connect to the internet via the bluetooth connection to the phone, UrlHTTPConnection is disabled because it is not a Wear issue, as I will BUT it will connect when connected via WiFi.
Unfortunately, most devices pre mid-2015 don't support WiFi :-( More unfortunate, is that Android Wear App for handhelds won't bridge Bluetooth from the watch with the internet from the world.
UrlHTTPConnection is enabled because it is not a Wear issue. The guilty is the Wear-App on the handheld.
Obviously, it is not viable "for life" but for curiosity, if you connect your device via WiFi and disable Bluetooth on your phone (it always prefers BT for power considerations) it will miraculously begin to work.
Related
I want to have multiple hardware smartphones connected to Selenium Grid, as
Appium nodes (one appium server/device). I also want to only specify the
Selenium Grid Hub as the target in my Appium tests.
If I do this, Appium seems to require that I specify a "deviceName" or "udid" as a DesiredCapability. Specifying either of these means my test will only target a single specific device that is hard-coded into the test, instead of targeting any device that meets "platform".
How can I use Appium with Selenium Grid to just choose any device that meets DesiredCapabilities, instead of targeting a specific device with the (seemingly required) "udid" or "deviceName"?
As a use case, I have (1) iOS hardware device and (1) Android hardware device. I would like my AppiumDriver instantiation to only have a Desired Capability of that specifies Android or IOS and just return any device that meets those capabilities.
You can try running tests from testNG.xml and keep all the deviceName in testNG.xml, I've kept a if-else block for the apk path as I had two different machines.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Automation" parallel="tests">
<test name="Test1">
<parameter name="deviceName" value="XYZZZZZ" />
<classes>
<class name="poc.grid.GridTest" />
</classes>
</test>
<test name="Test2">
<parameter name="deviceName" value="ZYXXXXX" />
<classes>
<class name="poc.grid.GridTest" />
</classes>
</test>
</suite>
** And keep the test class like: **
public void appium_driver(String deviceName)
{
try
{
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", deviceName);
capabilities.setCapability("platformName", "Android");
if(deviceName.equalsIgnoreCase("XYZZZZZ")){
capabilities.setCapability("app", "/XXXXXX/chocolate.apk");
}else{
capabilities.setCapability("app", "/XXXXXX/chocolate.apk");
}
capabilities.setCapability("newCommandTimeout", "120");
WebDriver driver = new RemoteWebDriver(new URL("http://WHERE_HUB_RUNNNING_IP:4444/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
catch(Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
I also had issues with the udid capability. To me (as a appium beginner) it's just not clear enough which capability you can send to match and which one you can send to overwrite a setting. I know the defaultcapabilitymatcher only matches a few:
https://github.com/SeleniumHQ/selenium/blob/master/java/server/src/org/openqa/grid/internal/utils/DefaultCapabilityMatcher.java
However I needed to add the udid to the session creation to make it work for me in my setting. So maybe my findings are usefull for you as well. How to make sure the appium node is connected to only one phone?
is it possible to associate specific URL with Windows Phone 8.1 application?
When there is a request to open URL in format e.g. http://myservice.mydomain.com?Params... from e-mail or page in browser, my application will process an URL.
On Android it is possible in manifest with intent-filter for some activity:
...
<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:host="myservice.mydomain.com" android:scheme="http" />
</intent-filter>
...
Thanks.
You can make an URI association with a custom URI schema, like "myapp:"
Read more here: URI Associations
I am trying to setup OAUTH for my twitter related app .I am using a callback url which gets the access token inside my application .
However I am getting the following error :-
onReceivedError -2 http://www.someurl.com/auth/twitter/callback?&oauth_token=ajGYfwX5YauPcHnUIQCjFf1pFBGmhBEhAxFv8Ej6Ns&oauth_verifier=VBWZ5HaDMwGzrzbGOUlEQhUbZmKoLzWXVRqSxBUZI The URL could not be found.
My Browser shows page not responding .
My CallBack Url =http://www.someurl.com/auth/twitter/callback .
I am using onNewIntent for receving the intent from my browser .
public void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
System.out.println("Here ");
Uri uri = intent.getData();
String oauthToken = uri.getQueryParameter("oauth_token");
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
}
Manifest File :-
<activity android:name=".Testing" android:launchMode="singleTask">>
<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>
</activity>
The call back is a bit odd, it's actually in the format scheme://host.
So for your app, based on the manifest file, it would be "x-oauthflow-twitter://callback". This means that you'll have to specify that url as the callback url in your code too.
I have gotten the Push Demo from here to work in the simulators.
When I tried it on a blackberry device (BlackBerry Bold 9000) with the UrbanAirship Test Push messages, I was not able to receive any push notifications.
Things that I have done so far are:
* Changed the push port from 100 to 29580
* Added the application id as an attribute to the widget element in config.xml
* The application has been signed before uploaded to the phone.
* I'm assuming no errors in the code because both start/stop subscribe alert messages appear on app start/button click
* There is no indication of network activity when a test message has been sent by UrbanAirship.
My config.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:rim="http://www.blackberry.com/ns/widgets" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" id="{app_id}">
<name>Push Example</name>
<description>Samples of code</description>
<author href="http://www.rim.com/" rim:copyright="no copyright" email="webapi#rim.com">
Research in Motion - Web API Team
</author><content src="index.htm" />
<feature id="blackberry.system" required="true" version="1.0.0.0" />
<feature id="blackberry.app" required="true" version="1.0.0.0" />
<feature id="blackberry.invoke.JavaArguments" required="true" version="1.0.0.0" />
<feature id="blackberry.invoke.CalendarArguments" required="true" version="1.0.0.0" />
<feature id="blackberry.invoke" required="true" version="1.0.0.0" />
<feature id="blackberry.push" version="1.0.0"/>
<feature id="blackberry.identity" version="1.0.0"/>
<feature id="blackberry.utils" required="true" version="1.0.0.0" />
<rim:connection timeout="30000">
<id>MDS</id>
<id>BIS-B</id>
<id>TCP_WIFI</id>
<id>TCP_CELLULAR</id>
<id>WAP2</id>
<id>WAP</id>
</rim:connection>
<license href="http://www.license.com">This is a sample license</license>
</widget>
The action.js file looks like this:
//the port that the Push Listener will listen to on the MDS
//Open the rimpublic.property file, which is located in the MDS\config subdirectory
//of your BlackBerry Email and MDS Services Simulators installation directory.
//Ensure the "push.application.reliable.ports=100" line is NOT commented out.
var port = 29580;
function subscribe() {
//open the listener to listen if there is pushed data coming through
blackberry.push.openPushListener(handleReturnData, port);
try {
alert("push listening has started. push port = ("+port+") app id = (" + blackberry.app.id + ") pin = ("+blackberry.identity.PIN+")");
} catch (e) {
alert (e);
}
}
//handleReturnData - the function to call for the event of pushed data coming through
//port - the port to listen on
function handleReturnData(data) {
try {
if (data != null) {
var text = blackberry.utils.blobToString(data.payload);
alert("text recieved from push: " + text);
} else {
alert("No data from the push");
}
} catch (e) {
alert (e);
}
}
function unsubscribe() {
//stop listening for pushed data, a clean up step
blackberry.push.closePushListener(port);
alert("Push listening has stopped");
}
Finally, my index.html file looks like this:
<html>
<head>
<title>Push Example</title>
<script src="Scripts/action.js" type="text/javascript"></script>
<link href="Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
<body onload="javascript:subscribe();">
<button id="btnUnsubscribe" onclick="unsubscribe();">Unsubscribe</button>
</body>
</html>
Would anyone know what could be wrong with my code/configuration?
Cheers,
Stephen
I have this configuration in ibatis-config.xml
<configuration>
<properties resource="collector.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${dev.jdbc.driver}" />
<property name="url" value="${dev.jdbc.url}" />
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${test.jdbc.driver}" />
<property name="url" value="${test.jdbc.url}" />
</dataSource>
</environment>
</environments>
<mappers>
</mappers>
</configuration>
As shown it will load datasource from <environment id="development">
QUESTION: Is it possible at run time switch to use <environment id="test"> without modifying XML? For example - I have a test file where I'm using SqlSessionFactory and want to set it programmatically to use test environment?
SqlSessionFactoryBuilder.build() method can select a specific environment in XML.
For example,
private Reader reader;
private SqlSessionFactory sqlSessionFactorys;
private SqlSession session;
reader = Resources.getResourceAsReader("ibatis-config.xml");
sqlSessionFactorys = new SqlSessionFactoryBuilder().build(reader, "test");
testSession = sqlSessionFactorys.openSession(); // test env
sqlSessionFactorys = new SqlSessionFactoryBuilder().build(reader, "development");
devSession = sqlSessionFactorys.openSession(); // dev env
According to this site:
http://codenav.org/code.html?project=/org/mybatis/mybatis/3.2.5&path=/Source%20Packages/org.apache.ibatis.session/SqlSessionFactoryBuilder.java
The build() method closes the reader/inputstream before returning SqlSessionFactory now. So you will need to open a new reader/stream in order to load the second session. I discovered this when I separated out my account/security tables to a separate database from the main application DB. My first go around I kept getting errors when the bean was trying to load the session factory due to an input stream error (closed).
e.g.
try {
inputStream = Resources.getResourceAsStream(MYBATIS_CONFIG_PATH);
prodDbSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, prodDbEnvironment);
inputStream = Resources.getResourceAsStream(MYBATIS_CONFIG_PATH);
securityDbSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, securityDbEnvironment);
} catch (IOException ex) {
String msg = "Unable to get SqlSessionFactory";
CustomizedLogger.LOG(Level.SEVERE, this.getClass().getCanonicalName(), "methodName", msg, ex);
}
Although I put them in separate try catch blocks so that I know which one failed specifically right away in the log file.
I also implement this as a singleton so that it only has to load load resources once.
Context: I run this in a Java EE container and use MyBatis for straight forward queries and for where I would use native queries since it is a much simpler and straight forward framework. I might switch to using it over JPA everywhere, but that is still up for debate.