Android: Passing back user input from DialogFragment results in NullPointerException - java

so i looked at the Android tutorial for Dialogs Link.
And Decided to make a custom Dialog to ask a user for a host, username and password to connect to. I dont want to connect to the host within the Dialog Class so i need to pass the strings back to the main activity. I tried to to that with an Interface just like in the tutorial but when i want to handle the event in the main activity accessing the EditText i get a NullPointerException. Im sure there is an easy workaround or Im making some other stupid mistake. Please help!
Dialog Class:
public class ConnectionDialog extends DialogFragment {
public interface NoticeDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
NoticeDialogListener mListener;
// Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = (NoticeDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString()
+ " must implement NoticeDialogListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
final LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(inflater.inflate(R.layout.connection_dialog, null))
// Add action buttons
.setPositiveButton(R.string.connect, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
mListener.onDialogPositiveClick(ConnectionDialog.this);
// sign in the user ...
}
})
.setNegativeButton(R.string.abort, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mListener.onDialogNegativeClick(ConnectionDialog.this);
//LoginDialogFragment.this.getDialog().cancel();
}
});
return builder.create();
}
}
And Main Activity:
public class MainActivity extends FragmentActivity implements ConnectionDialog.NoticeDialogListener {
public void showConnectionDialog() {
// Create an instance of the dialog fragment and show it
DialogFragment dialog = new ConnectionDialog();
dialog.show(getFragmentManager(), "Connection Dialog");
}
public void toast(String message){
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, message, duration);
toast.show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
EditText editHost = (EditText)dialog.getView().findViewById(R.id.dialog_host);
EditText editUser = (EditText)dialog.getView().findViewById(R.id.dialog_user);
EditText editPassword = (EditText)dialog.getView().findViewById(R.id.dialog_password);
String host = editHost.getText().toString();
String user = editUser.getText().toString();
String password = editPassword.getText().toString();
dialog.dismiss();
}
#Override
public void onDialogNegativeClick(DialogFragment dialog) {
toast("cancled");
dialog.dismiss();
// User touched the dialog's negative button
}
public void connect(View view){
showConnectionDialog();
}
}
Thanks a lot!
Edit:
NullPointerException
04-12 18:52:00.278 5216-5216/com.example.josias.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.josias.myapplication, PID: 5216
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at com.example.josias.myapplication.MainActivity.onDialogPositiveClick(MainActivity.java:44)
at com.example.josias.myapplication.ConnectionDialog$2.onClick(ConnectionDialog.java:54)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:153)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Yes You can.
Your interface will look like this,
public interface NoticeDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
}
Pass DialogFragment instance like this to the interface, in positive button onClick () method.
.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
noticeDialogListener.onDialogPositiveClick(NoticeDialog.this);
}
})
Next in your MainActivity - you can have every field of DialogFragment that you have displayed as forms. In interface method that you will override in MainActivity, define like this,
#Override
public void onSaveButtonClick(DialogFragment dialog) {
......
EditText field1= (EditText) dialog.getDialog().findViewById(R.id.field1);
EditText field2= (EditText) dialog.getDialog().findViewById(R.id.field2);
....
}
Then you can get the Text and work as per your requirement. For more information you can refre this one: https://www.youtube.com/watch?v=a0T--DfR48A Here everything is explained well...

Switch out your interfaces to pass the String values instead of passing along the entire dialog.
To get you started, do something like this
public interface NoticeDialogListener {
public void onDialogPositiveClick(String host, String user, String pass);
public void onDialogNegativeClick();
}
final LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View dialogView = inflater.inflate(R.layout.connection_dialog, null);
final EditText editHost = (EditText)dialogView.findViewById(R.id.dialog_host);
final EditText editUser = (EditText)dialogView.findViewById(R.id.dialog_user);
final EditText editPassword = (EditText)dialogView.findViewById(R.id.dialog_password);
builder.setView(dialogView)
// Add action buttons
.setPositiveButton(R.string.connect, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
String host = editHost.getText().toString();
String user = editUser.getText().toString();
String pass = editPassword.getText().toString();
mListener.onDialogPositiveClick(host, user, pass);
}
})
// set null to dismiss dialog
.setNegativeButton(R.string.abort, null);
return builder.create();

You should use:
dialog.getDialog()
instead of:
dialog.getView()

Related

Android's AlertDialog in fragment

I have an app that uses tabbed activity, with 3 tabs, each with a separate fragment and layout. Tab3 has some user-profile settings, like a name for example. Name is displayed inside a cardview, so I made that cardview clickable, and onClick it would open an alertDialog with an edit text to enter the name. to build this dialog I found 2 methods.
First:- (this is run once the cardview is clicked(On clicklistener)) and its working very well and I have no issues with it but it just doesn't feel like a best-practice
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
alert.setTitle("Enter your Username");
LayoutInflater inflater = getActivity().getLayoutInflater();
View view1 = inflater.inflate(R.layout.editname_layout, null);
alert.setView(view1);
final EditText input = view1.findViewById(R.id.editname);
alert.setPositiveButton("Save", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
textView.setText(input.getText().toString());
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
Second:- is that I build a separate DialogFragment with an interface to send data back to fragment this one feels like a best practice but i have faced many issues with it, such as.. when data is sent back to my fragment, I can't use the method "textView.setText" on the received data as I receive it outside the onCreateView method and thus textView always returns null.
public class Dialog extends AppCompatDialogFragment {
private Context context;
public DialogListener listener;
public Dialog(Context context) {
this.context = context;
}
#NonNull
#Override
public android.app.Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.name_layout, null);
final EditText name = (EditText) view.findViewById(R.id.editname);
builder.setView(view)
.setTitle("Username")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("Save", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String text = name.getText().toString();
listener.data(text);
Toast.makeText(getActivity(), "Saved", Toast.LENGTH_SHORT).show();
}
});
return builder.create();
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
try {
Fragment fragment = new Tab3();
listener = (DialogListener) fragment;
}
catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement d.l");
}
}
public interface DialogListener {
void data(String name);
}
}
So what I'm thinking is that I should go with the first method as it's easier, and it's easier to extract text from it but still not sure if it would be a good practice.
thanks in advance!
Prefer second solution:
You can have your custom UI elements.
You have access to lifecycle changes (onResume,onCreate,etc.).
It keeps showing even when orientation is changed (the first solution doesn't).
And for sending data to previous fragment you can create listener to fragment.
interface MyFragmentListener {
fun onSendBackData(data: Any)
}
class MyFragment:Fragment {
private var listener: MyFragmentListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
listener = when {
context is MyFragmentListener -> context
parentFragment is MyFragmentListener -> parentFragment as MyFragmentListener
else -> error("You should implement MyFragmentListener")
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
button.setOnClickListener {
listener?.onSendBackData("Data")
}
}
}
class Activity : Activity(), MyFragmentListener {
override fun onSendBackData(data:Any) {
textView.text = data.toString()
}
}
It's not a question of best practice, it's just how you want to design your App.
The first solution: You can directly interact with your UI. e.g: Set the new value in textView. But if you write a lot of dialogs, think about to generify the logic (the second solution).
The second solution: If you want just a generic Dialog, you need the use-case for it = multiple calls for dialogs and don't forget: if you instantiate the Dialog class you need to give him the textView if you want to change it in the UI

How to avoid android application crash, when setOwnerActivity(Activity activity) in custom DialogFragment causes nullpointerException?

I got a very strange exception while using Sharedpreferences and DialogFragment:
Unable to start activity ComponentInfo{com.example.barta1.site_patrol/com.example.barta1.site_patrol.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method
'void android.app.Dialog.setOwnerActivity(android.app.Activity)'
on a null object reference -
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2679)
I really do not have a clue what causes this error, but after this happened, I never be able to start
my application again, it continuosly crashed with the same exception above. The MainActivity is my launching activity in my application with a DialogFragment attached which I use to login users. I show this dialogfragment if the users not logged in (the "logged in" status saved in a sharedpreference object).
My MainActivity is like this:
public class MainActivity extends AppCompatActivity implements LoginDialogFragment.NoticeDialogListener {
//...
private LoginDialogFragment dialogFragment;
SharedPreferences pref;
SharedPreferences.Editor edit;
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pref = getSharedPreferences("Globals", MODE_PRIVATE);
edit = pref.edit();
boolean isloggedin = pref.getBoolean("Loggedin", false);
if (!isloggedin) {
//if not logged in show the login dialog
showLoginDialog();
}
else {
//... doing some network calls...
}
}
public void showLoginDialog() {
dialogFragment = new LoginDialogFragment();
dialogFragment.show(getFragmentManager(), "LoginDialogFragment");
}
/***
* Network calls if dialog dismissed
* Login dialog can only be closed if logging in is successful
* (if loginname and password matches).
*/
#Override
public void onDismiss() {
//... some network related jobs
}
}
And here is the fragment class:
public class LoginDialogFragment extends DialogFragment {
public interface NoticeDialogListener{
void onDismiss();
}
NoticeDialogListener mListener;
Activity activity;
AlertDialog dialog;
SharedPreferences pref;
SharedPreferences.Editor edit;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
activity = (Activity) context;
mListener = (NoticeDialogListener) activity;
pref = activity.getSharedPreferences("Globals", MODE_PRIVATE);
edit = pref.edit();
} catch (ClassCastException e){
throw new ClassCastException(activity.toString() + "must implement NoticeDialogListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String username = pref.getString("Username", null);
if(username==null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_signin, null);
final AutoCompleteTextView actv_username = view.findViewById(R.id.username);
final EditText password = view.findViewById(R.id.password);
dialog = new AlertDialog.Builder(new ContextThemeWrapper(getContext(), R.style.AlertDialogCustom))
.setView(view)
.setTitle("Bejelentkezés")
.setPositiveButton("OK", null)
.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialogInterface) {
final Button button = ( dialog).getButton(AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String passw = password.getText().toString();
String user = actv_username.getText().toString();
try {
if (user.length() < 4 || passw.length() < 4) {
Toast.makeText(getContext(), "Too short user/pass.", Toast.LENGTH_SHORT).show();
dialog.show();
} else {
//login to account, if success dismiss.
login(user, passw, dialog);
}
} catch (Exception e) {
e.printStackTrace();
}
// dialog.dismiss();
}
});
}
});
dialog.setCanceledOnTouchOutside(false);
// set the DialogFragment to make the dialog unable to dismiss with back button
// (because not working if called on the dialog directly)
this.setCancelable(false);
return dialog;
} // end of - if username == null.
return null;
}
public void login(final String username, String password, final AlertDialog dialog){
//... some network call
//... if successful:
// edit.putString("Username", username);
// edit.commit();
// edit.putBoolean("Loggedin", true);
// edit.commit();
// dialog.dismiss();
// dialog.setOnShowListener(null);
//
// else
// Toast.makeText(getContext(),"Wrong login credentials",
// Toast.LENGTH_SHORT).show();
}
#Override
public void onDismiss(DialogInterface dialog) {
mListener.onDismiss();
dismissAllowingStateLoss();
}
After reinstalling the package, I could not recreate this exception (even when I killed app process, and start it from the recent apps), end users somehow managed to do this and that time, restarting the application was an instant crash (see the exception above.). It looks like parent activity becomes null somehow ( possible after saving the state and after cannot recover).
How to avoid this in the future? Is there a simple way to deal with this situation?
It would be also a great help if someone can explain to me when this "setOwnerActivity(Activity activity)" from the android library called, that way maybe I can identify what went wrong.
Thanks for any help.
As Mike M. stated out,
You cannot return null from onCreateDialog(). That's too late to be canceling or aborting the Dialog showing.
And the username check before creating the fragment will obviously solve the problem. Also, the LoggedIn field looks redundant now.

Returning Data from a Dialog Fragment to the Activity that Called It

Hey fellow stackoverflowers!!!
I'm wondering what the best way to pass a string taken from a Dialog Fragment based on user input on the Dialog into the main activity which called the string?
Here's my specific example but it's really long so if you don't feel like going through it don't worry about everything below.
Here's my source code, I've ommitted the imports n stuff
public class GroupNameFragment extends AppCompatDialogFragment {
private EditText edittGroupName;
public static String GROUP_NAME = "com.example.mashu.walkinggroup.controller - groupName";
// When the views are inflated, get access to them
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
edittGroupName = Objects.requireNonNull(getView()).findViewById(R.id.edittGroupName);
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get reference to fragment's layout
View view = LayoutInflater.from(getActivity())
.inflate(R.layout.group_name_layout, null);
// OK button listener
DialogInterface.OnClickListener listener = (dialog, which) -> {
if (which == DialogInterface.BUTTON_POSITIVE) {
// If OK pressed, create bundle to be accessed in OnDismissListener in MapActivity,
// which contains the groupName user inputted
String groupName = edittGroupName.getText().toString();
Bundle bundle = new Bundle();
bundle.putString(GROUP_NAME, groupName);
setArguments(bundle);
}
};
// Build alert dialog
return new AlertDialog.Builder(getActivity())
.setTitle("Choose your Group Name!")
.setView(view)
.setPositiveButton(android.R.string.ok, listener)
.create();
}
// Extracts groupName from the bundle set up in the onClickListener above
public static String getGroupName(GroupNameFragment dialog) {
Bundle bundle = getArguments();
return bundle.getString(GROUP_NAME);
}
}
What I attempted to do was to this: First, I get access to the EditText that the user will type in their response. Then I set the Dialog Listener for the OK button which creates a bundle using the setArguments function which contains the groupName when the user is done, which will be accessed in the other activity later on by using the static getGroupName function. Here's the function in the main activity which creates the Dialog and sets the onDismissListener
private void createGroupNameDialog() {
// Instantiate Dialog
// Support Fragment Manager for backwards compatibility
FragmentManager manager = getSupportFragmentManager();
GroupNameFragment dialog = new GroupNameFragment();
dialog.show(manager, "GroupNameDialog");
// OnDismissListener callback function to be run whenever dialog dismissed.
dialog.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
// Update groupName based on what user inputted and update marker name at origin
groupName = GroupNameFragment.getGroupName(dialog);
originMarker.setTitle(groupName);
}
});
}
I think the problem is in groupName = GroupNameFragment.getGroupName(dialog). I feel like theres a better way to get the bundle here, and it seems weird to use the function as static and then pass in specific instance of GroupNameFragment in order to get the bundle (wouldn't that instance be gone by then since it's being used in the "OnDismiss"?). Also, the app crashes the second createGroupNameDialog is called, but it doesn't crash and actually opens the dialog window if I comment out the OnDismissListener, so I'm sure the problems in there somewhere but I don't know why it crashes before the dialog box even opens since OnDismiss happens AFTER the user dismisses the Dialog Box.
Thanks!!!
I accomplished passing variables back using an interface and listeners. I'll show you how I handled it (although I used a DialogFragment, this should still work for AlertDialogs, and in this example I passed an integer, not a string, but it would work for any data type).
public class DialogFragmentOtherMedia extends DialogFragment {
int dialogResult;
//The interface is important!
public interface YesNoListener {
void onYesOtherMedia(int output);
void onNoOtherMedia(int output);
}
//Checking for ClassCastException is nice here.
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof YesNoListener)) {
throw new ClassCastException(activity.toString() + " must implement YesNoListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
dialogResult = 0;
final String mediaType[] = {getString(R.string.Ringtones),getString(R.string.Music),getString(R.string.Alarms)};
return new AlertDialog.Builder(getActivity())
.setTitle(getString(R.string.Select_Other_Media_Type))
.setSingleChoiceItems(mediaType, dialogResult, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Log.d("DialogFragmentOtherMedia.onCreateDialog","Item clicked: " + mediaType[which]);
dialogResult = which;
}
})
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Casting the activity to YesNoListener is very important here!
//You'll register the listener in the activity later, by implementing the interface.
((YesNoListener) getActivity()).onYesOtherMedia(dialogResult);
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Same thing for your other callbacks.
((YesNoListener) getActivity()).onNoOtherMedia(dialogResult);
}
})
.create();
}
}
Then you just need to implement it in your activity where you called the dialog from:
public class AlarmDetailsActivity extends Activity
DialogFragmentOtherMedia.YesNoListener {
//All of your activity stuff here...
#Override
public void onYesOtherMedia(int result) {
Log.i("Tag", "onYes Result: " + result);
}
#Override
public void onNoOtherMedia(int result) {
Log.i("Tag", "onNo Result: " + result);
}
}
Sorry about all of the random strings and extra alert dialog. I just wanted to show some actual working code from my app. I tried to add comments next to the important stuff. Hope this helps!

getSharedPreferences error in non-activity class

I realize this issue has been touched on numerous times but nothing I try is working for me. I still get errors when trying to access SharedPreferences.
From the main Activity (McsHome) I am launch a variety of Dialogs to help the user add a location.
The first Dialog is below, this simply pops up a message stating a location needs to be added (PopupMessage.java):
public class PopupMessage extends DialogFragment {
String message = "";
AddLocation addLocation;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
addLocation = new AddLocation();
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(message)
.setPositiveButton("Add Location", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
addLocation.show(getFragmentManager(), "PopupMsgFragment");
}
})
.setNegativeButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//
};
});
// Create the AlertDialog object and return it
return builder.create();
}
}
This gives the user an option to add a location, when that button is clicked another dialog pops up (AddLocation.java):
public class AddLocation extends DialogFragment {
EditText mcsDomain;
EditText friendlyName;
EditText password;
ProcessLocation addLoc;
String message = "";
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View layout = inflater.inflate(R.layout.add_location_dialog, null); // Pass null as the parent view because its going in the dialog layout
mcsDomain = (EditText) layout.findViewById(R.id.mcsDomain);
friendlyName = (EditText) layout.findViewById(R.id.friendlyName);
password = (EditText) layout.findViewById(R.id.password);
builder.setView(layout)
.setTitle("Add/Update Location")
// Add action buttons
.setPositiveButton("Add/Update", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// Passes the chosen location parameters to the ProcessLocation class
addLoc.processLocation(mcsDomain.getText().toString(),friendlyName.getText().toString(),password.getText().toString());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
The AddLocation.java uses an XML layout which includes 3 EditText fields. The values of these are passed on to a third Class, ProcessLocation.java which includes the method processLocation().
public class ProcessLocation {
SharedPreferences domainToName;
SharedPreferences nameToDomain;
public void processLocation(String domain, String name, String password) {
domainToName = getSharedPreferences("domainToName", MODE_PRIVATE);
nameToDomain = getSharedPreferences("nameToDomain", MODE_PRIVATE);
// final Editor domainEdit = domainToName.edit();
// final Editor nameEdit = nameToDomain.edit();
if (nameToDomain.contains(name)) {
System.out.println("Name Doesn't Exist");
}
}
}
I'm getting an error on the MODE_PRIVATE, I believe related to Context. I've been playing around with context for hours with no luck (or understanding). I know I'm popping up a couple of dialogs in a row. If I add "extends Activity" the error goes away but then the app crashes when trying to getSharedPreferences.
From going through the other posts I'm sure it's to do with passing the context from my McsHome.java activity but everything I've tried has failed.
First of all, in AddLocation you declare the member variable addLoc, but you never assign it to anything. If you did get this to compile, it would throw a NullPointerException here:
addLoc.processLocation(mcsDomain.getText().toString(), friendlyName.getText().toString(),
password.getText().toString());
getSharedPreferences() is a method of the Context class. In ProcessLocation.processLocation() you are trying to call it. This method doesn't exist in the ProcessLocation class.
You need to do the following:
1) ProcessLocation needs to have a Context reference, so that it can call getSharedPreferences(). The easiest way to do this is to declare a member variable in ProcessLocation of type Context and have it initialized in the constructor of ProcessLocation. Like this:
public class ProcessLocation {
Context context;
SharedPreferences domainToName;
SharedPreferences nameToDomain;
// Constructor
ProcessLocation(Context context) {
this.context = context;
}
2) You need to create an instance of ProcessLocation. In AddLocation, before using the variable addLoc you will need to initialize it. Like this:
// Create instance of ProcessLocation and pass it the activity (Activity is a Context)
addLoc = new ProcessLocation(getActivity);
3) Use the Context in ProcessLocation.processLocation(), like this:
public void processLocation(String domain, String name, String password) {
domainToName = context.getSharedPreferences("domainToName", Context.MODE_PRIVATE);
nameToDomain = context.getSharedPreferences("nameToDomain", Context.MODE_PRIVATE);
...
}
It is late and I'm tired and I didn't put this through a compiler, so please forgive me if I left out a comma or a semicolon or spelled something wrong. Hopefully you get the drift. Good luck!

Want to use the same function in every class

I am developing an android application. Now i have created one function which create custom dialog box and i want this dialog box to display on every activity. So i need to call this function at every activity. But as the syntax of custom dialog (e.g. Dialog d = new Dialog(home.this)).home is the name of the activity where i have created the function so i am not ale to use this function in any other activity. And i haven't use android that much. So give me good example to solve my problem. Here is my code
here is sample code code of using AlertDialog in all activity.
crate one class file like as allmethod.java
and add this code in that class
public static void showAlert(Activity act,String msg)
{
AlertDialog.Builder alert = new AlertDialog.Builder(act);
alert.setMessage(msg).setPositiveButton("OK", new OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which)
{
}
}).show();
}
and you can use from any class like as
allmethod.showAlert(Activity,"Message");
In your case..
public void SearchDialog(Context ctx){
final Dialog dialog = new Dialog(ctx);
dialog.setContentView(R.layout.dialogsearch);
dialog.setTitle(" Enter The Text to Search");
dialog.setCancelable(true);
final EditText Text = (EditText) dialog.findViewById(R.id.EdText);
Button buttonOK = (Button) dialog.findViewById(R.id.btnOK);
buttonOK.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String SearchText = Text.getText().toString();
prefsPrivate =getSharedPreferences(Login.PREFS_PRIVATE,Context.MODE_PRIVATE);
Editor prefsPrivateEdit=prefsPrivate.edit();
prefsPrivateEdit.putString("Text",SearchText);
prefsPrivateEdit.commit();
Intent i = new Intent(ctx,SearchTask.class);
startActivity(i);
dialog.cancel();
}
});
Button buttonCancel = (Button) dialog.findViewById(R.id.btnCancel);
buttonCancel.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialog.cancel();
}
});
dialog.show();
}
Just add a Context parameter to your SearchDialog() constructor.
Make it like this:
public SearchDialog(Context context){
//....
}
You could either define your own Interface and implement for every class, or make the main Activity method static (as long as it wont need to access anything in dynamic objects that aren't method arguments).
final class Uutil {
public void static func() {
}
}
then do it in your classes:
class A {
public void f() {
Uutil.func();
}
}

Categories

Resources