I have one activity/java file (Browsefile.java) that would obtain the absolute path of the file. I want to pass this information to another java file for further processing (Sqlitefun.java). In the first stage, I just want to make sure the variable of file path is passed from Browsefile.java to Sqlitefun.java so I just create an alertdialog in the Sqlitefun.java file to test it. However, I have some issue on the context of the alertdialog object.
(As Sqlitefun.java would further perform i/o and Sqlite processing tasks, I prefer to put this in another file.)
Here are the codes for the files:
Browsefile.java
public class Browsefile extends ListActivity {
....
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.browsefile);
findViews();
getDir(root);
}
....
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
File file = new File(path.get(position));
if (file.isDirectory())
{
if(file.canRead())
{
getDir(path.get(position));
}
else
{
selectpath = file.getAbsolutePath();
fpath.setText(selectpath);
}
}
else
{
selectpath = file.getAbsolutePath();
fpath.setText(selectpath);
}
}
private Button.OnClickListener importcsv = new Button.OnClickListener() {
public void onClick(View v) {
Sqlitefun firstClass = new Sqlitefun();
firstClass.getsAlertDialog(selectpath);
}
};
....
}
Sqlitefun.java
public class Sqlitefun {
private Context context;
public void getsAlertDialog(String filepath) {
new AlertDialog.Builder(context)
.setMessage(filepath)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.show();
}
}
I have tried to use this, Sqlitefun.this to replace context in the line new AlertDialog.Builder(context) but none of this works. (Eclipse said The constructor AlertDialog.Builder(Sqlitefun) is undefined and did not allow me to compile. The above code did not have any error and allow me to compile, but there is a nullpointer exception for the Context.
I believe you need to show dialogs from the Activity you are currently in, so you would need to the put AlertDialog code in BrowserFile.
I'm not sure if this would work, but you could try passing the context from BrowserFile to SqliteFun and showing it there.
Additionally, if you're not set on using an AlertDialog, trying using a Toast notification instead. They generally do better when used outside of an Activity.
Edit: I don't think the following is the best way to implement what you are trying to do, but here is a code sample I wrote
In SqliteFun, modify your method as such:
public void getsAlertDialog(String filepath, Context mContext) {
new AlertDialog.Builder(mContext)
.setMessage(filepath)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
})
.show();
}
Then from your Activity, use this:
private Button.OnClickListener importcsv = new Button.OnClickListener() {
public void onClick(View v) {
Sqlitefun firstClass = new Sqlitefun();
firstClass.getsAlertDialog(selectpath, v.getContext());
}
};
Try this:
private Context context = getApplicationContext()
You need to give contex from activity you execute this method. So I suggest you to add constructor to Sqlitefun class and when you create object of this class add context to arguments.
There is something wrong in your app design.
You cannot really show a Dialog from another class than an activity class (well, you can, but it's very dangerous because the activity context can change anytime. For example when the device is rotated your app will crash because the activity context changed, since in Sqlitefun your reference still points to the old context).
So you should find another way to show your dialog. For example, you can create some getters to retrieve the values to show on your AlertDialog, and create it inside your activity.
First create a static variable in Sqlitefun.java.
Static String path;
After that you can access this variable from any class so you can directly store that path from Browse.class
Ex: You got the fullpath="XXXX" in browse.class. To store the fullpath variable in Sqlitefun.java use:
Sqlitefun.path=fullpath;
Related
I'm very new to Android, and have a basic question. I need at certain points to display a user notification in a dialog box, which they can simply acknowledge with the OK button.
I'm using:
myActivity.runOnUiThread(new Runnable() {
public void run() {
AlertDialog alertDialog = new AlertDialog.Builder(myContext).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage("My message");
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
});
This works well in the Main program, but within a called method it needs the Activity and the Context from the main program. Can anybody tell me how to pass these? getApplicationContext() seems to be acceptable, but I can't figure out how to pass the Activity.
Better still of course would be to get the parent Context and Activity within the method, but I can't get that to work either.
I'd be grateful for any help.
-update 10/07/21
Rahul has given me the solution to the problem I posed: how to pass in the Activity and Context.
The problem is that the dialog still doesn't show.
I found a variation online as follows:
AlertDialog.Builder builder = new AlertDialog.Builder(myContext);
builder.setTitle("Alert")
.setMessage("My message")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
but this doesn't work either.
I'm puzzled that such a common and simple task needs so much code. In the desktop languages I'm used to it can be done in a single line.
So my titled question stands, but can anyone see where the code is faulty?
Many thanks
You can either pass activity to the class when initializing the object or you can pass activity when calling the function.
Case 1 (Recommended)
Pass Activity when calling the function:
MyObj myObj = new MyObj();
myObj.showDialog(myValue, ActivityName.this);
Where function will look like this:
public void showDialog(int myValue, Activity activity){
...
}
Then you can use this activity instance inside the method.
Case 2
Pass Activity when initializing the object:
MyObj myObj = new MyObj(ActivityName.this);
Where Class will look like this:
class MyObj{
private Activity thisActivity;
public MyObj(Activity activity){
thisActivity = Activity;
}
...
}
Then you can use this activity instance.
When you have activity object available you can replace context object with it.
I'm trying to create a custom class for displaying a Yes/No AlertDialog, but I want to onClick handler to be in the activity that instantiates the custom class. So far, the custom class looks like this:
public class YesNoDialog {
private Context gContext = null;
private DialogInterface.OnClickListener onClickListener;
private AlertDialog alertDialog = null;
public YesNoDialog(Context context,
DialogInterface.OnClickListener listener) {
this.gContext = context;
this.onClickListener = listener;
}
public void ShowDialog() {
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(this.gContext);
alertDialogBuilder.setTitle("Hello World");
alertDialogBuilder
.setMessage("Are you sure?")
.setCancelable(false)
.setPositiveButton("Yes",this.onClickListener)
.setNegativeButton("No",this.onClickListener);
alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
My thinking was to pass the context and onClick handler to the object in the constructor, then assign the handler to the .setPositive and .setNegative buttons.
I implemented the DialogInterface.OnClickListener in my MainActivity class:
public class MainActivity
extends AppCompatActivity
implements DialogInterface.OnClickListener {
And created the onClick handler in MainActivity that should be called when either the Yes or No buttons are clicked in the dialog.
#Override
public void onClick(DialogInterface dialog, int id) {
Log.d("DIALOG RETURNS ID=", Integer.toString(id));
dialog.dismiss();
}
I'm not sure if I'm on the right track or not, but I got stuck in trying to figure out how I would now pass the onClick handler to the YesNoDialog object. I've tried several variations of this:
YesNoDialog dialog = new YesNoDialog(this, MainActivity.onClick);
With no success (won't compile). I have also tried passing only the context, assuming that maybe that's all I really need for .setPositive and .setNegative button handlers, but that didn't work either...this calls require a DialogInterface.OnClickListener.
It feels like I'm close, but I can't get over the hurdle. Can anyone help me connect the dots?
Create a class (DialogUtils) and add this method in it.
public static void showPopUp(Context context
, String title
, String msg
, String positiveBtnTxt
, String negativeBtnTxt
, DialogInterface.OnClickListener positiveBtnListener
, DialogInterface.OnClickListener negativeBtnListener){
final AlertDialog errorDialog;
AlertDialog.Builder errorDialogBuilder = new AlertDialog.Builder(context, R.style.NativeDialogue);
errorDialogBuilder.setTitle(title);
errorDialogBuilder.setMessage(msg);
errorDialogBuilder.setPositiveButton(positiveBtnTxt, positiveBtnListener);
errorDialogBuilder.setNegativeButton(negativeBtnTxt, negativeBtnListener);
errorDialog = errorDialogBuilder.create();
errorDialog.show();
}
Call the method like this :
DialogUtils.showPopUp(this, "title", "message", "positive btn name", "Negative Btn name", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
"Your action"
}
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
"Your action"
}
});
This is described in the official documentation on dialogs in Android. In short, you need to do the following steps:
Create a DialogFragment for your dialog so it is properly restored when the device rotates or changes the configuration in some other way.
Create an interface which will allow you to send the result of the dialog.
Implement this interface in the activity.
Cast the activity to the interface inside the DialogFragment in onAttach and store it in some field. Don't forget to set to null in onDetach.
When a dialog button is clicked, you can call the appropriate interface method, and the activity will get the result.
Alternatively, if you only ever use this dialog with one activity, you may not declare an interface and simply store a reference to the activity.
Hey you can make one method in your MainActivity class. Like below.
public void onClickOnYesButton(int id){
}
Pass the MainActivity reference like below.
public YesNoDialog(MainActivity context) {
this.gContext = context;
}
And call the onClickOnYessButton by using the MainActivity reference!
Job done!
i've already implemented this thing in my application using activity,
refer image link below
"http://imgur.com/LuErJjY"
in the first part you can see the context=PerformanceActivity#4015
but in the 2nd part it is null
the code i've used is
IN ACTIVITY:
viewHolder.nextReview.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int d=v.getId();
((PerformanceActivity)context).performReview(v.getId());
}
});
IN FRAGMENT:
NOTE: PerformanceFragment pf;
viewHolder.nextReview.setId(resData.get(position).getTestID());
viewHolder.nextReview.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int d=v.getId();
((PerformanceFragment)pf).performReview_frag(v.getId());
}
});
Both the methods are methods present in the adapter of a listview. In Activity It just works fine, but not in fragment.
Links to both adapters:
https://pastee.org/28chw - Fragment's Adapter https://pastee.org/nw8rr
- Fragment
https://pastee.org/wxepy -Activity's Adapter
At last this worked for me -
PerformanceFragmentAdapter adapter = new PerformanceFragmentAdapter(context,rsuData,device,this);
and adding this to the adapter as
private PerformanceFragment pf;
public PerformanceFragmentAdapter(Context conte, ArrayList<ResultData> rData,
int device, PerformanceFragment pp) {
super();
context = conte;
resData = rData;
size = device;
pf=pp;
}
guess #ursgtm is right. still confusing between Context c=getActivity(); and this keyword
In PerformanceFragmentAdapter class :
PerformanceFragment pf;
You are just creating a object with no instance and you are using that object as context,and you are not assigning anything to pf .
Instead of remove pf, and pass the context which you got from constructor:
viewHolder.nextReview.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int d=v.getId();
//Replace ((PerformanceFragment)pf) with context
context.performReview_frag(v.getId()); //you obtained context from contractor.
}
});
Hope this helps you !
In second part use getActivity() method if your fragment PerformanceFragment is associated with your activity PerformanceActivity
viewHolder.nextReview.setId(resData.get(position).getTestID());
viewHolder.nextReview.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int d=v.getId();
/* (getActivity()). no need to use content if
performReview_frag() is present in PerformanceFragment fragment*/
// this will call performReview_frag() method
performReview_frag(v.getId());
}
});
Else,
You can use getBaseContext() method to get correct context
I am trying to create an application with a widget. When the user places the widget on the desktop a listview should come up with a list of items. The user selects an item then the widget is created with the respective text related to that item. I thought I should do this by showing a dialog in the Service but it throws me
Caused by: android.view.WindowManager$BadTokenException: Unable to add
window -- token null is not for an application
to the dialog_newitem.show(); line. For simplicity I am using now a simple alertdialog.
Is it the way to do this? I haven't found anyhing about this on the net.
public class UpdateWidgetService extends Service {
private static final String LOG = "de.vogella.android.widget.example";
public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget";
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
String value;
Dialog dialog_newitem;
EditText et_newitem;
#Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this, "UpdateWidgetService", Toast.LENGTH_SHORT).show();
dialog_newitem = new Dialog(this); //I tried UpdateWidgetService.this, too
dialog_newitem.setContentView(R.layout.dialog_productlists_grp_capitalized);
dialog_newitem.setTitle("Select");
dialog_newitem.setCancelable(true);
et_newitem = (EditText) dialog_newitem.findViewById(R.id.et_item_name);
Button btn_Save = (Button) dialog_newitem.findViewById(R.id.btn_save_pr);
btn_Save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
value = et_newitem.getText().toString();
}
});
Button btn_Cancel = (Button) dialog_newitem.findViewById(R.id.btn_cancel_pr);
btn_Cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog_newitem.dismiss();
}
});
dialog_newitem.show(); //error
Toast.makeText(this, "value: " + value, Toast.LENGTH_SHORT).show();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I have used this alertdialog in some other part of the code, and there it is working fine. I think it has something to do with the service.
You can't show a dialog in the service.
if you really want to show a dialog.
try to start an Activity and set the Activity's Theme to Theme.Dialog.
There is a demo in The ApiDemo Project
I know this thread is old, but thought it would be worth contributing anyway for future sufferers.
Although most will say its not recommended to launch dialogs directly from a service, the following workaround works for me. Use the ServiceDialogBuilder class below to build your AlertDialog. Unlike the AlertDialog.Builder, this will work with a Service context and show() can be called directly from a service without having to start a new activity.
Just be wary that this is a bit of a hack, so there may well be some unintended side effects from doing this.
Hope this helps
public class ServiceDialogBuilder extends AlertDialog.Builder {
public ServiceDialogBuilder(Context context) {
super(context);}
#Override
public AlertDialog create() {
AlertDialog dialog=super.create();
//Change dialog window type from TYPE_CHANGED to TYPE_SYSTEM_ALERT
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
return dialog;
}
#Override
public AlertDialog show() {
return super.show();
}}
Just make sure your dialog's window is set to SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
public class DialogWithInputBox extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final AlertDialog.Builder alert = new AlertDialog.Builder(this);
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString().trim(); // important line!
Toast.makeText(getApplicationContext(), value, Toast.LENGTH_SHORT).show();
return value;
}
});
alert.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
alert.show();
}
Above code gives a dialog with ok and cancel button. There is a local variable value. I want to pass this to another method. when I put a return + local variable, it is asking me to change onclickevent listener type.
Well, yes, you can't return a value from a method whose return type is void. You have two choices:
If you need this value to stay around for a while, you can make value a field of your Activity, and just set it in your click handler. Then you can refer to it from other methods in the Activity.
If you only need to use it temporarily, then pass value as an argument to the other method you need to call, directly from your click handler.
This is a pure java issue. You could pass a value to class members
public class DialogWithInputBox extends Activity {
private String dest;
..
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dest = input.getText().toString().trim();
..
You can't change the return type of a method.
It is totally unclear what you expect by returning an value.
Return to whom?? What should be done with that string?
The caller would get the value but the caller (the positive button) does not expect anything
The code you have given to us, just tells the positive button to call method onClick.
And the button will do that but nothing more. The button does not know anything at all how your onClick method is implemented.
The only way is to set a member var or to call a method with that value.