I would like to send and email on the background of my app.
I followed this example and implemented it
http://javapapers.com/android/android-email-app-with-gmail-smtp-using-javamail/
public class SendMailTask extends AsyncTask {
private ProgressDialog statusDialog;
private Activity sendMailActivity;
public SendMailTask(Activity activity) {
sendMailActivity = activity;
}
protected void onPreExecute() {
statusDialog = new ProgressDialog(sendMailActivity);
statusDialog.setMessage("Getting ready...");
statusDialog.setIndeterminate(false);
statusDialog.setCancelable(false);
statusDialog.show();
}
#Override
protected Object doInBackground(Object... args) {
try {
Log.i("SendMailTask", "About to instantiate GMail...");
publishProgress("Processing input....");
GMail androidEmail = new GMail(args[0].toString(),
args[1].toString(), (List) args[2], args[3].toString(),
args[4].toString());
publishProgress("Preparing mail message....");
androidEmail.createEmailMessage();
publishProgress("Sending email....");
androidEmail.sendEmail();
publishProgress("Email Sent.");
Log.i("SendMailTask", "Mail Sent.");
} catch (Exception e) {
publishProgress(e.getMessage());
Log.e("SendMailTask", e.getMessage(), e);
}
return null;
}
#Override
public void onProgressUpdate(Object... values) {
statusDialog.setMessage(values[0].toString());
}
#Override
public void onPostExecute(Object result) {
statusDialog.dismiss();
}
}
The code is working fine
However, i have a presentation and i need to explain the code.
In the code, SendMailTask extends AsyncTask without any extra parameters not even Void
I m stuck in this point because i searched and no one is using this way.
Can anyone explain it to me?
without the parameters, AsyncTask will assume the default class (which is Object)
public class SendMailTask extends AsyncTask <Object1, Object2, Object3> {
#Override
protected Object doInBackground(Object1... args) {
...
//publishProgress calls "onPublishProgress" method
//e.g. publishProgress("email sent.");
publishProgress(object2);
//last line returns to "onPostExecute" method
//e.g. return null;
return object3;
}
#Override
public void onProgressUpdate(Object2... values) {
...
}
#Override
public void onPostExecute(Object3 result) {
...
}
}
Object1 is the array of parameters you pass in when initializing the asyncTask
new SendMailTask(SendMailActivity.this).execute(fromEmail,
fromPassword, toEmailList, emailSubject, emailBody);
so fromEmail, fromPassword, etc, etc all goes into the array of Object1.
you access them in doInBackground method using arg[ index ].
If you not specify any Generic parameter , You will see it will take Object as a type (Base Class for all Classes)
So in case of using only AsyncTask
You are actually dealing with Object
eg- See the parameter of doInBackground() in the given link
Honestly, the way they've extended AsyncTask isn't terribly smart. It causes a number of annoying warnings in Android Studio, and it would have been just as easy to extend AsyncTask<Object, Object, Object>, it's the same effect, but it removes the warnings.
All of that said, in order to use the class, you can simply call the following:
Object[] args = new Object[]{
arg1,
arg2,
etc
};
new SendMailTask(activity).execute(args);
You just need to check the GMail constructor to see how you should order your args.
Related
I'm making an AsyncTask extension that communicates with a service using different actions and returns different types of results depending on the action used. Each action has a listener, made of interfaces extending one interface called OnCommunicationFailedListener. The thing is, I want to have only one variable to save the listener, OnCommunicationFailedListener type, and make the user be able to save all "sub-interfaces" in that variable. They can save them just as is, but I cannot call the methods that the "sub-interface" introduces.
class CommunicationTask extends AsyncTask<Void, Void, String> {
private Action action;
private OnCommunicationFailedListener listener;
enum Action {
LOGIN,
LOGOUT,
SEARCH
}
interface OnCommunicationFailedListener {
void onCommunicationFailed();
}
interface OnLoginAchievedListener extends OnCommunicationFailedListener {
void onLoggedIn(String result);
void onLoginError(String error);
}
interface OnLogoutAchievedListener extends OnCommunicationFailedListener {
void onLoggedOut(String result);
void onLogoutError(String error);
}
interface OnSearchAchievedListener extends OnCommunicationFailedListener {
void onSearchAchieved(String[] results);
}
#Override protected String doInBackground(Void... voids){
try {
// Try to communicate with a query, resulting in some result.
return result;
} catch(IOException e) {
e.printStackTrace();
}
return null;
}
#Override protected void onPostExecute(String result){
super.onPostExecute(result);
if(result == null) {
listener.onCommunicationFailed();
return;
}
// ALL OF THESE GIVE ERRORS, SINCE THE METHODS DO NOT EXIST ANYMORE
switch(action){
case LOGIN:
if(<check if result is ok>){
listener.onLoggedIn(result);
} else listener.onLoginError(<some error>);
break;
case LOGOUT:
if(<check if result is ok>){
listener.onLoggedOut(result);
} else listener.onLogoutError(<some error>);
break;
case SEARCH:
String[] results = <process result>;
listener.onSearchAchieved(results);
break;
}
}
void login(String user, String password, OnLoginAchievedListener listener){
this.listener = listener;
action = Action.LOGIN;
//Build the query...
execute();
}
void logout(OnLogoutAchievedListener listener){
this.listener = listener;
action = Action.LOGOUT;
//Build the query...
execute();
}
void search(String query, OnSearchAchievedListener listener){
this.listener = listener;
action = Action.SEARCH;
//Build the query...
execute();
}
}
The idea is that another class calls the methods login(), logout() or search() and gives them a listener of the action's type. When the communication is finalized and the result is acquired, the action's listener methods are called (in my code, this happens in the switch statement).
The thing is, these methods cannot be called since the passed listener has been casted to OnCommunicationFailedListener.
Is there any way to save a subclass in a variable of its superclass type without being casted to it? I don't want to have actual variables for every type of listener.
i've got something blowing my mind all day long.
The question is, I have an AsyncTask that returns me an User Object, with all its attributes. I know that I have to return from the doInBackground method and receive in the OnPostExecute to work with my data. The fact is that i want to extract that user out of the AsyncTask method because i have to work with it in my main thread.
My AsyncTask class is placed in the MainActivity.class.
i've heard about using interfaces to get my value back but i can't understand the way to do it.
public class FetchUserDataAsyncTask extends AsyncTask<Void, Void, User> {
RequestHandler rh = new RequestHandler(); //this is the class i use to do de server conection
User user;
User ret_user;
public FetchUserDataAsyncTask(User user){
this.user = user;
}
#Override
protected void onPostExecute(User user) {
super.onPostExecute(user);
//I WANT THIS USER IN MY MAIN THREAD, TO WORK WITH ITS ATTRIBUTES
}
#Override
protected User doInBackground(Void... params) {
try {
HashMap<String, String> dataToSend = new HashMap<>();
dataToSend.put("username", user.username);
dataToSend.put("password", user.password);
ret_user = rh.sendGetRequest("myadresstophp.php", dataToSend);
} catch (Exception e) {
e.printStackTrace();
}
return ret_user;
}
and the call (when user press the log in button), a few lines above.
new FetchUserDataAsyncTask(userk).execute();
I was hoping to do something like that: (i know its not the way to do it)
User user = new FetchUserDataAsyncTask(userk).execute();
Thank you all, have a nice day!
At first declare an Interface in your project somewhere having the required functions, then implement that interface in the (AsyncTask)calling class ,then declare one Interface object in the AsyncTask. Create the constructor of AsyncTask as follows:
public FetchUserDataAsyncTask(User user,InterfaceClass object){
this.user = user;
this.interfaceObject=object;
}
And then do the following in onPostExecute:
#Override
protected void onPostExecute(User user) {
super.onPostExecute(user);
interfaceObject.function(user); //call the function of the calling class
}
You can create an interface, pass it toAsyncTask (in constructor), and then call method in onPostExecute()
For example:
Your interface:
public interface OnTaskCompleted{
void onTaskCompleted();
}
Your Activity:
public class YourActivity implements OnTaskCompleted{
// your Activity
}
And your AsyncTask:
public class YourTask extends AsyncTask<Object,Object,Object>{
//change Object to required type
private OnTaskCompleted listener;
public YourTask(OnTaskCompleted
listener){
this.listener=listener;
} // required methods
protected void onPostExecute(Object
o){
// your stuff
listener.onTaskCompleted();
}
}
Here you go, this is in general how it would work. This is based on this answer and modified to be specific to your existing code. Basically assign your member variable based on what the user entered, and compare that value to the one you get from the server:
public class MyClass extends Activity {
//member variable for the username the user enters:
User userEnteredUser;
public class FetchUserDataAsyncTask extends AsyncTask<Void, Void, User> {
RequestHandler rh = new RequestHandler(); //this is the class i use to do de server conection
User user;
User ret_user;
public FetchUserDataAsyncTask(User user){
this.user = user;
}
#Override
protected void onPostExecute(User user) {
super.onPostExecute(user);
//I WANT THIS USER IN MY MAIN THREAD, TO WORK WITH ITS ATTRIBUTES
processValue(user); //added
}
#Override
protected User doInBackground(Void... params) {
try {
HashMap<String, String> dataToSend = new HashMap<>();
dataToSend.put("username", user.username);
dataToSend.put("password", user.password);
ret_user = rh.sendGetRequest("myadresstophp.php", dataToSend);
} catch (Exception e) {
e.printStackTrace();
}
return ret_user;
}
}
private void getValue()
{
EditText et = (EditText) findViewById(R.id.username);
userEnteredUser.username = et.getText().toString(); //something like this.... replace with your syntax
new FetchUserDataAsyncTask(userEnteredUser).execute();
}
private void processValue(User userFromServer)
{
if (userEnteredUser.equals(userFromServer)) {
//Users match! Yay!
}
}
}
onPostExecute runs on the UI thread by default (main thread). Do what ever you need to be do on the main thread in onPostExecute
I suggest you read up more from the link provided below for a better understanding on AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
I'm uncertain what you mean by "main thread". If you mean "UI Thread", which is the primary thread used to execute in your app, then Shashank's reply is correct.
However, I suspect from the context of the question that you actually mean that you want the results returned to the code that initiated the AsyncTask. Let's call that the "invoking object" In that case, what I would do is define a callback in your invoking object whose only purpose is to receive the result of this AsyncTank. You could call it onUserDataFetched(User user).
So, to do this using Interfaces, you could define an Interface that contains a single method:
public interface FetchUserDataListener {
public void onUserDataFetched(User user);
}
Then make sure that your InvokingObject implements that interface, and pass your InvokingObject (which implements FetchUserData, and thus can be considered that object type) to your AsyncTask when you instantiate it.
So, you invoking object code would look like this:
public class InvokingObject implements FetchUserData {
public void someMethodToInvokeFetchUserData() {
//....
new FetchUserDataAsyncTask(userk, this).execute();
//....
}
#Override
public void onUserDataFetched(User user) {
//Compare the result to the data in your invoking object
}
}
Then pass that callback to your AsyncTask when you construct it:
And your AsyncTask Code would look like this:
public class FetchUserDataAsyncTask extends AsyncTask<Void, Void, User> {
FetchUserDataListener mFetchUserDataListener;
public FetchUserDataAsyncTask(User user, FetchUserDataListener listner){
this.user = user;
mFetchUserDataListener = listener
}
//...
#Override
protected void onPostExecute(User user) {
super.onPostExecute(user);
listener.onUserDataFetched(user)
}
//...
}
I am new to java generics and below is the code that has created a confusion for me to pass generics class as an argument to the method.
I have created an android project where i have used Volley library to handle server calls.Below is the code
Advanced Connection Util : this class returns the JacksonRequest object
public class AdvancedConnectionUtil<T> {
private String requestType;
private ServerListener listener;
public AdvancedConnectionUtil(String requestType , ServerListener<T> listener){
this.listener = listener;
this.requestType = requestType;
}
public JacksonRequest getRequest(){
//This gives compile error while while passing DataList.class in the argument
return new JacksonRequest<T>(Request.Method.GET, HttpRequestConstant.JACKSON_FETCH, null ,DataList.class, new Response.Listener<T>() {
#Override
public void onResponse(T response) {
listener.onDataReceived(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
listener.onErrorReceived(error.getMessage());
}
});
}
public interface ServerListener<T> {
public void onDataReceived(T data);
public void onErrorReceived(String errorMsg);
}
}
Custom JacksonRequest class : this class handles the server call and the success call backs
public class JacksonRequest<T> extends JsonRequest<T> {
private Class<T> responseType;
/**
* Creates a new request.
* #param method the HTTP method to use
* #param url URL to fetch the JSON from
* #param requestData A {#link Object} to post and convert into json as the request. Null is allowed and indicates no parameters will be posted along with request.
* #param responseType
* #param listener Listener to receive the JSON response
* #param errorListener Error listener, or null to ignore errors.
*/
public JacksonRequest(int method, String url, Object requestData, Class<T> responseType, Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(method, url, (requestData == null) ? null : Mapper.string(requestData), listener, errorListener);
this.responseType = responseType;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return super.getHeaders();
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(Mapper.objectOrThrow(json, responseType), HttpHeaderParser.parseCacheHeaders(response));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
}
Here is My activity class that creates a request and pass it to other method to make a server call
public class CustomJacksonRequestActivity extends SuperActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showProgressBar();
JacksonRequest jacksonRequest = new AdvancedConnectionUtil<DataList>(null, httpListener).getRequest();
//This commented code works fine when i create a request this way
/* JacksonRequest<DataList> jacksonRequest = new JacksonRequest<DataList>(Request.Method.GET, HttpRequestConstant.JACKSON_FETCH, null, DataList.class, new Response.Listener<DataList>() {
#Override
public void onResponse(DataList response) {
hideProgressBar();
Log.e("ANSH", "onResponse : " + response.getPicture());
// fillListWithIndex(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideProgressBar();
Log.e("ANSH", "onErrorResponse : " + error.getLocalizedMessage());
}
});*/
onExecute(jacksonRequest);
}
#Override
protected void internetAvailable() {
}
#Override
public void setTitle(CharSequence title) {
super.setTitle("CustomJacksonActivity");
}
private AdvancedConnectionUtil.ServerListener httpListener = new AdvancedConnectionUtil.ServerListener<DataList>() {
#Override
public void onDataReceived(DataList data) {
Log.e("ANSH", "onResponse : " + data.getPicture());
}
#Override
public void onErrorReceived(String errorMsg) {
Log.e("ANSH", "onResponse : " + errorMsg);
}
};
Now the problem is i am not able to pass DataList.class(This is the response model class) as a parameter in the constructor of JacksonRequest Class inside the getRequest method of AdvancedConnectionUtil class though i am able to do that when i was creating the request object in the activity(see the commented code in the activity).
How can i pass the DataList.class to the constructor of JacsonRequest?
The updated code is in git hub now
github link to the project
Your code is a little confusing (you could do with a simpler example), but I'll give it a shot...
The JacksonRequest class takes one generic type parameter <T> and the type of 4th constructor parameter references this type: , Class<T> responseType,. That means that when an instance of JacksonRequest is instantiated (with T being a real type), the 4th parameter passed must guarantee to be of type T.class.
When you call the constructor...
return new JacksonRequest<T>(Request.Method.GET, blah, null ,DataList.class, ...
... you are calling it with a generic type argument <T>. The compiler must always be able to match generic type arguments with generic type parameters, but with the 4th parameter you are asking it to match T with DataClass. Since the compiler does not know what T is (or more precisely, it cannot guarantee that when it is instantiated, T will actually be DataClass), it gives an error.
Generally speaking, you cannot mix generic type parameters and real type values - you must consistently choose one or the other. There are options which allow you to specify that a generic type parameter will derive from a class or implement an interface (<T super DataClass> or <T extends DataClass>, but it's a bit much to explain here.
The problem with your code is that :
Your JacksonRequest<T> is declared to take a listener that must be parameterized on the same type as your responseType
However with your AdvancedConnectionUtil<T>.getRequest(...), there is no guarantee that the JacksonRequest created will meet the above requirement. Because you can always write code like:
new AdvancedConnectionUtil<String> (null, httpListener).getRequest();
So the parameter you passed into the constructor of JacksonRequest will be a DataList.class (of type Class<DataList>) and a listener of type Listener<String>
Sadly there is no way to do T.class in Java, although that indeed feels like what you need. Usually in such cases we will declare the AdvancedConnectionUtil as:
class AdvancedConnectionUtil<T> {
private final Class<T> responseType;
private final ServerListener<T> serverListener;
private final String requestType;
public AdvancedConnectionUtil (String requestType , Class<T> responseType, ServerListener<T> listener) {
this.requestType = requestType;
this.responseType = responseType;
this.serverListener = listener;
}
public JacksonRequest<T> getRequest(){
return new JacksonRequest<T>(0, "", null ,responseType, new Response.Listener<T>(){
...
}
}
You need pass your responseType of Class<T> into AdvancedConnectionUtil and keep it as a member field. This way the AdvancedConnectionUtil instance, when created, is strictly limited to provide JacksonRequest bounded to a specific response type.
You could in theory declare your getRequest method as getRequest(Class<T> responseType). But your AdvancedConnectionUtil does not seem to gain anything from that
First off - I'm rather novice at Java so if the question makes no sense do let me know.
Basically I'm making an Android app which communicates with my web service and so I've made a separate class to deal with the communication, which also includes the AsyncTask (I've removed a lot from the code here just for preview):
public class api {
private String caller = null;
Context that = null;
api(Context that) {
this.that = that;
this.caller = that.getClass().getSimpleName();
}
void call(String action) {
/* .... */
}
new back().execute(param1, param2);
}
void callback(String action, String result){
that.callback(action, result);
}
public class back extends AsyncTask<String, Void, String> {
public String response = null;
protected String doInBackground(String... params) {
response = connection.executeRequest(params[1]);
return response;
}
protected void onPostExecute(String result) {
callback("a", "b");
}
}
}
And when I use the class from some part of the app (let's say SomeClass.class), I do:
api WS = new api(this);
WS.call("....");
And it's supposed to execute the function 'callback' which is in SomeClass.
But the key problem here is this line:
that.callback(action, result);
Eclipse makes me add the name of the "caller" class in the cast:
(SomeClass) that.callback(action, result);
But that doesn't work for me, because I use the 'api' class from many different classes, so ideally I need to put a variable in the cast. I do get the name of the "caller" class here:
this.caller = that.getClass().getSimpleName();
//obviously this won't work:
(this.caller) that.callback(action, result);
Is there anyway to do that, or am I doing something fundamentally wrong?
Thank you.
Currently your api class accepts a Context object in its default constructor. It would make more sense to extend Context with a new class which contains a callback method which you can then override in subclasses such as SomeClass, that would negate the need for casting in your api class. e.g:
public class APIContext extends Context
{
public void callback( String action, String result )
{
/* ... */
}
}
public class SomeClass extends APIContext
{
#Override
public void callback( String action, String result )
{
/* ... */
}
}
public class api
{
private APIContext callerContext = null;
public api( APIContext context )
{
this.callerContext = context;
}
public void callback( String action, String result )
{
callerContext.callback( action, result );
}
}
I'm already working on this for weeks to get it working but without success. I'm using Javafx and java for implementing a small chat programm using the smack API (xmpp). The problem is how to get the received messages from java to javafx. The code below is actualy working when I have variable with a static string like "test message" and calling postMessage in java to send it to javafx. But how do I get another object (MessageListener) from java calling postMessage?
public class Java_callback implements RunnableFuture {
FXListener listener;
public String testmsg;
public Java_callback(FXListener listener) {
this.listener = listener;
}
#Override
public void run() throws Exception {
postMessage(testmsg);
}
public void postMessage(final String msg) {
Entry.deferAction(new Runnable() {
#Override
public void run() {
listener.callback(msg);
}
});
}
}
Here the code for processing the message. This part somehow need to call postMessage from the code above.
public void xmpp_create_chat(String msg) {
ChatManager chatmanager = connection.getChatManager();
Chat newChat = chatmanager.createChat("admin#unfc", new MessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
//msgArray.add( new String("Received message: " + message.getBody()) );
//msg_return = "blabla";
//java_callback.postMessage(msg_return);
//test.postMessage(message.getBody());
//System.out.println("Received message: " + message);
}
});
If you make postMessage() static, as in:
public static void postMessage(final String msg);
... then you can make a static method call to it from processMessage(), as in:
Java_callback.postMessage(msg_return);
UPDATE: Change your initializion of listener as well.
private static FXListener listener;
Hopefully this doesn't break something outside of the provided code :)
The class containing your second function has to have a reference to the first object, so that it can make the call.
What needs here is so basic that it's hard to figure out what an example might be.
something like this for your second class:
class MessageReceiver {
private Java_callback callback;
public void setJava_callback(Java_callback callback) {
this.callback = callback;
}
....
void process_message(...) { // inside your inner class
calllback.postMessage(msg);
}
}
Is the magic recipe that inner classes can refer to fields of their containing class?