Retrieving Entity from Google App Engine backend to Android App - java

I followed the tutorial on how to build a backend for mobile devices and was able to create a backend for my Android app and store Entites on GAE.The problem is, i don't know how to retrieve the properties of my entity.To store entites i used the following code:
public class EndpointsTask extends AsyncTask<Context, Integer, Long> {
protected Long doInBackground(Context... contexts) {
Userendpoint.Builder endpointBuilder = new Userendpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) { }
});
Userendpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
try {
User user = new User();
String username;
if (responseCheckbox.isChecked()) {
username = MainActivity.getPersonName();
}
else {
username = usernameTextField.getText().toString();
}
String location = locationTextField.getText().toString();
String tempAge = ageTextField.getText().toString();
String tempWeight = weightTextField.getText().toString();
String gender = genderTextField.getText().toString();
String occupation = occupationTextField.getText().toString();
int age = Integer.parseInt(tempAge);
int weight = Integer.parseInt(tempWeight);
user.setUsername(username);
user.setLocation(location);
user.setAge(age);
user.setWeight(weight);
user.setGender(gender);
user.setOccupation(occupation);
#SuppressWarnings("unused")
User result;
result = endpoint.insertUser(user).execute();
} catch (IOException e) {
e.printStackTrace();
}
return (long) 0;
}
}
with a call to new EndpointsTask().execute(getApplicationContext()); in my onCreate() method.
To retrieve the properties of the Entity and display them using TextViews this is what i have tried:
public class EndpointsTask extends AsyncTask<Context, Integer, Long> {
protected Long doInBackground(Context... contexts) {
Userendpoint.Builder endpointBuilder = new Userendpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) { }
});
Userendpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
try {
User user = new User();
usernameTextView.setText(user.getUsername());
locationTextView.setText(user.getLocation());
ageTextView.setText(user.getAge());
occupationTextView.setText(user.getOccupation());
weightTextView.setText(user.getWeight());
genderTextView.setText(user.getGender());
User result = endpoint.getUser(user.getUsername()).execute();
} catch (Exception e) {
e.printStackTrace();
}
return (long) 0;
}}
and then called new EndpointsTask().execute(getApplicationContext()); in my onCreate() method.When i tried to run the app, i don't get anything.
I have spent several hours looking for how to do it but i only find tutorials on saving entites.
Any help would be appreciated.

Your problem is that you are trying to update the ui in a background thread. After retrieving the user from GAE, you should pass it as a result to onPostExecute which get executed on the main thread, and then update your UI there. Here is a quick draft of the change you need in your code to make it work.
public class EndpointsTask extends AsyncTask<Context, Integer, User> {
protected User doInBackground(Context... contexts) {
Userendpoint.Builder endpointBuilder = new Userendpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new JacksonFactory(),
new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) { }
});
Userendpoint endpoint = CloudEndpointUtils.updateBuilder(
endpointBuilder).build();
User user = null;
try {
user = endpoint.getUser("username").execute();
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
protected void onPostExecute(User user) {
//update your UI here
usernameTextView.setText(user.getUsername());
locationTextView.setText(user.getLocation());
ageTextView.setText(Integer.toString(user.getAge()));
occupationTextView.setText(user.getOccupation());
weightTextView.setText(Integer.toString(user.getWeight()));
genderTextView.setText(user.getGender());
}
}

The line "User user = new User()" should be replaced with " User result = ...". You're creating a new (probably empty) instance of user, which you're using to fill the TextViews. You should use the instance fetched from the server instead.
EDIT: like this: https://gist.github.com/TomTasche/e574b4d98269f6533405
Moreover, it's best practice to do UI stuff in the main thread. So what you should do is return the "User result" and use it in onPostExecuted() to fill your TextView.

Related

How can I send notification to specific User using the user's token in Firebase?

I am developing an android app (java), I am using Firebase, for each registered user I have a token of the device, how can I send a notification to a specific user using his token ?
For sending a notification to users the only thing required is that user's token. You can send notification using FCM.
Here, I'm sharing my FCM class which can be used for this purpose. It is using Okhttp3 requests, so make sure you add its dependency.
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2'
After adding this dependency, all you have to do is to use this FCM class.
FCMMessages.java
public class FCMMessages {
private Context context;
public void sendMessageSingle(Context context, final String recipient, final String title, final String body, final Map<String, String> dataMap)
{
this.context = context;
Map<String, Object> notificationMap = new HashMap<>();
notificationMap.put("body", body);
notificationMap.put("title", title);
Map<String, Object> rootMap = new HashMap<>();
rootMap.put("notification", notificationMap);
rootMap.put("to", recipient);
if (dataMap != null)
rootMap.put("data", dataMap);
new SendFCM().setFcm(rootMap).execute();
}
public void sendMessageMulti(Context context, final JSONArray recipients, final String title, final String body, final Map<String, String> dataMap) {
this.context = context;
Map<String, Object> notificationMap = new HashMap<>();
notificationMap.put("body", body);
notificationMap.put("title", title);
Map<String, Object> rootMap = new HashMap<>();
rootMap.put("notification", notificationMap);
rootMap.put("registration_ids", recipients);
if (dataMap != null)
rootMap.put("data", dataMap);
new SendFCM().setFcm(rootMap).execute();
}
#SuppressLint("StaticFieldLeak")
class SendFCM extends AsyncTask<String, String, String> {
private String FCM_MESSAGE_URL = "https://fcm.googleapis.com/fcm/send";
private Map<String, Object> fcm;
SendFCM setFcm(Map<String, Object> fcm) {
this.fcm = fcm;
return this;
}
#Override
protected String doInBackground(String... strings) {
try {
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, new JSONObject(fcm).toString());
Request request = new Request.Builder()
.url(FCM_MESSAGE_URL)
.post(body)
.addHeader("Authorization","key=" + StaticConfig.myMessagingAuth)
.build();
Response response = new OkHttpClient().newCall(request).execute();
return response.body().string();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String result) {
try {
JSONObject resultJson = new JSONObject(result);
int success, failure;
success = resultJson.getInt("success");
failure = resultJson.getInt("failure");
//Toast.makeText(context, "Sent: " + success + "/" + (success + failure), Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
// Toast.makeText(context, "Message Failed, Unknown error occurred.", Toast.LENGTH_LONG).show();
}
}
}
}
Make sure you get the messagingAuth from your firebase project settings. To get the messagingAuth token, follow these steps:
Open Firebase Project > Project Settings > Cloud Messaging > Server key
Copy the value of server key and paste it as messagingAuth in your android project.
To send a notification to single user token use sendMessageSingle method. It would be like
String user_token = "wiubd92uhe91dik-q";
String notification_title = "This is notification title";
String notification_des = "This is notification description";
new FCMMessages().sendMessageSingle(MainActivity.this, user_token, notification_title, notification_des, null);
To send a notification to multiple user tokens use sendMessageMulti method. It would be like
ArrayList<String> user_tokens = new ArrayList<>();
user_tokens.add(token_1);
user_tokens.add(token_2);
user_tokens.add(token_3);
String notification_title = "This is notification title";
String notification_des = "This is notification description";
new FCMMessages().sendMessageMulti(MainActivity.this, new JSONArray(user_tokens), notification_title, notification_des, null);
Use this YouTube link here EDMT Dev has implemented the following in his Eat it new series. And kindly mark this as the correct answer if this helps you.
Add the below dependency
`implementation 'io.reactivex.rxjava2:rxandroid:2.1.1`'
Now Create these classes :
Token Model This Model is used to retrieve token data( Token , Phone ). I have also a variable for the phone because I made this class according to my datastructure . Kindly modify the code according to your need
public class TokenModel {
private String phone,token;
public TokenModel() {
}
public TokenModel(String phone, String token) {
this.phone = phone;
this.token = token;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}}
FCM Send Data Model
public class FCMSendData {
private String to;
private Map<String,String> data;
public FCMSendData(String to, Map<String, String> data) {
this.to = to;
this.data = data;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public Map<String, String> getData() {
return data;
}
public void setData(Map<String, String> data) {
this.data = data;
}}
Create FCM Result Model
class FCMResult {
private String message_id;
public FCMResult() {
}
public String getMessage_id() {
return message_id;
}
public void setMessage_id(String message_id) {
this.message_id = message_id;
}}
Create RetrofitFCMClient
public class RetrofitFCMClient {
private static Retrofit instance;
public static Retrofit getInstance()
{
if(instance==null)
{
instance = new Retrofit.Builder().baseUrl("https://fcm.googleapis.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
return instance;
}
return instance;
}}
Now we need to implement an interface
//Authorization key is server key of Cloud Messaging
public interface IFCMService {
#Headers({
"Content-Type:application/json",
"Authorization:key=**YOUR_AUTHORIZATION KEY HERE**"
})
#POST("fcm/send")
Observable<FCMResponse> sendNotification(#Body FCMSendData body);}
Now We are ready to use the firebase messaging just need to put data and use our retrofit to push it
TokenModel tokenModel = dataSnapshot.getValue(TokenModel.class);
//("FCM",tokenModel.getToken());
Map<String, String> notiData = new
HashMap<>();
notiData.put(Common.NOTI_TITLE, "YOUR NOTIFICATION TITLE");
notiData.put(Common.NOTI_CONTENT,"YOUR_NOTFICATION CONTENT );
FCMSendData sendData = new FCMSendData(tokenModel.getToken(),
notiData);
compositeDisposable
.add(ifcmService.sendNotification(sendData)
.subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<FCMResponse>() {
#Override
public void accept(FCMResponse
fcmResponse)
throws Exception {
if (fcmResponse.getSuccess()
== 1) {
Toast.makeText(getContext(),
"Success", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), "Failed
to Notify", Toast.LENGTH_LONG).show();
}
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable
throwable) throws Exception {
Toast.makeText(getContext(),
throwable.getMessage(), Toast.LENGTH_LONG).show();
}
}));
Use this YouTube link here EDMT Dev has implemented the following in his Eat it new series

Google spreadsheet create a new sheet with permission for all users have link

I tried to user the google sheet API v4 to create a new sheet. I create it successfully. However, I found that the sheet is setting as I am the only one is able to access. My goal is to allow users have the url link can access the sheet in Java request.
I tried to set google credidential to null when create spreadsheet, but it use as to create the spreadsheet in drive. Thus, this is not work.
I browser it library class and api, but I cannot found anything related to the permission.
I am not so sure the way I create the spreadsheet is on right way. Here is my code:
public class CreateSpreadSheetTask extends AsyncTask<Void, Void, Void> {
private com.google.api.services.sheets.v4.Sheets mService = null;
private Exception mLastError = null;
private String title = null;
private CreateSpreadsheetListener listener = null;
public CreateSpreadSheetTask(GoogleAccountCredential credential, String title, CreateSpreadsheetListener listener) {
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new Sheets.Builder(
transport, jsonFactory, credential)
.setApplicationName("Google Sheets API Android Quickstart")
.build();
this.title = title;
this.listener = listener;
}
#Override
protected Void doInBackground(Void... params) {
try {
this.listener.onRecvCreateSpreadsheet(getSpreadsheetFromApi());
} catch (Exception e) {
e.printStackTrace();
mLastError = e;
cancel(true);
}
return null;
}
private Spreadsheet getSpreadsheetFromApi() throws IOException {
Spreadsheet spreadsheet = new Spreadsheet();
SpreadsheetProperties properties = new SpreadsheetProperties();
properties.setTitle(this.title);
spreadsheet.setProperties(properties);
Sheets.Spreadsheets.Create request = mService.spreadsheets().create(spreadsheet);
return request.execute();
}
}
As #tehhowch said the permission should handle via the Drive API. Here is just update an answer for this.
private void updateProperty(com.google.api.services.drive.Drive driveService, String fileId, String email) throws IOException {
BatchRequest batch = driveService.batch();
Permission clientPermission = new Permission();
clientPermission.setEmailAddress(email);
clientPermission.setRole("writer");
clientPermission.setType("user");
driveService.permissions().create(fileId, clientPermission)
.setFields("id")
.setSendNotificationEmail(true)
.queue(batch, new JsonBatchCallback() {
#Override
public void onSuccess(Object o, HttpHeaders responseHeaders) throws IOException {
Log.e("permissione success", String.valueOf(o));
listener.onRecvShareSpreadsheet(true);
}
#Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) throws IOException {
Log.e("permissione error", e.getMessage());
listener.onRecvShareSpreadsheet(false);
}
});
batch.execute();
}
ref: Google api permission

How to pass two different JSON Objects to processFinish at two different times

I have this MainActivity which does two HTTP calls and return the JSON object back to the MainActivity class. I have seperately implemented the AsyncTask class and used the AsyncResponse interface to get the JSON object to the MainActivity by using the processFinish function call.
At first I came up with one HTTP call which worked perfectly.
Secondly I wanted to do another HTTP call in the same activity class. So I edit the code to cater the second HTTP call.
When I run the application, only the first HTTP call is working. When I call the second HTTP call it throws an exception saying reference to a null object
Then I checked by logging the onPostExecute method which calls the processFinish function. There I could see the JSON Object. So, that means the second JSON object doesn't get to the processFinish
How do I manage the second HTTP call? Please help me! I am new to Android.
Following is my AsyncTask class...
public class ServiceHandler extends AsyncTask<String, Void, JSONObject> {
String startStationID;
String endStationID;
String searchDate;
String startTime;
String endTime;
public ServiceHandler(String startStationID, String endStationID, String searchDate, String startTime, String endTime) {
this.startStationID = startStationID;
this.endStationID = endStationID;
this.searchDate = searchDate;
this.startTime = startTime;
this.endTime = endTime;
}
public interface AsyncResponse {
void processFinish(JSONObject output);
}
public AsyncResponse delegate=null;
public ServiceHandler(AsyncResponse delegate) {
this.delegate = delegate;
}
#Override
protected JSONObject doInBackground(String... params) {
String method = params[0];
JSONObject JSON_Object = null;
if (method.equals("getStations")) {
JSON_Object = Constants.apiCall("http://api.lankagate.gov.lk:8280/railway/1.0/station/getAll?lang=en");
} else if (method.equals("searchTrains")) {
JSON_Object = Constants.apiCall("http://api.lankagate.gov.lk:8280/railway/1.0/train/searchTrain?" +
"startStationID="+this.startStationID+"&" +
"endStationID="+this.endStationID+"&" +
"searchDate="+this.searchDate+"&" +
"startTime="+this.startTime+"&" +
"endTime="+this.endTime+"&" +
"lang=en");
}
return JSON_Object;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(JSONObject obj) {
try{
Log.d("onPostExecute",obj.toString());
delegate.processFinish(obj);
}catch (Exception e){
Log.e("onPostExecute",e.getMessage());
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
}
Following is my processFinish function...
#Override
public void processFinish(JSONObject output) {
Log.d("processFinish",output.toString());
if(!isSearchClicked) {
//Get all the stations...
if (output != null) {
Toast.makeText(MainActivity.this, "Successfully Connected!", Toast.LENGTH_SHORT).show();
try {
JSONObject obj = output.getJSONObject("RESULTS");
output = null;
JSONArray dataArray = obj.getJSONArray("stationList");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject object1 = dataArray.getJSONObject(i);
String stationID = object1.getString("stationID");
String stationName = object1.getString("stationName");
stationNames.add(stationName);
stationIDs.add(stationID);
// stations.put(stationID,stationName);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, " Connection Failed!", Toast.LENGTH_SHORT).show();
}
}else {
//search click action...
if (output != null) {
Toast.makeText(MainActivity.this, "Successfully Searched!", Toast.LENGTH_SHORT).show();
try {
JSONObject obj = output.getJSONObject("RESULTS");
JSONArray directTrains = obj.getJSONArray("directTrains");
// Log.d("array size",String.valueOf(directTrains.length()));
// for (int i = 0; i < directTrains.length(); i++) {
// JSONObject object1 = directTrains.getJSONObject(i);
//
// String stationID = object1.getString("stationID");
// String stationName = object1.getString("stationName");
// Log.d("JArr", stationID + " : " + stationName);
//
// stationNames.add(stationName);
// stationIDs.add(stationID);
//// stations.put(stationID,stationName);
// }
// Log.d("stationNames", stationNames.toString());
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, " Connection Failed!", Toast.LENGTH_SHORT).show();
Log.d("output",output.toString());
}
}
}
Following is my first HTTP call...
ServiceHandler sh = new ServiceHandler(this);
String method = "getStations";
sh.execute(method);
Following is my second HTTP call...
String method = "searchTrains"
ServiceHandler sh = new ServiceHandler(startStationID,endStationID,searchDate,startTime,endTime);
sh.execute(method);
Although I don't understand exactly what your problem is. There are few things I suggest you to do.
Here I go.
Don't use AsyncTask to make your http calls , use an intent services instead.
Use a OkHTTP library for your networking source
On your intent service send local broadcast with LocalBroadcastManager to broadcast your results from the http call.
Register broadcastsReceivers within your activities or fragments that will listen for those broadcasts that comes from the intent service
Why not to use AsyncTask: Because of configuration change - if you rotate your device you will lose that network calls-
Read about intent services here

Facebook SDK email and gender is given Null in android

Dear developers I'm try to save data from Facebook I'm getting other all data but can't get the email and gender.
This is my code
loginButton.setReadPermissions("public_profile");
loginButton.setReadPermissions("email");
loginButton.setReadPermissions("user_friends");
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
AccessToken accessToken = loginResult.getAccessToken();
GraphRequest request = GraphRequest.newMeRequest( loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object,GraphResponse response) {
if (response != null) {
try {
email = object.getString("email");
} catch (JSONException e) {
e.printStackTrace();
}
try {
gender = object.getString("gender");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "email,gender");
request.setParameters(parameters);
request.executeAsync();
Profile profile = Profile.getCurrentProfile();
userid = profile.getId();
userfirstname = profile.getFirstName();
middlename = profile.getMiddleName();
userlastname = profile.getLastName();
userimage = profile.getProfilePictureUri(30, 40);
linkuri = profile.getLinkUri();
name = profile.getName();
new AsyncTask<String, String, String>() {
#Override
protected String doInBackground(String... params) {
WebService ws = new WebService(URL);
Map<String, String> data = new HashMap<String, String>();
data.put("user_fb_id", userid);
data.put("first_name", userfirstname);
data.put("middle_name", userfirstname);
data.put("gender", gender);
data.put("email", email);
data.put("last_name", userfirstname);
data.put("user_fb_profile_name", name);
data.put("fb_profile_pic", userimage.toString());
try {
String response = ws.makeHTTPRequest(data, "POST");
JSONObject jsonObject = new JSONObject(response);
Log.e("Response", jsonObject.toString());
} catch (Exception e) {
Log.d("", "Exception : " + e.getMessage());
}
return null;
}
}.execute();
}
#Override
public void onCancel() {
//info = ("Login attempt canceled.");
}
#Override
public void onError(FacebookException e) {
// info = ("Login attempt failed.");
}
});
now I will let you know what is the error in my above code.
when i run the GraphRequest it will execute successfully but didn't get the email and gender. The email and gender is equal to null After the GrapRequest method i am running AsyncTask and send that data in my web services post class my class give me error of null email and gender but when i hover the email and gender after execution of AsyncTask they have that data please help me how to solve that issue.
what i want i want to store the user basic data if there is another way also let me know that i will try.
The problem occurs because In your code two Asynctask runs simultaneously.
Means that the GraphRequest class also runs an asynctask to get user data and you are also running a async to send the user data to server.
Async tasks always runs on separate thread(not on Main thread) and they don't wait for completion of other task.
So the solution is call your Async task in onCompleted() method. LIKE..
Write this async class for upload data to server outside of registerCallback.
private class Upload_Data extends AsyncTask<String, String, String>() {
#Override
protected String doInBackground(String... params) {
WebService ws = new WebService(URL);
Map<String, String> data = new HashMap<String, String>();
data.put("user_fb_id", userid);
data.put("first_name", userfirstname);
data.put("middle_name", userfirstname);
data.put("gender", gender);
data.put("email", email);
data.put("last_name", userfirstname);
data.put("user_fb_profile_name", name);
data.put("fb_profile_pic", userimage.toString());
try {
String response = ws.makeHTTPRequest(data, "POST");
JSONObject jsonObject = new JSONObject(response);
Log.e("Response", jsonObject.toString());
} catch (Exception e) {
Log.d("", "Exception : " + e.getMessage());
}
return null;
}
}
then call this async class in onCompleted method after getting the email and gender value and also check that email and gender is not null before calling Asynctask class.
#Override
public void onCompleted(JSONObject object,GraphResponse response) {
if (response != null) {
try {
email = object.getString("email");
} catch (JSONException e) {
e.printStackTrace();
}
try {
gender = object.getString("gender");
} catch (JSONException e) {
e.printStackTrace();
}
}
if(email!=null && gender!=null){
new Upload_Data().execute();
}
}
});
Hope this will helpful.

Return data from AsyncTask class

How do I get the data from my AsyncTask? My MainActivity is calling the DataCall.getJSON function that triggers the AsyncTask but I am not sure how to get the data back to the original Activity.
MainActivity with call to DataCall that should return a string and save it in state_data
String state_data = DataCall.getJSON(spinnerURL,spinnerContentType);
DataCall:
public class DataCall extends Activity {
private static final String TAG = "MyApp";
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
protected void onPostExecute(String result) {
//THIS IS WHERE I NEED TO RETURN MY DATA TO THE MAIN ACTIVITY. (I am guessing)
}
}
public void getJSON(String myUrlString, String contentType) {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.mywebsite.com/" + myUrlString });
}
}
modify your AsyncTask as below:
public class GetData extends AsyncTask<String, Void, String>
{
DataDownloadListener dataDownloadListener;
public GetData()
{
//Constructor may be parametric
}
public void setDataDownloadListener(DataDownloadListener dataDownloadListener) {
this.dataDownloadListener = dataDownloadListener;
}
#Override
protected Object doInBackground(Object... param)
{
// do your task...
return null;
}
#Override
protected void onPostExecute(Object results)
{
if(results != null)
{
dataDownloadListener.dataDownloadedSuccessfully(results);
}
else
dataDownloadListener.dataDownloadFailed();
}
public static interface DataDownloadListener {
void dataDownloadedSuccessfully(Object data);
void dataDownloadFailed();
}
}
and use it in your Activity
GetData getdata = new GetData();
getdata.setDataDownloadListener(new DataDownloadListener()
{
#SuppressWarnings("unchecked")
#Override
public void dataDownloadedSuccessfully(Object data) {
// handler result
}
#Override
public void dataDownloadFailed() {
// handler failure (e.g network not available etc.)
}
});
getdata.execute("");
NOTE: For the people who are reading this.
Please consider this post for the best and perhaps right implementation.
The key for me was to create a class called URLWithParams or something because AsyncTask will allow only 1 type to be sent IN, and I needed both the URL and the params for the HTTP request.
public class URLWithParams {
public String url;
public List<NameValuePair> nameValuePairs;
public URLWithParams()
{
nameValuePairs = new ArrayList<NameValuePair>();
}
}
and then I send it to a JSONClient:
public class JSONClient extends AsyncTask<URLWithParams, Void, String> {
private final static String TAG = "JSONClient";
ProgressDialog progressDialog ;
GetJSONListener getJSONListener;
public JSONClient(GetJSONListener listener){
this.getJSONListener = listener;
}
#Override
protected String doInBackground(URLWithParams... urls) {
return connect(urls[0].url, urls[0].nameValuePairs);
}
public static String connect(String url, List<NameValuePair> pairs)
{
HttpClient httpclient = new DefaultHttpClient();
if(url == null)
{
Log.d(TAG, "want to connect, but url is null");
}
else
{
Log.d(TAG, "starting connect with url " + url);
}
if(pairs == null)
{
Log.d(TAG, "want to connect, though pairs is null");
}
else
{
Log.d(TAG, "starting connect with this many pairs: " + pairs.size());
for(NameValuePair dog : pairs)
{
Log.d(TAG, "example: " + dog.toString());
}
}
// Execute the request
HttpResponse response;
try {
// Prepare a request object
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pairs));
response = httpclient.execute(httpPost);
// Examine the response status
Log.i(TAG,response.getStatusLine().toString());
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
return json;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String json ) {
getJSONListener.onRemoteCallComplete(json);
}
public interface GetJSONListener {
public void onRemoteCallComplete(String jsonFromNet);
}
}
Then call it from my main class like this
public class BookCatalog implements GetJSONListener {
private final String TAG = this.getClass().getSimpleName();
private String catalog_url = "URL";
private void getCatalogFromServer() {
URLWithParams mURLWithParams = new URLWithParams();
mURLWithParams.url = catalog_url;
try {
JSONClient asyncPoster = new JSONClient(this);
asyncPoster.execute(mURLWithParams);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onRemoteCallComplete(String jsonBookCatalogList) {
Log.d(TAG, "received json catalog:");
Log.d(TAG, jsonBookCatalogList);
JSONObject bookCatalogResult;
try {
bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue();
JSONArray books = bookCatalogResult.getJSONArray("books");
if(books != null) {
ArrayList<String> newBookOrdering = new ArrayList<String>();
int num_books = books.length();
BookCatalogEntry temp;
DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books.");
for(int book_id = 0; book_id < num_books; book_id++) {
JSONObject book = books.getJSONObject(book_id);
String title = book.getString("title");
int version = book.getInt("price");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Although i disagree creating a new activity for that simple task there is
startActivityForResult()
to get data from another activity.
Check this. You can store your data to the Intent's extras. But still if you have a large amount of data you better off write it to a file get the result from the other activity that is done downloading and then read the file.
Serialize it and then read it. The only way I'm aware of.
Some options:
a) Make your bean implement Serializable interface, you can then pass your bean through Intent.
b) Implement Application interface (you need to make an entry in manifest), Have setter\getter method in your Application class. You can set your bean in Application from AsyncTask and later retrieve from Activity.
Sorry for answering so late, i think by this time you might have solved this problem. when i was searching for something else, i came across your question. I'm pasting a link here which might of some help for others.

Categories