am using pushy for push notifications but am not able to store the device token in the database.
private class RegisterForPushNotificationsAsync extends AsyncTask<Void, Void, Exception> {
protected Exception doInBackground(Void... params) {
try {
// Assign a unique token to this device
String deviceToken = Pushy.register(getApplicationContext());
// Log it for debugging purposes
Log.d("MyApp", "Pushy device token: " + deviceToken);
// Send the token to your backend server via an HTTP GET request
new URL("https://key}/register/device?token=" + deviceToken).openConnection();
} catch (Exception exc) {
// Return exc to onPostExecute
return exc;
}
// Success
return null;
}
#Override
protected void onPostExecute(Exception exc) {
// Failed?
if (exc != null) {
// Show error as toast message
Toast.makeText(getApplicationContext(), exc.toString(), Toast.LENGTH_LONG).show();
return;
}
// Succeeded, optionally do something to alert the user
}
}
I am using retrofit for the http requests and am not using any kind of backend system
What you're doing is well enough to get you a Device Token from Pushy service.
If you want to capture the returned device token and make it accessible to the AsyncTask class and the enclosing class in general (as you stated in the comments), then you can declare a global/instance String variable, say pushy_device_token, in the enclosing class.
Then in doInBackground() method of the AsyncTask, go ahead and assign the global variable as follows:
pushy_device_token = Pushy.register(getApplicationContext());
Complete code:
public class EnclosingClass {
String pushy_device_token;
// Additional class code
private class RegisterForPushNotificationsAsync extends AsyncTask<Void, Void, Exception> {
#Override
protected Exception doInBackground(Void... params) {
try {
// Assign a unique token to this device
pushy_device_token = Pushy.register(getApplicationContext());
// Log it for debugging purposes
Log.d("MyApp", "Pushy device token: " + deviceToken);
// Send the token to your backend server via an HTTP GET request
new URL("https://key}/register/device?token=" + deviceToken).openConnection();
} catch (Exception exc) {
// Return exc to onPostExecute
return exc;
}
// Success
return null;
}
#Override
protected void onPostExecute(Exception exc) {
// Failed?
if (exc != null) {
// Show error as toast message
Toast.makeText(getApplicationContext(), exc.toString(), Toast.LENGTH_LONG).show();
return;
}
// Succeeded, optionally do something to alert the user
}
}
}
Best practice recommendation:
It's best to have the result of processing in doInBackground(), returned in the onPostExecute() method, especially if you're going to do some UI work. So from onPostExecute(), you can do anything you want with the result, e.g. display to the user, report an error, etc.
To do this, you'll have to modify your doInBackground() method to return something as generic as Object. And so onPostExecute() will take in an Object as a parameter variable.
You'll modify by:
private class RegisterForPushNotificationsAsync extends AsyncTask<Void, Void, Object> { . . .
From this, you can check if the Object taken in by onPostExecute() is of type Exception, in which case, you'll display an error notification, or check if it's of type String, in which case you'll have the device token which you can then proceed to save in your DB (Firebase, SQLite, etc.).
Related
Good Afternoon, I am still very new to ESP32/android studio coding so I apologize for my beginner terminology. I am currently coding a project where I can control multiple stepper motors at the same exact time from the press of a button on my android application and the motors are connected to certain ESP32 GPIO pins, I am using the okhttp3 client as well. My code is below.
public class Connectivity {
public static String geturl (String url_esp32){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url_esp32)
.build();
try
{
Response response = client.newCall(request).execute();
return response.body().string();
} catch(IOException error) {
return error.toString();
}
}
}
above is my connectivity page for connecting to the requests for the esp32.
PBNow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// request information from esp32
// PB sandwich now, disable jelly motor
request_to_url("STEP");
request_to_url("DIR");
request_to_url("STEP2");
request_to_url("DIR2");
request_to_url("STEP4");
request_to_url("DIR4");
request_to_url("ledRED");
request_to_url("ledGREEN");
}
});
above is how im calling the requests for the esp32.
The problem I am having is that when these request_to_url lines are going line by line but I want them to all run at the exact same time. Is this possible.
Below are also my request_to_url function and request_data function.
public void request_to_url (String command) {
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isConnected()) {
new request_data().execute("http://" + ip_address + "/" + command);
}else {
Toast.makeText(activity_2.this, "Not connected ", Toast.LENGTH_LONG).show();
}
}
private class request_data extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... url)
{
return Connectivity.geturl(url[0]);
}
#Override
protected void onPostExecute(String result_data) {
if(result_data != null)
{
}else{
Toast.makeText(activity_2.this, "Null data", Toast.LENGTH_LONG).show();
}
}
}
I apologize if the code is very sloppy, I am still very new. Thank you very much.
Besides the messy code in your app required to fire off multiple requests, the ESP32 has very limited network stack and resources, and cannot handle many simultaneous connections. If your app opens too many HTTP connections to the ESP32 at once, some will likely fail or have to wait for others to close.
Instead, you can do it all in a single request and tell the ESP32 to do multiple things at once. Pass the requests as parameters in the URL, like so:
http://ip-address/cmd?step=1&dir=0&ledGREEN=0&ledRED=1
Just have the handler on the ESP32 for the path /cmd look for the presence of each possible parameter and respond to it appropriately.
I have a code in my android app:
homes=Get_HomeList(this, progressBar, view, mMap,MapsActivity.this);
Log.v(TAG, "onMapReady: "+homes.size());
Get_HomeList is a function that fetches data from back end using asynchronous okhhttp call.
Inside this function I have onsuccessful method that is the place I have access to list of homes that has just been fetched.
However I need homes list outside of this function. but this line
Log.v(TAG, "onMapReady: "+homes.size());
gives me null for homes; I guess it is because it is running in parallel thread that has not seen home results yet.
Now my question is that how can handle this and be able to see fetched data outside Get_HomList function? Inside this function it looks like this:
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
try {
String responsedata = response.body().string();
homes= extractHomesUpdateMap(responsedata,mMap,mapsActivity);
} catch (IOException e) {
e.printStackTrace();
}
} else {
}
Is there a way that when loading is successful and finished I can pass the results outside of Get_HomeList?Or in General how we can deal with this cases?
Actully i working in a app, but i have problems to connect my Web services, i have this code:
try{
HttpServices post = new HttpServices ("http://sotem.com.mx/WebServices/controller.php");
post.add("funcion", "test");
System.out.println("Si lo mande///////////////////Jhgfdsa");
String respuesta = post.getRespueta();
System.out.println(respuesta);
Toast.makeText(getApplicationContext(),"Cool: "+respuesta, Toast.LENGTH_SHORT).show();
}catch (Exception ex) {
Toast.makeText(getApplicationContext(),"error: "+ex.toString(), Toast.LENGTH_SHORT).show();
}
but i can make connection, i try to make other thinks, but i can make the thread, i'am new in this part, the app launcher this error:
android os network on main thread exception
It is not okay to do the Network Operation on main thread.. You can use AsyncTask to perform such operations and handle the result in onPostExecute method.
class YourNetworkingTasks extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
try{
HttpServices post = new HttpServices ("http://sotem.com.mx/WebServices/controller.php");
post.add("funcion", "test");
String respuesta = post.getRespueta();
Log.d("Output", respuesta);
// DON'T DO ANY UI CHANGES LIKE TOAST FROM BACKGROUND THREAD.. Toast.makeText(getApplicationContext(),"Cool: "+respuesta, Toast.LENGTH_SHORT).show();
}catch (Exception ex) {
// DON'T DO ANY UI CHANGES LIKE TOAST FROM BACKGROUND THREAD.. Toast.makeText(getApplicationContext(),"error: "+ex.toString(), Toast.LENGTH_SHORT).show();
}
return null;
}
protected void onPostExecute(RSSFeed feed) {
// TODO: YOU CAN MAKE U.I. Changes Like Display text in TextView, TOAST HERE.
// TODO: do something with the result
}
}
And write new YourNetworkingTasks().execute(); to run that code in background thread.
Please also not that since you are using http and not https you may get Network Security Exception and may not get any output due to recent security change in android.
I'm trying to fetch Oauth token using GoogleAuthUtil.getToken and running the task as a separate thread using Async Task.
LogCat ouput shows me that the arguments required by the Async Task has been passed to it.(in this case the context, email and scope).
Here's the code of Async Task:
public class GetUsernameTask extends AsyncTask<Void, Void, Void>{
Activity mActivity;
String mScope;
String mEmail;
GetUsernameTask(Activity activity, String Email, String Scope){
Log.i(TAG,"Local variables are set from received arguments");
this.mActivity = activity;
this.mScope = Scope;
this.mEmail = Email;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
Log.i(TAG,"fetchToken is called");
String token = fetchToken();
mToken = token;
//Stuff to do with the token comes here - (Consider sending it to the backend;
} catch(IOException e){
}
return null;
}
LogCat also tells me that fetchToken() method is called. Here's the code for fetchToken()
private String fetchToken() throws IOException {
try {
Log.i(TAG,"attempts to getToken");
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException){
Log.i(TAG,"recoverable Exception Found");
//((MainActivity) mActivity).handleException(userRecoverableException);
} catch (GoogleAuthException fatalException){
Log.i(TAG,"fataException found");
}
return null;
}
The last logcat message before the debug mode opens up, is from Log.i(TAG,"attempts to getToken"); .
I have no idea how to proceed from here or how to do debugging in this particular case. Any direction on where to go next will be great.
There was a meta-data tag missing in the android manifest file. I added the followin code in the manifest file
<meta-data
android:name = "com.google.android.gms.version"
android:value="#integer/google_play_services_version"
/>
The error was pointed out after I had added RuntimeException which printed the suggestion. Here's the code I added for RuntimeException
catch (RuntimeException e){
Log.i(TAG, "RuntimeException caught");
e.printStackTrace();
}
I am new to android. I am developing the new app with email sending option. To send a mail I have used gmail configurations host "smtp.gmail.com", port 465 with SSL true. To send an email I have apache commons API. OnTouch event mail sending method will call. Whenever touch button it shows following errors,
Error : Could not find class 'javax.naming.InitialContext', referenced from method org.apache.commons.mail.Email.setMailSessionFromJNDI
Warning: VFY: unable to resolve new-instance 955 (Ljavax/naming/InitialContext;) in Lorg/apache/commons/mail/Email;
Warning : org.apache.commons.mail.EmailException: Sending the email to the following server failed : smtp.gmail.com:465
I have added uses-permission android:name="android.permission.INTERNET" in my manifest file.
Can i use all java files in android ?
My email code executed correctly as a stand alone java program.
Here is an example of what I am doing in an app. I have an app that has its own email account that sends an email to the user when they fill out a form and press the submit button.
Important make sure you have the libSMTP.jar file referenced in your app. I am using this library for the following code. Here is the following code being used, take from it what you'd like, hope this is useful:
Imports needed:
import org.apache.commons.net.smtp.SMTPClient;
import org.apache.commons.net.smtp.SMTPReply;
import org.apache.commons.net.smtp.SimpleSMTPHeader;
Submit button to make the request to send email
submit.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//-- Submit saves data to sqlite db, but removed that portion for this demo...
//-- Executes an new task to send an automated email to user when they fill out a form...
new sendEmailTask().execute();
}
}
});
Email task to be preformed on seperate thread:
private class sendEmailTask extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPostExecute(Void result)
{
}
#Override
protected void onPreExecute()
{
}
#SuppressLint("ParserError")
#Override
protected Void doInBackground(Void... params)
{
try {
//--Note the send format is as follows: send(from, to, subject line, body message)
send("myAppName#gmail.com", "emailToSendTo#gmail.com", "Form Submitted", "You submitted the form.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Send function being used:
public void send(String from, String to, String subject, String text) throws IOException
{
SMTPClient client = new SMTPClient("UTF-8");
client.setDefaultTimeout(60 * 1000);
client.setRequireStartTLS(true); // requires STARTTLS
//client.setUseStartTLS(true); // tries STARTTLS, but falls back if not supported
client.setUseAuth(true); // use SMTP AUTH
//client.setAuthMechanisms(authMechanisms); // sets AUTH mechanisms e.g. LOGIN
client.connect("smtp.gmail.com", 587);
checkReply(client);
//--Note the following format is as follows: client.login("localhost", (...your email account being used to send email from...), (...your email accounts password ...));
client.login("localhost", "myAppName#gmail.com", "...myAppName email account password...");
checkReply(client);
client.setSender(from);
checkReply(client);
client.addRecipient(to);
checkReply(client);
Writer writer = client.sendMessageData();
if (writer != null)
{
SimpleSMTPHeader header = new SimpleSMTPHeader(from, to, subject);
writer.write(header.toString());
writer.write(text);
writer.close();
client.completePendingCommand();
checkReply(client);
}
client.logout();
client.disconnect();
}
Check reply function being used:
private void checkReply(SMTPClient sc) throws IOException
{
if (SMTPReply.isNegativeTransient(sc.getReplyCode()))
{
sc.disconnect();
throw new IOException("Transient SMTP error " + sc.getReplyCode());
}
else if (SMTPReply.isNegativePermanent(sc.getReplyCode()))
{
sc.disconnect();
throw new IOException("Permanent SMTP error " + sc.getReplyCode());
}
}
From Apache Commons Net 3.3, you can just drop the jar in your classpath and start using the AuthenticationSMTPClient : http://blog.dahanne.net/2013/06/17/sending-a-mail-in-java-and-android-with-apache-commons-net/