I want to do a chat application and I found this code on GitHub : https://github.com/Pirngruber/AndroidIM. And author created a function to send a message which looks like this
public String sendHttpRequest(String params)
{
URL url;
String result = new String();
try
{
url = new URL(AUTHENTICATION_SERVER_ADDRESS);
HttpURLConnection connection;
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.println(params);
out.close();
BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
}
in.close();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
if (result.length() == 0) {
result = HTTP_REQUEST_FAILED;
}
return result;
}
Where private static final String AUTHENTICATION_SERVER_ADDRESS = "http://192.168.0.102/android-im/index.php";
And also here he explained how to make it run
https://code.google.com/archive/p/simple-android-instant-messaging-application/
So, my question is that: As I understood author sends all messages to his server and after this server sends them to user. So, if PC will be turned off server won't work and his chat won't work too, is it right? If yes, can somebody explain me how to do a chat app without server?
Thank you
Yes, seems like it requires a server to be online at all times. But that's how all modern chat applications on smartphones work (Telegram, Whatsapp, Threema, all google chats...). Without a server you would rely on the fact that both smartphones are online at the same time in order to establish a direct connection. This is a huge disadvantage and works against any power-saving features of the mobile OS. Also two parties can hardly communicate if they are always online at different times.
So essentially you need to decide for yourself whether you really want a peer-to-peer or a server-based chat. Just remember that even in case of P2P, you will have to figure out the IP addresses of the other chat clients. And then you'll probably have to use some sort of server, again.
What you need is a P2P chat implementation, you can use WIFI direct for that in Android. Checkout this code: https://github.com/life0fun/wifi-direct-chat
Usually the chat apps need to have a central server to receive the messages and send it to the correct nodes. That code you paste is that kind of implementation.
Related
I am working on a project which will have some part developed as a Android APP and some part as a website. The website would be a content management system, and the android app will be one of the consumer of the data.
Just to be aware, my background is completely .NET, C#. And i am learning, Java and Android, so far good.
I was thinking about the technology i should use, so that the two parts can communicate and also how i can reuse most of the common components like Logging, Instrumentation etc.
Few questions where i am not sure which would be the best choice:
Sharing cross platform code? In android i am writing code in Java, and in the website C#. I am facing an issue where how to re-use the common components like logging. I have heard about some tools like IKVM, but are they really worth? Or writing the code at two places will be a better choice in long term ?
Database: I am planning to go with ASP.NET MVC and MySQL and then on Android i can have a SQLite local DB, which i can sync using a web service. I really want to use MSSQL Server (because i know it very well). Is there a way to sync the MS SQL Server hosted remotely and the local Android SQLite DB? Or any other suggestion.
Also, if anyone has any suggestion in how to architect a hybrid solution like this, it would be really helpful.
Note: I cannot use tools like Xamrin as they are not free, and cost is a worry for now. Also, i want to really develop a native android app, which means i don't want to go with PhoneGap etc.
Thanks in advance.
the best way for android and website to communicate is a web service
I have worked on android apps that communicate with a .net web service to access
sql server database (insert, update, delete, retrieve data....etc)
but I fount that having a local data base causes a big issue in sync.
so all my apps dont have local DB and request all info from a local server connected using Wi-Fi.
code wise: you need to use Android AsyncTask to send http (GET,POST) requests to the Web service, this is an example of the code:
public class httpGetProduct extends AsyncTask<Void,Void,String> {
String result, rs;
JSONArray jArray;
String itemcode="",price,desc_ar,desc_en;
#Override
protected void onPreExecute() {
super.onPreExecute();
isOnline=ping(); // a function that checks if local server is available
}
#Override
protected String doInBackground(Void... params) {
if(isOnline)
try {
String link = "http://"+ip+":"+port+"/PriceCheckerWS.asmx/get_product_data?barcode="+barcode;
URL url = new URL(link);
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(link));
//execute http get request
HttpResponse response = client.execute(request);
// read the reply
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
// split string as the result is inside xml tags
String[] separated = result.split(">");
JSONObject jObject = new JSONObject(separated[2]);
jArray = jObject.getJSONArray("product");
// read the string in from of JSON array
JSONObject json_data = jArray.getJSONObject(0);
itemcode=json_data.getString("Barcode");
price=json_data.getString("Price");
desc_ar=json_data.getString("Item_Desc_Ar");
desc_en=json_data.getString("Item_Desc_En");
rs = "sucessful";
} catch (Exception e) {
rs = "Fail";
}
return rs;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//after execution is done you can do something here
if(!isOnline)
Toast.makeText(getApplicationContext(),
"Fail to connect to server", Toast.LENGTH_SHORT).show();
else if(itemcode.isEmpty())
{
if(lang){
Toast toast = Toast.makeText(getApplicationContext(),
"No information about this item in database", Toast.LENGTH_SHORT);
toast.show();
}
else{
Toast toast = Toast.makeText(getApplicationContext(),
R.string.no_data_ar, Toast.LENGTH_SHORT);
toast.show();
}
}else{
intent = new Intent(MainActivity.this, ViewProduct.class);
intent.putExtra("barcode", barcode);
intent.putExtra("price",price);
intent.putExtra("desc_ar",desc_ar);
intent.putExtra("desc_en",desc_en);
startActivity(intent);}
}
}
and in the onCreate you call the asynctask like this:
new httpGetProduct().execute();
hope this helps
Currently, I'm building a Android mobile app & Python restful server services.
I found that, it makes no different, whether or not I'm using
self.response.headers['Content-Type'] = "application/json"
The following code (which doesn't specific Content-Type explicitly) works fine for me. I was wondering, in what situation, I should specific Content-Type explicitly?
Python restful server services code
class DebugHandler(webapp2.RequestHandler):
def get(self):
response = {}
response["key"] = "value"
self.response.out.write(json.dumps(response))
application = webapp2.WSGIApplication([
('/debug', DebugHandler),
], debug = True)
Android mobile app client code
public static String getResponseBodyAsString(String request) {
BufferedReader bufferedReader = null;
try {
URL url = new URL(request);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
initHttpURLConnection(httpURLConnection);
InputStream inputStream = httpURLConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
int charRead = 0;
char[] buffer = new char[8*1024];
// Use StringBuilder instead of StringBuffer. We do not concern
// on thread safety. stringBuffer = new StringBuffer();
StringBuilder stringBuilder = new StringBuilder();
while ((charRead = bufferedReader.read(buffer)) > 0) {
stringBuilder.append(buffer, 0, charRead);
}
return stringBuilder.toString();
} catch (MalformedURLException e) {
Log.e(TAG, "", e);
} catch (IOException e) {
Log.e(TAG, "", e);
} finally {
close(bufferedReader);
}
return null;
}
Content-Type specifies what's inside the response (i.e. how to interpret the body of the response). Is it JSON, a HTML document, a JPEG, etc? It is useful when you have different representations of your resources and together with Accept it's a header involved in doing content negotiation between client and server.
Different clients might need different formats. A C# client might prefer XML, a Javascript client might prefer JSON, another client could work with multiple representations but try to request the most efficient one first and then settle for others if the server can't serve the preferred one, etc.
Content-Type is very important in the browser so that the user agent knows how to display the response. If you don't specify one the browser will try to guess, usually based on the extension and maybe fallback to some Save as... dialog if that fails also. In a browser, the lack of a Content-Type might cause some HTML to open a Save as... dialog, or a PDF file to be rendered as gibberish in the page.
In an application client, not having a Content-Type might cause a parsing error or might be ignored. If you server only serves JSON and your client only expects JSON then you can ignore the Content-Type, the client will just assume it's JSON because that's how it was built.
But what if at some point you want to add XML as a representation, or YAML or whatever? Then you have a problem because the client assumed it's always JSON and ignored the Content-Type. Now when it receives XML it will try to parse as JSON and fail. If instead the client was built with content types in mind and you always specify a Content-Type then your client will then take it into account and select an appropriate parser instead of blindly making assumptions.
I am developing an app that logs onto a tomcat server.
I am using a HTTP GET request to do so, and upon successful connection,
the message is displayed via a buffered stream.
The following code, is used to connect.
public String getInternetData() throws Exception {
BufferedReader in = null;
String data = null;
try {
HttpClient client = new DefaultHttpClient();
client.getConnectionManager().getSchemeRegistry().register(getMockedScheme());
URI website = new URI("https://ts.rks.com:8443/kss/login?username=hydm&password=pw1234");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
response.getStatusLine().getStatusCode();
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) != null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
} finally {
if (in != null) {
try {
in.close();
return data;
} catch (Exception e) {
Log.e("GetMethodLogin", e.getMessage());
}
}
}
This is the code that is activated when the user logs in via a login activity.
When I go back to the menu screen and try to run another activity that requires the user
to be logged in, it says that the user is not logged in.
Is the connection being disconnected when the user moves away from the activity or am I not establishing the connection correctly.
There are actually two things you need to change, not just one.
Anything that you need to have persistent across Activities should be done in a Service, not in the code of an Activity.
Second, on recent Android releases, all networking must be done from background threads, rather than the UI thread (there was always a recommendation against UI thread networking, but now it triggers an exception). Just putting the code in a Service does not mean it is in another thread.
So the answer is that you should be doing this using one of the background threading mechanisms, and doing that within a Service.
The connection will not persist when the activity is moved to the background. I cannot tell from your posted code, but I believe you should be using an AsyncTask for this connection. This is coming from my experience pulling HTML source from a link.
This question may answer yours: What to do with AsyncTask in onPause()?
I'm new to the android but now days done much more coding in Android. Now I have a doubt. I created android database application using Android and SQL Lte. But SQL Lite is client site database. But now my requirement is,I want a database like SQL Server,so that I connect my application to SQL Server. So suppose,consider and example,I know about WCF. I create a WCF service which have a function just like:
I hosted WCF on IIS because android does not response localhost,so i hosted WCF on IIS
Public string check(string username,string password)
{
SQLConnection con=new SQLConnection("Data Source=.;Database=test;Integrated Security=true");
SQLDataAdapeter ad=new SQLDataAdapter("select * from table where usrename='"+username+"'and password='"+password+"'");
Dataset ds=new Dataset();
ad.fill(ds,"table");
if(ds.Tables[0].Rows.Count>0)
{
return "true";
}
else
{
return "false";
}
}
I hosted WCF in my local host so that I can use this service in My Android Application coding.
just like:
HttpGet httpGet=new HttpGet("http://192.168.1.111:8083/Service1.svc/checkLogin?username="+UserName+"&password="+Password);
//Get the response
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
InputStream stream=httpEntity.getContent();
However here I'm not getting any httpEntity though the code is correct.
I take this entity and want to convert it into string by using function like:
public static String convertStreamToString(InputStream is)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
however,it does not return any string value,the debugger goes on catch point.
So what can I do so that i'll get result in string format from my WCF?
Based on above code, I am not sure how do you put mobile client app, WCF and SQL Server in perspective. The basic design is that WCF service will internally talk to SQL Azure and collect data for your. You mobile client will just connect to WCF service at exposed method and the method will pass the data to mobile client. I do not see that architecture in above description or code snippet.
I would suggest you to use oData WCF Data Services to connect any mobile application to SQL Server. OData services are fast and easy way to connect on-premise SQL Server or Cloud based RDBMS i.e. SQL Azure.
This article explains how to do it step by step so I would suggest trying it and if you met any problem, post to SO and we sure will help you:
Most of the Android developers actually prefer WCF using JSON to connect from Android to SQL Server/Azure so you sure can take a look as well here.
I'm developing an android application which is to collect data and then send it to a web directory.
So lets say a want to collect an array of data on the phone, and then after clicking a button send it all to the online directory as a file or stream. It does not even need to get a response - although in the future a confirmation would be handy.
Here is a guess at the sort of order of things...
dir = "someurl.com/data/files_received";
Array data;
sendDataSomehow(dir, data); //obv the difficult bit!
I am in very early stages of developing for Android although I have a lot of experience coding web so that bit will be fine.
I have found suggestions for things such as JSON, Google GSON, HTTP POST and GET - do these sound like the right track?
I hope I have been clear enough.
Yep, JSON would be a good solution for this.
Encode your array as JSON and then send it to your web server as the body of an HTTP POST request. If you have an hour to kill, here's a really good video from Google IO last year explaining how to implement a REST client on Android (what you're doing isn't strictly REST-ful, but the calls you make to the server are very similer): http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
Right, just wanted to do a quick thank for putting me on the right track. Just had one of those THE CODE WORKS EUREKA moments, very happy. I haven't used JSON but I have managed to pass a variable from Android to SQL through a HTTP-POST and little bit of PHP.
I'm sure this is not the recommended ideology for many reasons although for prototype and presentation it will do just fine!
Here is the code for android:
try {
URL url = new URL("http://www.yourwebsite.com/php_script.php");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
OutputStream out = conn.getOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.write("stringToPass=I'd like to pass this");
writer.close();
out.close();
if(conn.getResponseCode() != 200)
{
throw new IOException(conn.getResponseMessage());
}
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null)
{
sb.append(line);
}
rd.close();
conn.disconnect();
} catch (MalformedURLException e1) {
textBox.setText(e1.toString());
} catch (IOException e2) {
textBox.setText(e2.toString());
}
And here is the code for the PHP:
$conn = mysql_connect("localhost","web108-table","********") or die (mysql_error());
mysql_select_db("web108-table",$conn) or die (mysql_error());
$str = $_POST['stringToPass'];
mysql_query("INSERT INTO table(field) VALUES ($str)");
This code works, very simple. Next tests will be to find out if it is suitable for a large number of strings.
I hope this is helpful to somebody else.