Android:Method Callback is not working - java

I am trying to implement method callback using relection but it is not calling the desired method.Here is my main activity
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RetrofitCalls retrofitCalls = new RetrofitCalls();
retrofitCalls.requestAccesstoken();
retrofitCalls.requestDataFromServer(MainActivity.this,"onCountryListReceived");
}
public void onCountryListReceived(JsonObject jsonObject)
{
String temp = "hello";
}
}
and here is the requestDataServer method
public void requestDataFromServer(final Activity activity, final String callBackMethod){
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new HeaderInterceptor())
.build();
retrofit = new Retrofit.Builder()
.baseUrl(Constants.ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
Api api = retrofit.create(Api.class);
Call<JsonObject> call = api.getDataFromServer(Constants.COUNTRY_LIST);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if(response.errorBody() != null){
try {
String j1 = response.errorBody().string();
String temp = "hello";
} catch (IOException e) {
e.printStackTrace();
}
}else if(response.body() != null) {
JsonObject jsonObject = response.body();
JsonArray jsonArray = jsonObject.getAsJsonArray("Data");
String temp = "hello";
try {
String x = activity.getClass().toString();
Method method = activity.getClass().getDeclaredMethod(callBackMethod.trim(),Object.class);
method.invoke(activity,jsonObject);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
String temp = "hello";
}
});
}
why the onCountryListReceived is not invoked? It is giving NoSuchMethodException. What's the problem?

Instead of Object.class i passed JsonObject.class in getDeclaredMethod as it is the parameter of the method to be called.
getDeclaredMethod accepts two parameters 1.callback method name 2.parameters of that method.

Related

Activity keeps restarting when I leave the activity and come back to it

I have two activities, When I will move from activity A to B, B keeps restarting or "refreshing", when i go back from B to A, it also keeps restarting. The code is very big, here I am posting area where I think problem causes :
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
deviceStatus();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
this is deviceStatus();
public void deviceStatus(){
try {
RequestQueue requestQueue = Volley.newRequestQueue(InActivate.this);
String URL = "http://gickuwait-dev.com/electionapi/api/DeviceStatus";
JSONObject jsonBody = new JSONObject();
jsonBody.put("device_PK", device_ID2);
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if(response.equals("true")){
Intent intent = new Intent(InActivate.this, Vote.class);
startActivity(intent);
finish();
}else if(response.equals("false")) {
}
// Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString;
String json = null;
try {
json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
responseString = String.valueOf(json).trim();
ArrayList<DeviceStatusResponse> list = new ArrayList<DeviceStatusResponse>();
Type listType = new TypeToken<List<DeviceStatusResponse>>() {}.getType();
list = new Gson().fromJson(responseString, listType);
device_Status = list.get(0).getIsActive().toString();
// Toast.makeText(getApplicationContext(), ""+device_Status+" null ", Toast.LENGTH_LONG).show();
return Response.success(device_Status, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
in Activity B, i have the same code to check the device status from the database, any help would be appreciated
You can use Handle to check the repeated task.
private Handler delayHandler = new Handler();
private Runnable runnable = new Runnable() {
#Override
public void run() {
deviceStatus();
driverDelayHandler.postDelayed(runnable, 1000);
}
};
Don't forgot to cancel on onStop method.
delayHandler.removeCallbacks(runnable);

Okhttp3 - IndexOutOfBoundsException after calls to API

I'm new to android development but I'm stuck on why I can make calls to my API, but it doesn't populate my class in time for the recycler view to populate. I get IndexOutOfBoundsException because the mData.getDataFeeds() returns null. If I debug this application and walk through it slowly, it works.
ListFeedAdapter listFeedAdapter = new ListFeedAdapter(mData.getDataFeeds());
I have an Activity that gets a Fragment.
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
RecyclerView recyclerView = view.findViewById(R.id.listRecyclerView);
try {
login();
getFeed();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
ListFeedAdapter listFeedAdapter = new ListFeedAdapter(mData.getDataFeeds());
recyclerView.setAdapter(listFeedAdapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
return view;
}
Then I call login()
private void login() throws IOException {
String user = "user";
String password = "pass";
String loginUrl = getString(R.string.jsonLogin);
OkHttpClient client = new OkHttpClient.Builder()
.build();
JSONObject credentials = new JSONObject();
JSONObject session = new JSONObject();
try {
credentials.put("email", user);
credentials.put("password", password);
session.put("session", credentials);
} catch (JSONException e) {
e.printStackTrace();
}
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, session.toString());
Request request = new Request.Builder()
.url(loginUrl)
.post(body)
.addHeader("Content-Type", mediaType.toString())
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String jsonData = response.body().string();
String jsonHead = response.headers("Set-Cookie").toString();
if(response.isSuccessful()) {
for (String setCookie : response.headers("Set-Cookie")) {
cookies.add(Cookie.parse(response.request().url(), setCookie));
}
}
}
});
The getFeed()
private void getFeed() throws IOException, JSONException {
String loginUrl = "http://testurlhere";
OkHttpClient client = new OkHttpClient.Builder()
.build();
MediaType mediaType = MediaType.parse("application/json");
Request request = new Request.Builder()
.url(loginUrl)
.get()
.addHeader("Content-Type", mediaType.toString())
.addHeader("_session", cookies.get(0).toString())
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
String jsonData = response.body().string();
String jsonHead = response.headers("Set-Cookie").toString();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mData = parseDataFeed(jsonData);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
updateDisplay();
}
});
}
}
catch (IOException e) {
Log.e(TAG, "Exception caught: ", e);
}
catch (JSONException e) {
Log.e(TAG, "Exception caught: ", e);
}
}
});
}
okhttp is an asynchronous operation, and you should use mData after onResponse ()
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
String jsonData = response.body().string();
String jsonHead = response.headers("Set-Cookie").toString();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mData = parseDataFeed(jsonData);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
ListFeedAdapter adapter = new ListFeedAdapter(mData.getDataFeeds());
rexyxlerView.setAdapter(adapter);
updateDisplay();
}
});
}
}
catch (IOException e) {
Log.e(TAG, "Exception caught: ", e);
}
catch (JSONException e) {
Log.e(TAG, "Exception caught: ", e);
}
}
});

AsyncTask already finished [duplicate]

This question already has answers here:
How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
(17 answers)
Closed 5 years ago.
How to catch moment when AsyncTask is finished?
I have ProfileUpdate class which extends AsyncTask, and from another activity I calling this method and after I need update my data. How to know that asynctask finished? My asynctask method in another class and not in activity class!!!
this is my onRefresh method in the activity:
#Override
public void onRefresh() {
if (!AlertView.isInternetAvailable(getContext())) {
swipeLayout.setRefreshing(false);
Toast.makeText(getContext(), Messages.CONNECTION_ERROR + ": " + Messages.NO_INTERNET, Toast.LENGTH_SHORT).show();
} else {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
new UpdateProfile(getActivity(), swipeLayout, sharedPreferences.getString(Constants.TOKEN, ""), user.getIin()).execute(Urls.GET_USER);
}
});
profileDefaults();
}
}
and here my AsyncTask method:
public class UpdateProfile extends AsyncTask <String, Void, String> {
private Activity activity;
private SwipeRefreshLayout swipeRefreshLayout;
private String token;
private String userIin;
private SharedPreferences sharedPreferences;
public UpdateProfile(Activity activity, SwipeRefreshLayout swipeRefreshLayout, String token, String userIin) {
this.activity = activity;
this.swipeRefreshLayout = swipeRefreshLayout;
this.token = token;
this.userIin = userIin;
sharedPreferences = this.activity.getSharedPreferences(Constants.PROJECT, Context.MODE_PRIVATE);
}
#Override
protected String doInBackground(String... params) {
URL url = null;
try {
url = new URL(params[0]);
try {
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("iin", userIin)
.build();
Request request = new Request.Builder()
.url(url)
.addHeader(Constants.AUTH_TOKEN, token)
.post(body)
.build();
Response responses = null;
try {
responses = okHttpClient.newCall(request).execute();
} catch (Exception e) {
AlertView.showAlertView(activity, Messages.CONNECTION_ERROR, Messages.NO_INTERNET, Messages.OK);
}
assert responses != null;
return responses.body().string();
} catch (Exception e) {
AlertView.showAlertView(activity, Messages.CONNECTION_ERROR, Messages.NO_INTERNET, Messages.OK);
}
} catch (Exception e) {
AlertView.showAlertView(activity, Messages.CONNECTION_ERROR, Messages.NO_INTERNET, Messages.OK);
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
JSONObject jsonObject = new JSONObject(s);
int code = Integer.valueOf(jsonObject.getString(Constants.CODE));
if (code == Codes.OK) {
Toast.makeText(activity, "Данные обновлены", Toast.LENGTH_SHORT).show();
String userHeader = jsonObject.getString("user");
JSONObject userInfo = new JSONObject(userHeader);
String mobilePhone = userInfo.getString(SingletonConstants.MOBILE_PHONE);
Boolean isActive = userInfo.getBoolean(SingletonConstants.IS_ACTIVE);
Boolean signedAgreement = userInfo.getBoolean(SingletonConstants.SIGNED_AGREEMENT);
Boolean esfEntered = userInfo.getBoolean(SingletonConstants.ESF_ENTERED);
String address = userInfo.getString(SingletonConstants.ADDRESS);
String iin = userInfo.getString(SingletonConstants.IIN);
String certExpDate = userInfo.getString(SingletonConstants.CERT_EXP_DATE);
String firstName = userInfo.getString(SingletonConstants.FIRST_NAME);
String middleName = userInfo.getString(SingletonConstants.MIDDLE_NAME);
String workPhone = userInfo.getString(SingletonConstants.WORK_PHONE);
String secondName = userInfo.getString(SingletonConstants.SECOND_NAME);
String avatarUrl = userInfo.getString(SingletonConstants.AVATAR_URL);;
String secondEmail = userInfo.getString(SingletonConstants.SECOND_EMAIL);
String email = userInfo.getString(SingletonConstants.EMAIL);
User newUser = new User(mobilePhone, isActive, signedAgreement, esfEntered, address, iin, certExpDate, firstName, middleName, workPhone, secondName, avatarUrl, secondEmail, email);
Gson gson = new Gson ();
String userGson = gson.toJson (newUser);
sharedPreferences.edit().putString(SingletonConstants.USER, userGson).apply();
swipeRefreshLayout.setRefreshing(false);
} else {
AlertView.showAlertView(activity, Messages.ERROR, jsonObject.getString(Constants.MESSAGE), Messages.OK);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
How I can call profileDefaults()? It's into my activity. And I need to call it after onPostExecute!
A cleaner way to do it is to use interfaces as listeners.
Create this interface:
public interface OnAsyncFinished{
void onAsyncFinished(Object o);
}
Add the interface as a parameter in your AsyncTaskClass constructor:
private OnAsyncFinished onAsyncFinished;
public UpdateProfile(..., OnAsyncFinished onAsyncFinished) {
...
this.onAsyncFinished = onAsyncFinished;
}
...
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
onAsyncFinished.onAsyncFinished(s); //This will notifiy the method on main activity, and you can now resume the work there
...
}
Implement the interface in your main activity:
public MainActivity extends Activity implements OnAsyncFinished {
#Override
public void onAsyncFinished(Object o) {
//This will get called after onPostExecute, do what u want with the object you got from onPostExecute, json or string in ur example
profileDefaults(); //call ur function
}
}
EDIT:
When creating the async task in your main activity pass this in the constructor likeso:
#Override
public void run() {
new UpdateProfile(..., this).execute(Urls.GET_USER);
}

FirebaseMessagingService is not getting called in AsyncTask's doInBackground

I have push Notification and I want to update realm objects when the phone gets a notification but when I try launch this:
RealmModelActiveUser actUser= realm.where(RealmModelActiveUser.class).equalTo("id",1).findFirst();
int myid= actUser.getUser().getUser_id();
new ServerBackgroundDownloadConversations(getApplicationContext()) {
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (!result.equals("Error")) {
Log.i("Conversation", "UPDATED");
}
}
}.execute(myid);
The program jumps into the constructor ServerBackgroundDownloadConversations(getApplicationContext()) but doesn't call doInBackground and I don't know why.
My AsyncTask:
public class ServerBackgroundCreateConversation extends AsyncTask<RealmModelConversations,Void,String> {
Context context;
Handler handler;
String out= "";
#SuppressLint("HandlerLeak")
public ServerBackgroundCreateConversation(Context context) {
this.context = context;
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
Bundle bundle= msg.getData();
if (bundle!=null){
out = (String) bundle.get("response");
} else {
out= "Error";
}
}
};
}
#Override
protected String doInBackground(RealmModelConversations... params) {
RealmModelConversations newConv = params[0];
UploadImageApacheHttp uploadTask = new UploadImageApacheHttp();
uploadTask.doFileUpload(newConv.getWork(newConv.getIntWork()), newConv, handler);
while (out.equals("")){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return out;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String result) {
if (!result.equals("]") || !result.equals("")){
/// prihlási nového user aj do active (login/register)
CreateNewConversation(result);
} else {
result="Error";
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
private void CreateNewConversation(String result){
Realm realm= Realm.getDefaultInstance();
try {
Gson gson = new Gson();
Type typeConv = new TypeToken<JsonSablonaConversations>() {
}.getType();
JSONObject pom;
JSONArray parentArray = new JSONArray(result);
JSONObject finalObject = parentArray.getJSONObject(0);
JsonSablonaConversations conversation = gson.fromJson(finalObject.toString(), typeConv);
final RealmModelConversations NewUserConv = new RealmModelConversations();
NewUserConv.setId_dialog(conversation.getId_dialog());
NewUserConv.setDate(conversation.getDate());
NewUserConv.setKey(conversation.getKey());
NewUserConv.setId_user(conversation.getId_user());
NewUserConv.setId_user2(conversation.getId_user2());
NewUserConv.setMeno(conversation.getMeno());
NewUserConv.setMeno2(conversation.getMeno2());
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
try {
realm.copyToRealmOrUpdate(NewUserConv);
} catch (Exception e) {
int pom=4;
}
RealmResults<RealmModelConversations> ru= realm.where(RealmModelConversations.class).findAll();
}
});
}
catch (Exception e) {
int ppp=4;
ppp++;
}finally {
realm.close();
}
}
}
I try calling this ↑ from an external thread which is called from a Service, but my AsyncTask has handler and handler needs to be in runOnUIthread and in Thread. I can't get Activity because the thread is called from a Service which doesn't have access to Activity.
I solved my problem with this code
public String postData(int myUserId) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.gallopshop.eu/OFY/getConversations.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", Integer.toString(myUserId)));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String responseStr = EntityUtils.toString(response.getEntity());
return responseStr;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
return null;
}
I will try to put this method & after this method into simply thread, But maybe it's not needed because it's in a service.
Question - Do I put this into Thread or do you think it'll affect the performance of the app?

Get Android Volley response in another class

I'm trying to use Volley as a DBA layer to call a webservice that hadles JSON objects. Because this layer is below the activity and another service layer, it doesn't seem to be working properly. I'll try to explain my setup:
MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ProductService productService = new ProductService();
productService.getProduct();
}
ProductService.java:
public void getProduct() {
JsonObjectRequest req = new JsonObjectRequest("http://echo.jsontest.com/name/Milk/price/1.23/", null, createMyReqSuccessListener(), createMyReqErrorListener());
ApplicationController.getInstance().addToRequestQueue(req);
}
private Response.Listener<JSONObject> createMyReqSuccessListener() {
return new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.v("response", response.toString());
}
};
}
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
return;
}
};
}
I hope that is clear enough.
In the end, I would like to use the ProductService::getProduct() from an activity and the the actual JSON response from the webservice in a variable which I can later use.
However, at the moment, the line
Log.v("response", response.toString());
doesn't even execute. What am I doing wrong?
What I would try is this:
Declare getProduct as
public void getProduct(Response.Listener<JSONObject> listener,
Response.ErrorListener errlsn) {
JsonObjectRequest req = new JsonObjectRequest("http://echo.jsontest.com/name/Milk/price/1.23/",null, listener, errlsn);
ApplicationController.getInstance().addToRequestQueue(req);
}
And than call in your activity like this:
productService.getProduct(
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
variableFromActivity = response;
//Or call a function from the activity, or whatever...
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Show error or whatever...
}
});
Create an abstract class AppActivity
import androidx.appcompat.app.AppCompatActivity;
public abstract class AppActivity extends AppCompatActivity
{
abstract void callback(String data);
}
Extend all your Activities using AppActivity
public class MainActivity extends AppActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "Your URL";
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("Title", "Android Volley Demo");
jsonBody.put("Author", "BNK");
}
catch (JSONException e) {
System.out.println(e);
}
final String requestBody = jsonBody.toString();
Messenger messenger = new Messenger(MainActivity.this);
messenger.sendMessage(this, url, requestBody);
}
public void callback(String data)
{
System.out.println(data);
}
}
Create Messenger class as below:
public class Messenger
{
private AppActivity myActivity;
public Messenger(AppActivity activity)
{
myActivity = activity;
}
public void sendMessage(Context context, String url, final String requestBody)
{
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(context);
// Request a string response from the provided URL.
StringRequest stringRequest =
new StringRequest(
Request.Method.POST,
url,
null,
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
}
) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
}
catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
myActivity.callback(new String(response.data));
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
queue.add(stringRequest);
}
}
Hope it helps.

Categories