[Q] How to replace onMeasure method? Can't call setMeasuredDimension - Xposed General

Hi there. I'm trying to write a module for an app that looks like this:
Code:
public class ThirdPartyAppView extends View {
// ...
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// ...
// do some stuff to calculate desired dimensions
// ...
setMeasuredDimension(desiredWidth, desiredHeight);
}
// ...
}
I want to change the calculated dimensions, so I'm replacing the onMeasure method of this class, like this:
Code:
XC_MethodReplacement onMeasure_replacement = new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
View v = (View) param.thisObject;
int paramInt1 = (Integer) param.args[0];
int paramInt2 = (Integer) param.args[1];
// ...
// do MY OWN stuff to calculate desired dimensions
// ...
setMeasuredDimension(myDesiredWidth, myDesiredHeight); // here is the problem call
return null;
}
};
findAndHookMethod("com.third.party.app.ThirdPartyAppView",
lpparam.classLoader,
"onMeasure", int.class, int.class,
onMeasure_replacement);
The roadblock I'm hitting is
Code:
The method setMeasuredDimension(int, int) is undefined for the type new XC_MethodReplacement(){}
Any pointers?

On closer look, that should be v.setMeasuredDimension:
Code:
View v = (View) param.thisObject;
// ...
v.setMeasuredDimension(myDesiredWidth, myDesiredHeight); // here is the problem call
return null;
But both onMeasure() and setMeasuredDimension() are protected methods on class ThirdPartyAppView. How could I call them from the module? I can't instance ThirdPartyAppView...

Found a solution thanks to http://forum.xda-developers.com/showpost.php?p=57190802&postcount=2
Ended up hooking on the superclass instead (android.view.View), doing things before calling setMeasuredDimension() there, and checking class name within the hook. This did the trick.
Code:
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals(com.third.party.app))
return;
XC_MethodHook setMeasuredDimensionHook = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (param.thisObject.getClass().getName().equals(com.third.party.app.ThirdPartyAppView") {
View v = (View) param.thisObject;
int paramInt1 = (Integer) param.args[0];
int paramInt2 = (Integer) param.args[1];
// ...
// calculate my dimensions here
// ...
param.args[0] = desiredWidth;
param.args[1] = desiredHeight;
}
};
findAndHookMethod("android.view.View",
lpparam.classLoader,
"setMeasuredDimension", int.class, int.class,
setMeasuredDimensionHook);
}

Nephiel said:
Found a solution thanks to http://forum.xda-developers.com/showpost.php?p=57190802&postcount=2
Ended up hooking on the superclass instead (android.view.View), doing things before calling setMeasuredDimension() there, and checking class name within the hook. This did the trick.
Code:
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals(com.third.party.app))
return;
XC_MethodHook setMeasuredDimensionHook = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (param.thisObject.getClass().getName().equals(com.third.party.app.ThirdPartyAppView") {
View v = (View) param.thisObject;
int paramInt1 = (Integer) param.args[0];
int paramInt2 = (Integer) param.args[1];
// ...
// calculate my dimensions here
// ...
param.args[0] = desiredWidth;
param.args[1] = desiredHeight;
}
};
findAndHookMethod("android.view.View",
lpparam.classLoader,
"setMeasuredDimension", int.class, int.class,
setMeasuredDimensionHook);
}
Click to expand...
Click to collapse
Another way is to "emulate" call to setMeasuredDimension directly from onMeasure hook.
Example: https://github.com/GravityBox/Gravi...kitkat/gravitybox/ModQuickSettings.java#L1358
"Emulating" means you basically execute the same code that the original method does.
Of course, attention should be paid to different android versions and potential differences in setMeasuredDimension implementation.

Related

[Q] Hook to BroadcastReceiver.

How to hook a onReceive method which is inside BroadcastReceiver?
Code:
public class RecentsActivity extends Activity
{
mIntentReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
...
}
};
}
I want to get my hook called when onReceive is invoked.
Anyone know?
mIntentReceiver is registered within onCreate method, so...
PHP:
XposedHelpers.findAndHookMethod(RecentsActivity.class, "onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// get the field
final BroadcastReceiver mIntentReceiver = (BroadcastReceiver) XposedHelpers.getObjectField(param.thisObject, "mIntentReceiver");
// hook its class
XposedHelpers.findAndHookMethod(mIntentReceiver.getClass(), "onReceive", Context.class, Intent.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// check it !!!
BroadcastReceiver thiz = (BroadcastReceiver) param.thisObject;
if (thiz == mIntentReceiver) {
// get parameters
Context context = (Context) param.args[0];
Intent intent = (Intent) param.args[1];
// do your job...
}
}
});
}
});
Hope that helps you!!

App lags and freeze badly.

is it because of many operations executing from main UI ?
In my app i just have a splash screen and a main activity. In the main thread i have three EditText boxes and a spinner with a string array. On clicking the Button, input from three EditText and spinner selection is posted to my mysql database. For the button click network operation, i used Volley since its east and i dont have to use AsyncTask which am not familiar with.
Apart from this, on entering the main UI .. app first check for network connectivity using ConnectivityManager class. After onClick app checks for empty/invalid imputs using TextUtils.
Now the problem is that when i run my app, its very slow and taking upto 65mb of RAM. IS something wrong with my code. Should i run something else as AsynTask ? Can someone check my code and refine it .. thank you
SplashActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
int SPLASH_TIME_OUT = 5000;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent i = new Intent(SplashActivity.this, MainActivity.class);
startActivity(i);
finish();
}
}, SPLASH_TIME_OUT);
}
}
Click to expand...
Click to collapse
MainActivity.java
Code:
public class MainActivity extends Activity {
EditText name, phonenumber, address;
Button insert;
RequestQueue requestQueue;
Spinner spinner;
String insertUrl = "localhost";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner s = (Spinner) findViewById(R.id.spinner);
s.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
/* CHECK INTERNET CONNECTION */
boolean mobileNwInfo;
ConnectivityManager conxMgr = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
try { mobileNwInfo = conxMgr.getActiveNetworkInfo().isConnected(); }
catch (NullPointerException e) { mobileNwInfo = false; }
if (!mobileNwInfo) {
Toast.makeText(this, "No Network, please check your connection. ", Toast.LENGTH_LONG).show();
}
/* CHECK INTERNET CONNECTION PROCEDURE DONE */
name = (EditText) findViewById(R.id.editText);
phonenumber= (EditText) findViewById(R.id.editText2);
address = (EditText) findViewById(R.id.editText3);
insert = (Button) findViewById(R.id.insert);
requestQueue = Volley.newRequestQueue(getApplicationContext());
spinner = (Spinner) findViewById(R.id.spinner);
insert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
/* CHECK EMPTY STRING */
EditText txtUserName = (EditText) findViewById(R.id.editText);
EditText txtUserAddress = (EditText) findViewById(R.id.editText3);
EditText txtUserPhone = (EditText) findViewById(R.id.editText2);
String strUserName = name.getText().toString();
String strUserAddress = address.getText().toString();
String strUserPhone = phonenumber.getText().toString();
if(TextUtils.isEmpty(strUserName)) {
txtUserName.setError("You can't leave this empty.");
return;
}
if(TextUtils.isEmpty(strUserPhone)) {
txtUserPhone.setError("You can't leave this empty.");
return;
}
if(TextUtils.isEmpty(strUserPhone) || strUserPhone.length() < 10) {
txtUserPhone.setError("Enter a valid phone number.");
return;
}
if(TextUtils.isEmpty(strUserAddress)) {
txtUserAddress.setError("You can't leave this empty.");
return;
}
/* LOADING PROCESS DIALOG */
final ProgressDialog pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Booking Service ....");
pd.show();
/* REQUEST RESPONSE/ERROR */
StringRequest request = new StringRequest(Request.Method.POST, insertUrl, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
pd.hide();
System.out.println(response);
name.setText("");
phonenumber.setText("");
address.setText("");
Toast.makeText(getApplicationContext(), "Service successfully booked !!", Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
pd.hide();
Toast.makeText(getApplicationContext(), "Error: Please try again later.", Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<>();
parameters.put("name", name.getText().toString());
parameters.put("phonenumber", phonenumber.getText().toString());
parameters.put("address", address.getText().toString());
parameters.put("service", spinner.getItemAtPosition(spinner.getSelectedItemPosition()).toString());
return parameters;
}
};
requestQueue.add(request);
}
});
}
}

(New) Question about custom arrayadapter

Hey everyone,
I am working on a schoolproject and I want to make an app for that, but haven't coded any app before, so I recently started on it.
Right now I have a listview working with a custom arrayadapter with a custom class.
However, whenever I reload the app, it doesn't change the textview to the name of my custom class but just stays at "Textview"
This is my code:
Code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LockManager lockManager = new LockManager();
lockManager.AddNewLock("Lock1");
lockManager.AddNewLock("Testielock2");
ListView listView = (ListView) findViewById(R.id.LockListView);
listView.setAdapter(new MyListAdapter(this, R.layout.listitem2, lockManager.Locks));
}
private class MyListAdapter extends ArrayAdapter<Lock>{
private int _layout;
public MyListAdapter(Context context, int resource, List<Lock> objects) {
super(context, resource, objects);
_layout = resource;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Viewholder mainViewHolder = null;
if (convertView == null){
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(_layout, parent, false);
Viewholder viewholder = new Viewholder();
viewholder._image = (ImageView) convertView.findViewById(R.id.list_item_picture);
viewholder._text = (TextView) convertView.findViewById(R.id.list_item_text);
viewholder._switch = (Switch) convertView.findViewById(R.id.list_item_switch);
viewholder._switch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getItem(position).Toggle();
Toast.makeText(getContext(), "Clicked switch for " + getItem(position).Name, Toast.LENGTH_LONG).show();
}
});
convertView.setTag(viewholder);
}
else
{
mainViewHolder = (Viewholder) convertView.getTag();
Lock lock = getItem(position);
mainViewHolder._text.setText(lock.Name);
}
return convertView;
}
}
public class Viewholder{
ImageView _image;
TextView _text;
Switch _switch;
}
Thank you in advance for your help,
Patrick de Mooij
Question about custom arrayadapter
http://stackoverflow.com/questions/36862968/android-custom-arrayadapter-with-custom-object

Using an arraylist for listview. Problem with setadapter

Hi, Can someone please help me to resolve the following issue?
I have an arraylist that I have created in an activity file. Name of this arraylist is doctorList and it is public. But when I try to populate a listview with this arraylist using setadapter, it refuses to identify the arraylist.
Code:
private ListView docList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doctor__list);
docList = (ListView) findViewById(R.id.docList);
docList.setAdapter(new ArrayAdapter<String>(Doctor_List.this, android.R.layout.simple_list_item_1, [B][U][I]doctorList[/I][/U][/B]));
}
The doctorList appears red and it says the symbol cant be resolved.
Where are you getting the doctorList ArrayList? The ArrayList needs to be declared and initialised before you can pass it to the adapter.
TechTev said:
Where are you getting the doctorList ArrayList? The ArrayList needs to be declared and initialised before you can pass it to the adapter.
Click to expand...
Click to collapse
doctorList is declared and initialized in another activity ..
Code:
private DrawerLayout mDrawerLayout;
private Button pButton = null;
private ActionBarDrawerToggle mToggle;
private int noOfDoctors;
public ArrayList<String> doctorList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_first_screeen);
pButton = (Button) findViewById(R.id.goTODocList);
pButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i = new Intent (view.getContext(),Doctor_List.class);
startActivity(i);
final String url = <link>;
final JsonArrayRequest getDocList = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onResponse(JSONArray response) {
try {
JSONArray docList = new JSONArray(response);
JSONObject docRow;
noOfDoctors = docList.length();
for (int i=0; i<noOfDoctors; i++) {
docRow = docList.getJSONObject(i);
doctorList.add(i,docRow.getString("name"));
}
Toast.makeText(PatientFirstScreen.this, "Hi brother.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PatientFirstScreen.this, "List of Doctors can't be retrieved right now. Please try later.", Toast.LENGTH_SHORT).show();
//what to do with error
}
}
);
MySingleton.getInstance(PatientFirstScreen.this).addToRequestQueue(getDocList);
}}
);
I see. What you need to do is pass the ArrayList as an Extra to the activity. To do this you need to call startActivity after you've done your JSONArray request. Here's an example of what that might look like:
First activity
Code:
private DrawerLayout mDrawerLayout;
private Button pButton = null;
private ActionBarDrawerToggle mToggle;
private int noOfDoctors;
public ArrayList<String> doctorList = new ArrayList<>();
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_first_screeen);
pButton = (Button) findViewById(R.id.goTODocList);
pButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
final String url = <link>;
final JsonArrayRequest getDocList = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@override
public void onResponse(JSONArray response) {
try {
JSONArray docList = new JSONArray(response);
JSONObject docRow;
noOfDoctors = docList.length();
for (int i=0; i<noOfDoctors; i++) {
docRow = docList.getJSONObject(i);
doctorList.add(i,docRow.getString("name"));
}
Toast.makeText(PatientFirstScreen.this, "Hi brother.", Toast.LENGTH_SHORT).show();
// Call start activity here as it depends on the docList.
Intent i = new Intent (view.getContext(),Doctor_List.class);
// Put the String Array List as an extra.
i.putStringArrayListExtra(Doctor_List.EXTRA_DOC_LIST, docList);
startActivity(i);
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PatientFirstScreen.this, "List of Doctors can't be retrieved right now. Please try later.", Toast.LENGTH_SHORT).show();
//what to do with error
}
}
);
MySingleton.getInstance(PatientFirstScreen.this).addToRequestQueue(getDocList);
}}
);
Doctor List Activity
Code:
private ListView docList;
// Key for the extra you are passing to the activity.
public static final String EXTRA_DOC_LIST = "your.package.name.Doc_List.extra_doc_list";
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doctor__list);
docList = (ListView) findViewById(R.id.docList);
// Get the doctor list extra
ArrayList<String> doctorList = getIntent.getStringArrayListExtra(EXTRA_DOC_LIST);
// The Adapter should now work
docList.setAdapter(new ArrayAdapter<String>(Doctor_List.this, android.R.layout.simple_list_item_1, doctorList));
}
TechTev said:
I see. What you need to do is pass the ArrayList as an Extra to the activity. To do this you need to call startActivity after you've done your JSONArray request. Here's an example of what that might look like:
First activity
Code:
private DrawerLayout mDrawerLayout;
private Button pButton = null;
private ActionBarDrawerToggle mToggle;
private int noOfDoctors;
public ArrayList<String> doctorList = new ArrayList<>();
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_first_screeen);
pButton = (Button) findViewById(R.id.goTODocList);
pButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
final String url = <link>;
final JsonArrayRequest getDocList = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@override
public void onResponse(JSONArray response) {
try {
JSONArray docList = new JSONArray(response);
JSONObject docRow;
noOfDoctors = docList.length();
for (int i=0; i<noOfDoctors; i++) {
docRow = docList.getJSONObject(i);
doctorList.add(i,docRow.getString("name"));
}
Toast.makeText(PatientFirstScreen.this, "Hi brother.", Toast.LENGTH_SHORT).show();
// Call start activity here as it depends on the docList.
Intent i = new Intent (view.getContext(),Doctor_List.class);
// Put the String Array List as an extra.
i.putStringArrayListExtra(Doctor_List.EXTRA_DOC_LIST, docList);
startActivity(i);
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PatientFirstScreen.this, "List of Doctors can't be retrieved right now. Please try later.", Toast.LENGTH_SHORT).show();
//what to do with error
}
}
);
MySingleton.getInstance(PatientFirstScreen.this).addToRequestQueue(getDocList);
}}
);
Doctor List Activity
Code:
private ListView docList;
// Key for the extra you are passing to the activity.
public static final String EXTRA_DOC_LIST = "your.package.name.Doc_List.extra_doc_list";
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doctor__list);
docList = (ListView) findViewById(R.id.docList);
// Get the doctor list extra
ArrayList<String> doctorList = getIntent.getStringArrayListExtra(EXTRA_DOC_LIST);
// The Adapter should now work
docList.setAdapter(new ArrayAdapter<String>(Doctor_List.this, android.R.layout.simple_list_item_1, doctorList));
}
Click to expand...
Click to collapse
Thanks. But, the arraylist is now accepted in the adapter but now, the button has stopped responding. Looks like the intent is not working now. I can't go the next page.
pk0486 said:
Thanks. But, the arraylist is now accepted in the adapter but now, the button has stopped responding. Looks like the intent is not working now. I can't go the next page.
Click to expand...
Click to collapse
I just checked the code I posted and I made a couple of typos and I think as the activity start call is from within the listener it needs to be Patient_First_Screen.this.startActivity(i).
Try this code:
Code:
private DrawerLayout mDrawerLayout;
private Button pButton = null;
private ActionBarDrawerToggle mToggle;
private int noOfDoctors;
public ArrayList<String> doctorList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_first_screeen);
pButton = (Button) findViewById(R.id.goTODocList);
pButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
final String url = <link>;
final JsonArrayRequest getDocList = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onResponse(JSONArray response) {
try {
JSONArray docList = new JSONArray(response);
JSONObject docRow;
noOfDoctors = docList.length();
for (int i=0; i<noOfDoctors; i++) {
docRow = docList.getJSONObject(i);
doctorList.add(i,docRow.getString("name"));
}
Toast.makeText(PatientFirstScreen.this, "Hi brother.", Toast.LENGTH_SHORT).show();
// Call start activity here as it depends on the docList.
Intent i = new Intent (view.getContext(),Doctor_List.class);
// Put the String Array List as an extra.
i.putStringArrayListExtra(Doctor_List.EXTRA_DOC_LIST, doctorList);
Patient_First_Screen.this.startActivity(i);
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PatientFirstScreen.this, "List of Doctors can't be retrieved right now. Please try later.", Toast.LENGTH_SHORT).show();
//what to do with error
}
}
);
MySingleton.getInstance(PatientFirstScreen.this).addToRequestQueue(getDocList);
}}
);
TechTev said:
I just checked the code I posted and I made a couple of typos and I think as the activity start call is from within the listener it needs to be Patient_First_Screen.this.startActivity(i).
Try this code:
Code:
private DrawerLayout mDrawerLayout;
private Button pButton = null;
private ActionBarDrawerToggle mToggle;
private int noOfDoctors;
public ArrayList<String> doctorList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_first_screeen);
pButton = (Button) findViewById(R.id.goTODocList);
pButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
final String url = <link>;
final JsonArrayRequest getDocList = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onResponse(JSONArray response) {
try {
JSONArray docList = new JSONArray(response);
JSONObject docRow;
noOfDoctors = docList.length();
for (int i=0; i<noOfDoctors; i++) {
docRow = docList.getJSONObject(i);
doctorList.add(i,docRow.getString("name"));
}
Toast.makeText(PatientFirstScreen.this, "Hi brother.", Toast.LENGTH_SHORT).show();
// Call start activity here as it depends on the docList.
Intent i = new Intent (view.getContext(),Doctor_List.class);
// Put the String Array List as an extra.
i.putStringArrayListExtra(Doctor_List.EXTRA_DOC_LIST, doctorList);
Patient_First_Screen.this.startActivity(i);
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PatientFirstScreen.this, "List of Doctors can't be retrieved right now. Please try later.", Toast.LENGTH_SHORT).show();
//what to do with error
}
}
);
MySingleton.getInstance(PatientFirstScreen.this).addToRequestQueue(getDocList);
}}
);
Click to expand...
Click to collapse
Still the same issue .. Can you please explain what is the issue with the code? I didn't understand why did you modify the code?
pk0486 said:
Still the same issue .. Can you please explain what is the issue with the code? I didn't understand why did you modify the code?
Click to expand...
Click to collapse
Sure, I moved the call to start the activity into the JSON response listener as that's when the doctorList is populated which we need to pass to the next activity. As that is in an anonymous inner class it needs to call the instance of the outer class using OuterClassName.this . However you have two inner classes so that's probably why it isn't working.
Maybe try moving the startActivity(i) call and intent creation to below the call to MySingleton.getInstance(PatientFirstScreen.this).addToRequestQueue(getDocList);
TechTev said:
Sure, I moved the call to start the activity into the JSON response listener as that's when the doctorList is populated which we need to pass to the next activity. As that is in an anonymous inner class it needs to call the instance of the outer class using OuterClassName.this . However you have two inner classes so that's probably why it isn't working.
Maybe try moving the startActivity(i) call and intent creation to below the call to MySingleton.getInstance(PatientFirstScreen.this).addToRequestQueue(getDocList);
Click to expand...
Click to collapse
Got it. Thanks. You were right. But there was some issue with my JSONArray because of which the loop wasn't getting executed. Resolved it now. Thanks again!
pk0486 said:
Got it. Thanks. You were right. But there was some issue with my JSONArray because of which the loop wasn't getting executed. Resolved it now. Thanks again!
Click to expand...
Click to collapse
No problem. Good luck with the rest of your project.
TechTev said:
No problem. Good luck with the rest of your project.
Click to expand...
Click to collapse
Now, I am stuck again. I changed my arraylist to custom array list. I have created the custom array adapter and its fine. I got my JSONArray which I parsed and created the required ArrayList. But when I use this ArrayList as an argument for the custom array adapter, it gives the below error.
https://ibb.co/hhYqOG - this is the link for screenshot of error
Code:
List<DocRow> doctors = new ArrayList<>();
After this, I have assigned values to this ArrayList.
Code:
DocAdapter adapter = new DocAdapter(getApplicationContext(), R.layout.doc_row, doctors);
docList.setAdapter(adapter);
Below is the adapter constructor
Code:
public DocAdapter(@NonNull Context context, @LayoutRes int resource, ArrayList<DocRow> doctors) {
super(context, resource, doctors);
this.context = context;
this.resource = resource;
this.doctors = doctors;
inflater = LayoutInflater.from(context);
What am I missing? Thanks.
pk0486 said:
Now, I am stuck again. I changed my arraylist to custom array list. I have created the custom array adapter and its fine. I got my JSONArray which I parsed and created the required ArrayList. But when I use this ArrayList as an argument for the custom array adapter, it gives the below error.
https://ibb.co/hhYqOG - this is the link for screenshot of error
Code:
List<DocRow> doctors = new ArrayList<>();
After this, I have assigned values to this ArrayList.
Code:
DocAdapter adapter = new DocAdapter(getApplicationContext(), R.layout.doc_row, doctors);
docList.setAdapter(adapter);
Below is the adapter constructor
Code:
public DocAdapter(@NonNull Context context, @LayoutRes int resource, ArrayList<DocRow> doctors) {
super(context, resource, doctors);
this.context = context;
this.resource = resource;
this.doctors = doctors;
inflater = LayoutInflater.from(context);
What am I missing? Thanks.
Click to expand...
Click to collapse
I think it's because you've specifically asked for an arrayList instead of a List as an argument for your custom adapter constructor. Try changing your constructor for the adapter to this:
Code:
public DocAdapter(@NonNull Context context, @LayoutRes int resource, List<DocRow> doctors) {
super(context, resource, doctors);
this.context = context;
this.resource = resource;
this.doctors = doctors;
inflater = LayoutInflater.from(context);

Get all information from Android Room Database based on ID

In database Note have id, title and description. I'm passing id from Mainactivity in to the NoteInfoActivity and into the NoteInfoActivity I'd like to get title and description from room database based on that id. What should I add into the NoteInfoActivity? Your help will be appreciated.
NoteDao
Code:
@Dao
public interface NoteDao {
@Insert
void insert(Note note);
@Update
void update(Note note);
@Delete
void delete(Note note);
@Query("DELETE FROM note_table")
void deleteAllNotes();
@Query("SELECT * FROM note_table ORDER BY priority")
LiveData<List<Note>> getAllNotes();
@Query("SELECT * FROM note_table WHERE id =:noteID")
List<Note> getNote(long noteID);
MainActivity
Code:
public class MainActivity extends AppCompatActivity {
private NoteViewModel noteViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final NoteAdapter adapter = new NoteAdapter();
recyclerView.setAdapter(adapter);
noteViewModel = new ViewModelProvider(this).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>() {
@Override
public void onChanged(@Nullable List<Note> notes) {
adapter.setNotes(notes);
}
});
adapter.setOnItemClickListener(new NoteAdapter.OnItemClickListener() {
@Override
public void onItemClick(Note note) {
Intent intent = new Intent(MainActivity.this, NoteInfoActivity.class);
intent.putExtra("NoteID", note.getId());
startActivity(intent);
}
});
}
}
NoteInfoActivity
Code:
public class NoteInfoActivity extends AppCompatActivity {
private static final String TAG = "NoteInfoActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note_info);
TextView textViewTitle = findViewById(R.id.textViewNoteTitle);
TextView textViewPriority = findViewById(R.id.textViewPriority);
Intent intent = getIntent();
if (intent != null && intent.hasExtra("NoteID")) {
long noteID = intent.getIntExtra("NoteID", -1);
Log.d(TAG, "onCreate: Note Id Is " + noteID);
} else {
Toast.makeText(getApplicationContext(), R.string.empty_not_saved, Toast.LENGTH_SHORT).show();
}
}
}

Categories

Resources