Challenge with Android communicating to GAE using restlet - android

I'm using Eclipse to (try to) build an Android client to get reuse a restlet service I developed using GAE and GWT.
My service is running at
http://127.0.0.1:8888/abc/audits
I can test this by going directly to this url, and by using my GWT client - both work.
However, the following code returns a communication error
private AuditsResource resource;
private Audits audits;
ClientResource cr = new ClientResource("http://127.0.0.1:8888/abc/audits");
resource = cr.wrap(AuditsResource.class);
try {
// Get the remote contact
audits = resource.retrieve();
// The task is over, let the parent conclude.
handler.sendEmptyMessage(0);
} catch (Exception e) {
Message msg = Message.obtain(handler, 2);
Bundle data = new Bundle();
data.putString("msg", "Cannot get the contact due to: "
+ e.getMessage());
msg.setData(data);
handler.sendMessage(msg);
}
I have no idea where to look next. I've instrumented the server implementation of AuditsResource, and it is never touched (by the Android application).
The AuditsResource class has one method, to keep things simple for now
#Get
public Audits retrieve();

It appears the problem is that the Andriod Emulator cannot connect to either 127.0.0.1 or 10.0.2.2. The solution is to use your PC's IP address.

I am able to connect from Android to my local Google App Engine through Android/Restlet using 10.0.2.2 instead of localhost.

Related

Xamarin SqlServer cant get a connection

I'm building an app with the Entity Framework on Xamarin that lets me compare some data. But when I start my "fetchdata" function, I receive the Error:
System.Data.SqlClient.SqlException (0x80131904): Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)
I see many posts about Xamarin / Android & that it is not possible to get a connection to a SQL Server. Is there any way to fetch data from a SQL Server with .NET Core on Xamarin?
This is the string I put into SQL_Class folder with Sql_Common.cs
Fill up the brace brackets with actual parameters (removing the brace brakets too).
public static string SQL_connection_string = #"data source={server_address};initial catalog={database_name};user id={user_id};password={password};Connect Timeout={seconds}";
Then I access whenever I need it from any xamarin code just like we use in our asp.net c#
This works for me on my app without any issues.
using (SqlConnection Sql_Connection = new SqlConnection(Sql_Common.saralEHR_connection_string))
But as #Jason mentioned in his first reply, I too would get once again check the security part. I fexperienced before publishing Package to Google Play, they encrypt the App files with Hash Key Code and then only it gets upload to server
Yes it is possible (HuurrAYY!):
Im new in .net core, c# and so on and for me it was a hell of a work to get it working..
So here for the other noobs who are seeking for Help:
Guide´s i used:
Building Android Apps with Entity Framework
https://medium.com/#yostane/data-persistence-in-xamarin-using-entity-framework-core-e3a58bdee9d1
https://blog.xamarin.com/building-android-apps-entity-framework/
Scaffolding
https://cmatskas.com/scaffolding-dbcontext-and-models-with-entityframework-core-2-0-and-the-cli/
How i did it:
Build your normal Xamarin app.
create new .net solution like in the tutorials (DONT WRITE YOUR Entity Framework CLASSES)
create a third solution what has to be a .net core console application
Scaffold your DB in your CONSOLE application move all created classes & folders in your "xamarin .net" solution & change the namespaces
Ready to Go!
Side Node: NuGets you need in every solution:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
[EDIT: NuGets you need in every solution]
I am doing this way (working snippet):
string connectionString = #"data source={server};initial catalog={database};user id={user};password={password};Connect Timeout=10";
string databaseTable = "{table name}";
string selectQuery = String.Format("SELECT count(*) as Orders FROM {0}", databaseTable);
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
//open connection
connection.Open();
SqlCommand command = new SqlCommand(selectQuery, connection);
command.Connection = connection;
command.CommandText = selectQuery;
var result = command.ExecuteScalar().ToString();
//check if there is result
if(result != null)
{
OrdersLabel.Text = result;
}
}
}
catch (Exception ex)
{
OrdersLabel.Text = ex.Message;
}
It is working fine, but API call more elegant.
I hope it helps.

failed to connect to localhost/127.0.0.1 android

I am new to android development, and trying to call local .NET web api service in android via retrofit library. After starting my web api on IIS I am getting this error failed to connect to localhost/127.0.0.1 android.
When I did same thing as suggested http://themakeinfo.com/2015/04/retrofit-android-tutorial/, It's working fine, But my localhost service is not calling up from android
My service url is,
http://localhost:52511/api/Values/getAllStudents/5
and it is giving me output in XML format in browser too.
I have also try to call it with,
public interface gitapi {
#GET("/api/Values/GetProduct/{id}") //here is the other url part.best way is to start using /
public void getFeed(#Path("id") int id, Callback<gitmodel> response);
}
public class gitmodel {
public int studentId;
public String studentName;
public String studentAddress;
}
String API = "http://10.0.2.2:52511";
public void CallService(View view){
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(API).build();
gitapi git = restAdapter.create(gitapi.class);
int id = 5;
git.getFeed(id, new Callback<gitmodel>() {
#Override
public void success(gitmodel gitmodel, Response response) {
Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(getApplicationContext(), "Errors", Toast.LENGTH_LONG).show();
}
});
}
but no luck.
Please tell me where do I need to change to make it work. ?
Response I am getting in browser is,
<ArrayOfstudents xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/APICall.Controllers">
<students>
<studentAddress>valsad</studentAddress>
<studentId>1</studentId>
<studentName>Keval</studentName>
</students>
<students>
<studentAddress>Hyderabad</studentAddress>
<studentId>2</studentId>
<studentName>Honey</studentName>
</students>
</ArrayOfstudents>
Instead of using 127.0.0.1:<PORT> use your local IP
There's nothing to do with retrofit library in your case.
It's about your network settings,
your phone and IIS server must be the same LAN.
You can follow as below.
Launch an AP on you IIS server;
Connecting the AP with your phone.
Sometimes you need to close security firewall on your IIS server.
I had the same problem as u (failed to connect to localhost/127.0.0.1).
First of all i recommend u to read this:
android developer's guide (main part of this on the image↓)
I had all of this, mean A, B and C. As C(emulator) i used a Genymotion.
And i solved my problem by changing Network Configurations on it.
IMPORTANT: my adress in baseURL were: "localhost:8099/"
Let's see it:
U should click on Settings → Network → check Use HTTP Proxy → input your IP adress and Port(in my situation it was 8099) → close. See it more details on image ↓
I have the same problem, and I resolve it by changing the IP address instead of 'localhost':
open cmd(if you are using windows): type 'ipconfig' and see your computer's ip.(make sure that your computer and your android device connect to the same network).
remove 'localhost' in the url and use the ip(ip of your computer in step 1).
run the project again and check
Actually this helped when using 2 apps on the same Android device (Android 9)
android:usesCleartextTraffic="true"
You can try this in androidmanifest.xml
android:usesCleartextTraffic="true"

Avoid man in the middle (proxy) Android

I got a task at my job to reverse engineer an application.
I've been using Charles Proxy several times with other applications without any problems and have also tried Fiddler. I've always been able to monitor the request/responses made.
But the application that I'm trying now does now show any activity in either Charles or Fiddler. First I thought that they check the certificate and kill the connection but the application works as normal without any hiccups.
Is there any way for an application to be able to avoid the proxy settings or what am I missing?
I've been using apktool as well as dex2jar and found this peace of code. Probably not 100% correct but it can give you some clues of what happening.
public final void a(int paramInt1, int paramInt2)
{
this.b = paramInt2;
InetSocketAddress localInetSocketAddress = new InetSocketAddress(InetAddress.getByName(this.a), this.b);
while (true)
{
try
{
SSLContext localSSLContext = SSLContext.getInstance("TLS");
X509TrustManager[] arrayOfX509TrustManager = new X509TrustManager[1];
arrayOfX509TrustManager[0] = new c(this);
localSSLContext.init(null, arrayOfX509TrustManager, new SecureRandom());
this.e = ((SSLSocket)localSSLContext.getSocketFactory().createSocket());
this.e.connect(localInetSocketAddress, paramInt1);
this.d.clear();
if (Arrays.asList(this.e.getSupportedProtocols()).contains("TLSv1.2"))
{
this.d.add("TLSv1.2");
String[] arrayOfString1 = (String[])this.d.toArray(new String[this.d.size()]);
SSLSocket localSSLSocket1 = this.e;
if (arrayOfString1.length > 0)
localSSLSocket1.setEnabledProtocols(arrayOfString1);
this.c.clear();
if (!Arrays.asList(this.e.getSupportedCipherSuites()).contains("TLS_RSA_WITH_AES_256_CBC_SHA"))
break label374;
this.c.add("TLS_RSA_WITH_AES_256_CBC_SHA");
String[] arrayOfString2 = (String[])this.c.toArray(new String[this.c.size()]);
SSLSocket localSSLSocket2 = this.e;
if (arrayOfString2.length > 0)
localSSLSocket2.setEnabledCipherSuites(arrayOfString2);
e.a().a(this.e.getLocalAddress().getAddress());
e.a().a(this.e.getLocalPort());
a(5000);
this.e.startHandshake();
a(0);
return;
}
}
catch (Exception localException)
{
throw new IOException(localException.toString());
}
if (Arrays.asList(this.e.getSupportedProtocols()).contains("TLSv1.1"))
{
this.d.add("TLSv1.1");
}
else if (Arrays.asList(this.e.getSupportedProtocols()).contains("TLSv1"))
{
this.d.add("TLSv1");
continue;
label374: if (Arrays.asList(this.e.getSupportedCipherSuites()).contains("TLS_RSA_WITH_AES_128_CBC_SHA"))
this.c.add("TLS_RSA_WITH_AES_128_CBC_SHA");
else if (Arrays.asList(this.e.getSupportedCipherSuites()).contains("SSL_RSA_WITH_3DES_EDE_CBC_SHA"))
this.c.add("SSL_RSA_WITH_3DES_EDE_CBC_SHA");
else if (Arrays.asList(this.e.getSupportedCipherSuites()).contains("DES-CBC3-SHA"))
this.c.add("DES-CBC3-SHA");
}
}
}
Don't know that much about TLS 1.2 but I know its suppose to be more robust? But can it avoid the proxy?
I've also dumped the traffic using Wireshark, that worked but the information is encrypted, as expected, so its not much of use.
Any help would be appreciated.
This code will probably avoid proxy because is making direct socket. If you are using some higher level api, like HttpURLConnection, it respect proxy settings.
http://developer.android.com/reference/java/net/HttpURLConnection.html
You can try using SandroProxy to find out on which port communication is made.
http://code.google.com/p/sandrop/issues/detail?id=76
Go to HTTP tab and pres play button on acction bar
SandroProxy will listen on two new ports 8020 -> web , 8021 -> websockets for chrome devtools
start chrome from PC with url http your_device_ip:8020
Check Connection tab, last two columns are process uid and names(can be more than one)
To capture data you can also use SandroProxy and force iptable redirects. You will need rooted phone.
btw: send by sandroproxy support :)
You could try using something like adb forward 80 3456 against the device or emulator to have all port 80 traffic redirected to 3456 on your workstation. Then have your proxy listen on that port.

Cannot get list of public rooms from xmpp Server on Android?

Hello Everyone i am new to android and i am currently stuck on this.
I have to return list of public rooms created on xmpp server. The problem i am having is that the code below works fine for java but there is a null pointer exception in case of android.
Any help regarding this would be appreciated.
I am using an openfire server and testing it on local machine so that is the reason why i am using ip Address instead of domain name.
I am using smack library for JAVA and Asmack Library for android
String server_name = "192.168.3.113";
ConnectionConfiguration config = new ConnectionConfiguration(
server_name, 5222);
XMPPConnection connection = new XMPPConnection(config);
try {
connection.connect();
connection.login("s1", "123");
Collection<HostedRoom> rooms = MultiUserChat.getHostedRooms(
connection, "conference.geekoid");
for (HostedRoom room : rooms) {
System.out.println(room.getName());
}
} catch (XMPPException e) {
System.out.println("Error" + e.getMessage() + "\n"); //for JAVA
log.e("Android Error",e.getmessage()); // For Android
}
The problem is that the static block of the ServiceDiscoveryManager class has to be evaluated before any connection is created. In smack this is done via an configuration file, but this approach does not work on Android and therefore on aSmack.
The workaround mentioned in the answer is somehow ugly, since you really don't want to use the Constructor to fetch the SDM object, instead the get() method should be used. But the get() method only works if there was actually a SDM created for the connection.
So in order to init the SDM correctly on Android you need to call the full forName notation to init the static blocks of the class before you create the first (XMPP)Connection object.
Class.forName("org.jivesoftware.smackx.ServiceDiscoveryManager", true, ClassLoader.getSystemClassLoader()):
This is tracked as aSmack Issue 8
I have found the Solution to the problem.
The Android asmack library was using this in
getHostedRooms(Connection connection,
String serviceName) method
ServiceDiscoveryManager discoManager =ServiceDiscoveryManager.getInstanceFor(connection);
i replaced it with
ServiceDiscoveryManager discoManager = new ServiceDiscoveryManager(connection);
For those who are confused where this method is its in
Package: org.jivesoftware.smackx.muc
File: MultiUserChat.java
After you have done this. We have to register all the providers in Android whose detail can be found here. These providers are automatically registered when are using JAVA's smack library (In java Development) but in Android we have to register them ourself.

DatagramSocket.bind(); Socket exception: cannot assign requested address. Android Emulator

I am new to both Android and Java so I beg your pardon if my question
is asked at the inappropriate group or forum. I made a .Net
application for my company and recently they asked me to port it on
Android so as to install it on Samsung Galaxy Tabs.
First of all, I am using Eclipse, JDK 6, target platform android 2.2
and an Emulator with the GalaxyTab plugin. My operating system is Windows 7.
This application, sends and receives messages to and from a certain
controller on the network using UDP.
In short my application uses a "DatagramSocket", binds it to a local
"InetSocketAddress" and then launches a thread that listens for
datagrams, while another thread sends requests to the controller upon
the user's request. Here is a some code snippet:
This is where I assign the local address and the socket:
try {
loc_addr = new InetSocketAddress(
Inet4Address.getByAddress(
new byte[]{(byte) 192,(byte) 168,1,(byte)240}), 0xBAC0);
//192.168.1.240 is the IP of my machine on the network
} catch (UnknownHostException e) {
.......
}
try {
soc = new DatagramSocket();
soc.setReuseAddress(true);
soc.setBroadcast(true);
soc.bind(loc_addr);
} catch (SocketException e) {
.......
}
This is where I listen for incoming datagrams:
try{
buf = new byte[1024];
receive_pac = new DatagramPacket(buf, 1024);
soc.receive(receive_pac);
if (receive_pac.getData() != null){
.......
}
}
This is where I send data:
try {
addr = (Inet4Address) Inet4Address.getByAddress (new byte[]
{(byte) 192,(byte) 168,1,(byte) 255}); //The message I am sending should be broadcasted
} catch (UnknownHostException e) {
......
}
sendPacket = new DatagramPacket(buf, buf.length, addr,
loc_addr.getPort());
try {
soc.send(sendPacket);
} catch (IOException e) {
......
}
Well when I use "soc.bind(...)" I receive the following exception:
cannot assign requested address
Then I receive a debug message (I don't know if it is relevant):
DEBUG/SntpClient(58): request time failed: java.net.SocketException: Address family not supported by protocol
The application is working, I verified through "WireShark" that when I
ask from the emulator to send the data to the controller, the
controller replies back with the expected data correctly. However, the
socket, in the application, on the emulator doesn't receive anything and stays blocked on
the "Receive" call!
Can anyone help me figure out what problem or error I have committed with the receiving part of my application!
Any help is much appreciated,
TMI,
[Edited: If you saw my other answer, please disregard, I made the classic mistake of changing two variables in one test and it was the other variable that made the difference.]
In regards to this:
I tried binding it to the socket and it resulted with the "SocketException: Invalid Argument". Still the program delivered the same operation! Do you have any idea what this exception might mean?
You may have solved this by now, but I just had the same question and answered it myself here.
What got rid of this exception for me was to change the way I was creating the DatagramSocket.
From:
sock = new DatagramSocket();
To:
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
Usually you see that error message if you're trying to bind to an IP address that you don't own. Are you sure that the IP address of your Android emulator is 192.168.1.240? The emulator IP can be different from your host machine IP.

Categories

Resources