Gcm android application triggers multiple registrations for the same device - java

My GCM app generate multiple registrations for same device. I have searched for this but coud'nt find any solution.
Here is my main activity::
public void onCreate(Bundle savedInstanceState) {
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, "952039800261");
} else {
Log.v(TAG, "Already registered");
}}
And this is my onRegistered() method::
protected void onRegistered(Context arg0, final String regId) {
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
// sets the app name in the intent
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", senderId);
startService(registrationIntent);
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.ludlowcastle.co.in/moksha/register.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("regId", regId));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
I have got around 5K registrations IDs for same device on my server..

You are registering in an infinite loop.
I don't use the GCMRegistrar class, but I'm quite sure that GCMRegistrar.register(this, "952039800261"); does the same as these lines :
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
// sets the app name in the intent
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", senderId);
startService(registrationIntent);
In my app, these 4 lines are in the onCreate method of my main activity instead of the GCMRegistrar call.
When onRegistered is called, this means the registration has been successful and you have a registration id. Since you are asking in this method to register again, a new registration request is sent to Google, and then this method is called again when the next registration succeeds. I'm not sure if you are getting different registration IDs on each call, or if you get the same one, but simply removing the mentioned 4 lines from onRegistered will solve your problem.

Related

How to send HTTP request from android app to Heroku

I have a android app that uses the twilio sdk and is hosted by heroku server. I'm trying to push a button in my app to send a HTTP request to heroku to send a REST API request to Twilio to update my twiml URL. The current way i'm trying to send the the HTTP request is not working. I have looked through all of the examples that i could find and none of them show how to do this function. Does anybody know how to do this? Thanks in advance.
This is my code for trying to send the HTTP request to heroku
holdButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://yourappnamehere.herokuapp.com/hello");
try {
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//setting a toast to see if this is being initiated
Toast.makeText(getBaseContext(), "why wont it work!", Toast.LENGTH_SHORT).show();
}
;
});
This is my updated code including the volley library
holdButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//setting up a request queue from Volley API
//RequestQueue mRequestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);
// Start the queue
mRequestQueue.start();
String url = "http://yourappnamehere.herokuapp.com/hello";
// Formulate the request and handle the response.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Do something with the response
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Handle error
}
});
// Add the request to the RequestQueue.
mRequestQueue.add(stringRequest);
Toast.makeText(getBaseContext(), "why wont it work!", Toast.LENGTH_SHORT).show();
}
;
});
I would suggest using a library like Google Volley which is pretty slick
https://developer.android.com/training/volley/index.html
HttpRequest is deprecated from API level 22. It would be best practice to avoid using that. Use java.net.HttpUrlConnection instead.
However, if you still want to use it, the above code needs to be run on a thread other than the UI thread as mentioned in the comment above.

doInBackground in AsyncTask for Android

I want to know that if a doInBackground method of a AsyncTask calls a method, for example XYZ(), Is that method also executed asynchronously?
Can we make changes to the UI in XYZ() in such a situation? Will it make the UI unresponsive?
I have a method call in doInBackground which is network intensive and requires to download an image from the web. The UI becomes unresponsive as soon as the call to that method is made. Why?
protected String[] doInBackground(String... params)
{
String[] response = new String[2];
Log.v("Background", "I am in background!");
String url = params[0];
String VoiceInput = params[1];
IsCalledOnVoiceInput = VoiceInput;
Log.v(url,url);
HttpPost httppost = new HttpPost(url);
try
{
HttpParams p = new BasicHttpParams();
HttpClient httpclient = new DefaultHttpClient(p);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
responseBody = httpclient.execute(httppost,
responseHandler);
Log.v("Thread", responseBody);
//Getting background image URL
JSONObject reader = new JSONObject(responseBody);
JSONObject coords = reader.getJSONObject("coord");
loc_latitude = coords.getString("lat");
loc_longitude = coords.getString("lon");
String imageURL="";
/////////////////////////////////////////////////////////////////////////////////
try
{
imageURL = getRandomImageURL(loc_latitude,loc_longitude);
Log.v("Image URL as recieved from getRandomImageURL", imageURL);
//Trying to convert Image from the above URL, get it and theh convert it to String
URL urlOfTheImage = new URL(imageURL);
bmp = BitmapFactory.decodeStream(urlOfTheImage.openConnection().getInputStream());
//Image successfully converted to string, ready to pass as a parameter!
response[0] = "";
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(),"There seems to be a problem with the application. Please try again later.", Toast.LENGTH_LONG).show();
}
Log.v("URL of Random Image",imageURL);
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
response[1] = responseBody;
return response;
}
The method getRandomImageURL and all that code in the try block is network intensive. I can also provide its code.
The code executing in the background is run in a separate thread. Anything it does, including calling other methods, happens in that thread. Since this is not the UI thread, it's not valid to make UI calls. You have to post messages to the UI thread.
Yes, whatever you call within doInBackgroud will run asynchronously. And no you shoudn't update UI from background thread for that you have CallBackDefined(onPostExecute). Or if UI update is require you can use runOnUIThread(...) API
You can make changes to the UI only from the UI thread. In general the doInBackground() is for lengthy operations that do not update the UI or access the UI toolkit. You can periodically publish changes in state that need to be reflected in the UI (eg progress bar showing status of a download operation) by calling publishProgress().
Set time out like this...
HttpPost httppost = new HttpPost(url);
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(httppost);

Invalid use of SingleClientConnManager: connection still allocated

I want to know why does this code not execute? I'm trying to send my data from my device via POST method but there is no error. The app just finishes by itself on my device by communicating "My app was stopped.:
Here is execution:
KlientNameValue kn = new KlientNameValue(getApplicationContext());
kn.new MyAsyncTask().execute(zam.klient.getNazwa(),zam.klient.getNip(),zam.klient.getAdres());
And here is code:
public class KlientNameValue {
List<NameValuePair> KlientNameValuePairs = new ArrayList<NameValuePair>();
Context context;
public KlientNameValue(Context context) {
super();
this.context=context;
}
public class MyAsyncTask extends AsyncTask<String, Void, Void> {
#Override protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
postData(params[0], params[1], params[2]);
return null;
}
#Override
protected void onPostExecute(Void result) {
Toast.makeText(context , "Zlecenie zostało wysłane",
Toast.LENGTH_LONG).show();
}
void postData(String nazwa, String nip, String adres) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("here is my default link :)");
try { // Add your data
KlientNameValuePairs = new ArrayList<NameValuePair>();
KlientNameValuePairs.add(new BasicNameValuePair("Kli_imie", nazwa));
KlientNameValuePairs.add(new BasicNameValuePair("Kli_adres", adres));
KlientNameValuePairs.add(new BasicNameValuePair( "Kli_nr_telefonu",
nip));
httppost.setEntity(new UrlEncodedFormEntity( KlientNameValuePairs));
HttpResponse response = httpclient.execute(httppost);
//httppost.setEntity(new UrlEncodedFormEntity(
// ZamowienieNameValuePairs)); // HttpResponse response1 =
} catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace(); }
}
}
}
Error:
02-15 17:45:24.695: E/AndroidRuntime(21890): at android.widget.Toast.<init>(Toast.java:94)
02-15 17:47:19.343: W/SingleClientConnManager(22288): Invalid use of SingleClientConnManager: connection still allocated.
02-15 17:47:19.343: W/SingleClientConnManager(22288): Make sure to release the connection before allocating another one.
Invalid use of SingleClientConnManager: connection still allocated.
You are executing the http request two times that is completely wrong before you consume it. So remove the second httpclient.execute(httppost); because you have already execute this http request.
and call this
httpResponse.getEntity().consumeContent();
Above method is called to indicate that the content of this entity is no longer required. All entity implementations are expected to release all allocated resources as a result of this method invocation
public static DefaultHttpClient getThreadSafeClient() {
DefaultHttpClient client = new DefaultHttpClient();
ClientConnectionManager mgr = client.getConnectionManager();
HttpParams params = client.getParams();
client = new DefaultHttpClient(
new ThreadSafeClientConnManager(params,
mgr.getSchemeRegistry()), params);
return client;
}
use this code so that your exception of free resource and allocate or being used will not come
This exception can happen when two or more threads interact with a single org.apache.http.impl.client.DefaultHttpClient
or simply give new object to each request when and where ever you are calling you get or post http client request to interact with server to fetch the data or download the large file
like
String post_url="http://www.google.com";
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpost = new HttpPost(Post_url);
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");
HttpResponse httpResponse = client.execute(httpost);
String response= EntityUtils.toString(httpResponse.getEntity());
as you like in code to retrieve the response

Sending sign up data from user to server

EDIT:
I finally figured out where the problem is. I keep getting an IOException on this line
response = httpClient.execute(httpPost).
However, the normal problems that will cause this error (the ones that I searched online, like the url being wrong and such) are not the problem here. The url is correct. Can anyone help or list all of the possible reasons I would get this error. Thank you.
I know this question has been asked several times, and I actually looked at the answers given for those questions in order to originally figure out how to do this but for some reason it's not working and I don't know why.
I have an app that requires a user to sign up. After they sign up I send the information they inputted to the server.
Android code:
//This is the method called when user presses submit button. The variables not declared
//are global
public void registerUser(View v){
context = getApplicationContext();
username = ((EditText) this.findViewById(R.id.username)).getText().toString();
email = ((EditText) this.findViewById(R.id.email)).getText().toString();
password=((EditText)this.findViewById(R.id.password)).getText().toString();
String[] params = {username,email,password};
(new SendRegisterInfo(this.getApplicationContext())).execute(params);
Toast t = Toast.makeText(context, "Thank you for Signing up "+username, Toast.LENGTH_SHORT);
t.show();
//Start Main Page Activity. Page they'll see everytime they login
Intent i = new Intent(this,HomeActivity.class);
startActivity(i);
}
public class SendRegisterInfo extends AsyncTask<String,Void,Void>{
private String tag = "SendRegisterInfo";
private InputStream is;
private Context c;
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
public SendRegisterInfo(Context c){
this.c = c;
}
#Override
protected Void doInBackground(String... params) {
String URI="http://www.mysite.com/registerUser.php";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(URI);
HttpResponse response;
String username,email,password;
username = params[0];
email = params[1];
password = params[2];
try {
ArrayList<NameValuePair> submit = new ArrayList<NameValuePair>(2);
submit.add(new BasicNameValuePair("username",username));
submit.add(new BasicNameValuePair("email",email));
submit.add(new BasicNameValuePair("password",password));
httpPost.setEntity(new UrlEncodedFormEntity(submit));
response = httpClient.execute(httpPost);
Log.i(tag,response.getStatusLine().toString());
} catch (ClientProtocolException e) {
Log.e(tag, "Error in http connection "+e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.e(tag, "Error in http connection "+e.toString());
e.printStackTrace();
}catch (Exception e){
Log.e(tag, "Error in http connection "+e.toString());
e.printStackTrace();
}
return null;
}
}
Manifest File:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
PHP Code:
<?php
$username = $_POST["username"];
$email = $_POST["email"];
$pswrd = $_POST["password"];
$score = 0;
$user = "root";
$password="pword";
$database = "databasename";
mysql_connect(localhost,$user,$password);
mysql_select_db($database) or die("Unable to Select Database");
$query="INSERT INTO Players VALUES ('','$username','$email','$pswrd','','$score')";
mysql_query($query);
mysql_close();
?>
You have an error reading the (String... params) argument of the doInBackground() method.
When you start the AsyncTask:
String[] params = {username,email,password};
When you read the arguments
String username,email,weight,password;
username = params[0];
email = params[1];
password = params[3]; // should be: password = params[2];
If this isn't works, adds a mySql query asking for the last insert id on the php program and print the result to get the response in the client:
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
Log.i(tag,EntityUtils.toString(entity).toString());
So you can see if you are inserting or not on the db.
This is your issue:
RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
You're attempting to show a Toast from a class that isn't designed to show a Toast. Or, perhaps, isn't prepared to show a tost. What is the class containing the method registerUser
Please check the code below.
Add function name and key to the request along with your data.
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add((NameValuePair) new BasicNameValuePair("f", "yourFunctionName."+methodName));
nameValuePairs.add((NameValuePair) new BasicNameValuePair("u", "a0ff8a6a0a831ec25cf4de6c730be54c"));
//u is the key used by server to identify valid request.

Way to set connection timeout in asynchronous post method

I am using an asynchronous post method to post some data to the server. The post is working fine, but if the server is down or unresponsive then I am getting a force close in the application.
How should I implement a timeout to the post request?
This is the class which is asynchronously posting to a particular url:
//===================================================================================================================================
//sending EmailAddress and Password to server
//===================================================================================================================================
private class MyAsyncTask extends AsyncTask<String, Integer, Double>{
#Override
protected Double doInBackground(String... params) {
// TODO Auto-generated method stub
postData(params[0],params[1]);
return null;
}
protected void onPostExecute(Double result){
if(responseBody.contains("TRUE"))
{
String raw=responseBody;
raw = raw.substring(0, raw.lastIndexOf("<"));
raw = raw.substring(raw.lastIndexOf(">") + 1, raw.length());
String [] contents = raw.split(",");
//extracting user name and user id from response
String user_name=contents[1];
String student_code=contents[2];
//save user name and user id in preference
saveInPreference("user_name",user_name);
saveInPreference("student_code",student_code);
//login is successful, going to next activity
Intent intent = new Intent(LoginActivity.this, TakeTestActivity.class);
//hiding progress bar
progress.dismiss();
finish();
LoginActivity.this.startActivity(intent);
}
else
{
//hiding progress bar
progress.dismiss();
create_alert("Attention!", "Please provide valid userid and password");
}
}
protected void onProgressUpdate(Integer... progress){
}
public void postData(String emailId,String passwrd) {
**//EDIT START**
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient httpclient = new DefaultHttpClient(httpParams);
**//EDIT END**
// Create a new HttpClient and Post Header
//HttpClient httpclient = new DefaultHttpClient();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(LoginActivity.this);
final String url_first = preferences.getString("URLFirstPart","");
HttpPost httppost = new HttpPost(url_first+"ValidateLogin");
try {
// Data that I am sending
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("EmailId", emailId));
nameValuePairs.add(new BasicNameValuePair("Password", passwrd));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
**//EDIT START**
try
{
// Execute HTTP Post Request
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
responseBody = EntityUtils.toString(response.getEntity());
}
catch (SocketTimeoutException ex)
{
// Do something specific for SocketTimeoutException.
}
**//EDIT END**
//Log.d("result", responseBody);
}
catch (Throwable t ) {
}
}
}
//===================================================================================================================================
//END sending EmailAddress and Password to server
//===================================================================================================================================
This is how I am calling the class to execute the post request:
//sending request for login
new MyAsyncTask().execute(txtUsername.getText().toString(),txtPassword.getText().toString());
What should I do to implement a connection timeout after a particular time if the server does not respond or is not available?
Edited:
How do I notify the user using an alert that the connection has timed out? Where should I put the alert and during which condition?
Thanks in advance!
You can try this, I've set 10 sec. here...
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
HttpConnectionParams.setSoTimeout(httpParams, 10000);
HttpClient client = new DefaultHttpClient(httpParams);

Categories