i want to pass tow values from activity to AsyncTask class and send them from Background process to SOAP web service , but it return my null or wrong , i'm sure there is something wrnog in passing value from LoginActivity to AsyncTask .
here is my LoginActivity code :
final EditText LoginId = (EditText) findViewById(R.id.IDLogin);
final EditText LoginPass = (EditText) findViewById(R.id.LoginPass);
contextOfApplication = getApplicationContext();
mPrefs = getSharedPreferences(PREFS, 0);
boolean rememberMe = mPrefs.getBoolean("rememberMe", false);
final String login1 = LoginId.getText().toString();
final String pass1 = LoginPass.getText().toString();
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(LoginActivity.this);
prefs.edit().putString("login1", login1).commit();
prefs.edit().putString("password1", pass1).commit();
here is calling and passing activity context to AsyncTask Constractor :
loginBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ProgressDialog progressDialog = new ProgressDialog(
LoginActivity.this);
progressDialog.setMessage("جاري تسجيل الدخول الرجاء الانتظار");
progressDialog.show();
AsyncTaskWebServiceCaller MyTask = new AsyncTaskWebServiceCaller(
LoginActivity.this, progressDialog,
getApplicationContext());
MyTask.execute();
}
});
my FULL AsyncTask code :
public class AsyncTaskWebServiceCaller extends AsyncTask<Void, Void, String> {
Activity mActivity;
Context context;
LoginActivity MyClass = new LoginActivity();
public static Context contextOfApplication;
ProgressDialog progressDialog;
Context applicationContext = LoginActivity.getContextOfApplication();
// Constractor
public AsyncTaskWebServiceCaller(Activity activity,
ProgressDialog progressDialog, Context context) {
super();
this.progressDialog = progressDialog;
this.mActivity = activity;
this.context = context;
}
// BackGround Process
#Override
protected String doInBackground(Void... voids) {
// this is executed in a background thread.
// the result is returned to the UI thread via onPostExecute
try {
final String NAMESPACE = "http://ws.sams.com";
final String URL = "http://88.198.82.92:8080/sams1/services/LoginActvityWs?WSDL"; // usint
// //
// localhost
final String METHOD_NAME = "login";
final String SOAP_ACTION = "http://ws.sams.com/login";
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
final HttpTransportSE androidHttpTransport = new HttpTransportSE(
URL);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext);
String user = prefs.getString("login1", null);
String pass = prefs.getString("password2", null);
to pass values to AsyncTask subclass you either :
1- pass them throw a constructor :
class MyTask extends AsyncTask<Void,Void,Void>{
MyObject myObject = null;
public MyTask(MyObject myObject){
this.myObject = myObject;
}
//....
2- pass it in the execute() method parameters :
// your code on the Main thread which will call the execute() method
// ....
new MyTask().execute(myObject); // i dont remember the exact name of this method, any way
and snippets from your AsyncTask subClass will be
class MyTask extends AsyncTask<Void,MyObject,Void>{
#Override
public void doInBackGround(MyObject...params){
MyObject myObject = params[0];
// the rest of your code
}
just put in mind that if you want to do or edit any thing that is running on the UI thread, you
cant do it in the "doInBackground()" method, either on the preExecute() or the postExecute(), or
run it in a Runnable object (inside the doInBackground() method) but by calling runOnUI(myRunnable);
hope this helps, and just i cant remember the methods name for now, just CTRL + SPACE will help on your IDE :D
you are already doing it in your constructor
AsyncTaskWebServiceCaller MyTask = new AsyncTaskWebServiceCaller(
LoginActivity.this, progressDialog,
getApplicationContext());
thats passing values there
also you are passing the context twice LoginActivity.this gives you context and activity so you do not need to use getApplicationContext(). Its recommended that you never use getApplicationContext() really
Edit:
if you want context all you have to do is
public AsyncTaskWebServiceCaller(Context context,ProgressDialog progressDialog) {
super();
this.progressDialog = progressDialog;
this.context = context;
}
you do not need the activity
to use shared preferences all you need to do is
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
Related
I have a spinner consisting of the languages in the IBM library. I want the user to select a language and translate the text into the selected language. I got the value from spinner but I don't know how to pass the value to the target language. Please help.
`enter code here`Spinner s = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, languages);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s.setAdapter(adapter);
text = s.getSelectedItem().toString(); // value from spinner
new Hey().execute();
}
class Hey extends AsyncTask<Void, Void, String> {
String text;
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... voids) {
IamAuthenticator authenticator = new IamAuthenticator("nAh_Z_0X2AS1Vun2MI3UR3lYNRivFRkWaNsZyFwELMul"); //key
LanguageTranslator languageTranslator = new LanguageTranslator("2018-05-01", authenticator);
languageTranslator.setServiceUrl("https://api.eu-gb.language-translator.watson.cloud.ibm.com/instances/83f66689-1c94-4a9b-b595-e2d776f10ded"); //url
TranslateOptions translateOptions = new TranslateOptions.Builder()
.addText("Hello")
.source(Language.ENGLISH)
.target(Language.SPANISH) // need to get user to select the target language from the spinner option
.build();
TranslationResult result = languageTranslator.translate(translateOptions) //translation happens
.execute().getResult();
String som = result.toString();
System.out.println(som);
return som;
}
First You need to understand how could you pass the value as a parameter to the AsyncTask. So after taking the value from spinner pass it to AsyncTask parameter.
Your code will look like this:
text = s.getSelectedItem().toString(); // value from spinner
new Hey().execute(text);
Now in the AsyncTask you will retrieve the passed parameter:
class Hey extends AsyncTask<Void, Void, String> {
String text;
#Override
protected String doInBackground(Void... voids) {
String language = (String) params[0]; //can use it further
TranslateOptions translateOptions = new TranslateOptions.Builder()
.addText("Hello")
.source(Language.ENGLISH)
.target(language) // Do check the input format for this and do required conversion
.build();
}
}
Disclaimer: I am a newbie to Android development :)
How can I pass the string values collected from this first class to the class below? I attempted this but only got null values.
Here's my main activity.
public class Register extends AppCompatActivity {
protected SnapToSellDataSource mDataSource;
public String sFullname;
public String sEmail;
public String sMobileNumber;
public String sPassword;
EditText full_name, email, mobile_number, pwd, copwd;
Button registerButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
mDataSource = new SnapToSellDataSource(Register.this);
full_name = (EditText) findViewById(R.id.editText);
email = (EditText) findViewById(R.id.editText2);
mobile_number = (EditText) findViewById(R.id.editText3);
pwd = (EditText) findViewById(R.id.editText4);
copwd = (EditText) findViewById(R.id.editText5);
registerButton = (Button) findViewById(R.id.button);
registerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Register register = new Register();
String editPassword = pwd.getText().toString();
String editConfirmPassword = copwd.getText().toString();
if(editPassword.equals(editConfirmPassword)) {
//This isn't overwriting the null class variables I
//instantiated so that I can pass them to the class below
sFullname = full_name.getText().toString();
sEmail = email.getText().toString();
sMobileNumber = mobile_number.getText().toString();
sPassword = pwd.getText().toString();
mDataSource.insertUser(register);
}
}
});
}
}
Here's the class that should receive the string values:
public class SnapToSellDataSource {
private SQLiteDatabase mDatabase;
private SnapToSellHelper mHelper;
private Context mContext;
public SnapToSellDataSource(Context context){
mContext = context;
mHelper = new SnapToSellHelper(mContext);
}
public void insertUser(Register register){
ContentValues values = new ContentValues();
values.put(SnapToSellHelper.COL_NAME, register.sFullname);
values.put(SnapToSellHelper.COL_EMAIL, register.sEmail);
values.put(SnapToSellHelper.COL_NUMBER, register.sMobileNumber);
values.put(SnapToSellHelper.COL_PASSWORD, register.sPassword);
mDatabase.insert(SnapToSellHelper.TBL_USERS, null, values);
}
}
I attempted to getText, getString from the second class but my app crashed maybe since the widgets were not yet assigned ids at the class level. Passing actual string values encased in quoation marks ("") works so it means the DatabaseHelper is properly set up.
I also tried declaring class variables and assigning the widget values to them but kept getting the "Cannot resolve symbol" error.
How you get a read from the local variables and pass them to the class variables that can then be set as public and read by another class; in this case, the second class?
You can not simply create instances of an activity in Android. Activities are not classes that you just do a “new” on and call their constructor. An instance of an Activity is created when the app starts or when an Intent starts an activity.
So doing this: Register register = new Register(); is not good! You can find good arguments here
Instead you can pass those values as parameters to the insertUser(params...) method or create a new User class and instantiate it with those string values and pass it to insertUser(user) method.
Method call:
mDataSource.insertUser(sFullname, sEmail, sMobileNumber, sPassword);
Method definition:
public void insertUser(String sFullname, String sEmail, String sMobileNumber, String sPassword) {
ContentValues values = new ContentValues();
values.put(SnapToSellHelper.COL_NAME, sFullname);
values.put(SnapToSellHelper.COL_EMAIL, sEmail);
values.put(SnapToSellHelper.COL_NUMBER, sMobileNumber);
values.put(SnapToSellHelper.COL_PASSWORD, sPassword);
mDatabase.insert(SnapToSellHelper.TBL_USERS, null, values);
}
I have problem to pass context from Activity to Adapter.
I am calling my sharedpreference like this:
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(ctx);
String userObject = pref.getString(key, null);
And this one need context, so i am using : getApplicationContext()
But this not work in the Adapter (RecyclerView), is there someone facing the same issue ?
Adding the adapter into the Manifest file will solve the problem ? (Just a suggestion)
I am not sure what you are asking but here is a solution that I can think of.
Pass the context of the calling activity in your adapter through constructor and then use that context.
Context ctx;
public YourAdapter(Context ctx){
this.ctx = ctx;
}
now in your adapter you can do this
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(ctx);
String userObject = pref.getString(key, null);
In your adapter create constructor with Context like this,
public AdapterList(Context ctx){
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(ctx);
String userObject = pref.getString(key, null);
}
and create it by passing
adapter = new YourAdapter(getApplicationContext());
I suggest you to separate your preference-managing code into singleton class so you can get access to the preferences anywhere, just like this
public class SharedPreferenceManager {
private static final SharedPreferenceManager ourInstance = new SharedPreferenceManager();
public static SharedPreferenceManager getInstance() {
return ourInstance;
}
private SharedPreferenceManager() {
}
private SharedPreferences preferences;
public void init(Context ctx) {
preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
}
public String getValueByKey(String key) {
return preferences.getString(key, "");
}..other functions....}
you should call the SharedPreferenceManager.getInstance().init(this) in your onCreate() in the activity
and after you can get access to SP wherever you want: SharedPreferenceManager.getInstance().getValueByKey("somekey")
I'm getting NPE when I try to instantiate a class, I already tried using NameOftheClass.this, getApplicationContext(), getApplication(). None of those is working, here is the log:
java.lang.NullPointerException
at br.com.FragmentClientes.<init>(FragmentClientes.java:87)
line 87 is: mRepositorio = new Repositorio(FragmentClientes.this);
And here is the snippet:
public class FragmentClientes extends ActionBarActivity {
private boolean searchCheck;
private List<ClienteModel> clientes = new ArrayList<ClienteModel>();
private ProgressBar progressBar;
private ListView lv;
private ClientViewAdapter ad;
private ClientViewAdapter ads;
private SearchView searchView;
private LinearLayout footerLinearLayout;
private boolean shouldExecuteOnResume;
private Repositorio mRepositorio;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO Auto-generated method stub
setContentView(R.layout.fragment_cliente);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
SecurePreferences mSessao = new SecurePreferences(FragmentClientes.this, "sessao");
mSessao.put("menuAtual", "Clientes");
lv = (ListView) findViewById(R.id.listaClientes);
}
public FragmentClientes(Integer idViagem) {
clientes = new ArrayList<ClienteModel>();
try {
mRepositorio = new Repositorio(FragmentClientes.this);
List lista = mRepositorio.getClientesViagem(idViagem);
clientes = lista;
ad = new ClientViewAdapter(FragmentClientes.this, this, clientes);
lv.setVerticalFadingEdgeEnabled(true);
lv.setVerticalScrollBarEnabled(true);
lv.setAdapter(ad);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Do not use an activity context inside its constructor, it will now work. Please put all the code from the constructor into a method and call it inside the `onCreate method like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO Auto-generated method stub
setContentView(R.layout.fragment_cliente);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
SecurePreferences mSessao = new SecurePreferences(FragmentClientes.this, "sessao");
mSessao.put("menuAtual", "Clientes");
Integer idViagem = getIntent().getIntExtra(TAG, -1);
init(idViagem);
}
public void init(Integer mId) {
clientes = new ArrayList<ClienteModel>();
try {
mRepositorio = new Repositorio(FragmentClientes.this);
List lista = mRepositorio.getClientesViagem(mId);
clientes = lista;
ad = new ClientViewAdapter(FragmentClientes.this, this, clientes);
lv.setVerticalFadingEdgeEnabled(true);
lv.setVerticalScrollBarEnabled(true);
lv.setAdapter(ad);
} catch (Exception e) {
e.printStackTrace();
}
}
Also, you will need to find another way of passing the integer parameter.
For this, use Intent.putExtra(TAG, idViagem) on the intent which starts the activity and then retrieve the value in the constructor with getIntent().getIntExtra(TAG, -1)
For example if you're starting FragmentClientes activity from another activity:
Intent intent = new Intent(this, FragmentClientes.class);
intent.putExtra("idViagem", int_value_of_id_that_you_passed_through_constructor);
startActivity(intent);
Dont create Parameteriged Activity Constructor
just init your data in Activity Call back methods like onCreate(),onResume()
Start your Activity Using Intent
For more read Activity doc Activity Documnetation
FragmentClientes is an Activity. You should not define a custom counstructor, since the method onCreate behaves as constructor and will be called automatically by the system.
so put you code into onCreate method.
Important: you should never, i mean realy never call new FragmentClientes(1);
It might be because yout ListView is not properly instantiated
private ListView lv;
You never asign (in the code you provided) any instantiation for the object.
I'm trying to create an AsyncTask for the 1st time, but I don't have much luck.
My AsyncTask needs to get some information from a server and then add new layouts to the main layout to display this information.
Everything seems to be more or less clear but, the error message "MainActivity is not an enclosing class" is bothering me.
Nobody else seems to have this problem, so I think I miss something very obvious, I just don't know what it is.
Also, I'm not sure if I used the right way to get the context, and because my application doesn't compile so I can't test it.
Your help is much appreciated.
Here is my code:
public class BackgroundWorker extends AsyncTask<Context, String, ArrayList<Card>> {
Context ApplicationContext;
#Override
protected ArrayList<Card> doInBackground(Context... contexts) {
this.ApplicationContext = contexts[0];//Is it this right way to get the context?
SomeClass someClass = new SomeClass();
return someClass.getCards();
}
/**
* Updates the GUI before the operation started
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
/**
* Updates the GUI after operation has been completed
*/
protected void onPostExecute(ArrayList<Card> cards) {
super.onPostExecute(cards);
int counter = 0;
// Amount of "cards" can be different each time
for (Card card : cards) {
//Create new view
LayoutInflater inflater = (LayoutInflater) ApplicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewSwitcher view = (ViewSwitcher)inflater.inflate(R.layout.card_layout, null);
ImageButton imageButton = (ImageButton)view.findViewById(R.id.card_button_edit_nickname);
/**
* A lot of irrelevant operations here
*/
// I'm getting the error message below
LinearLayout insertPoint = (LinearLayout)MainActivity.this.findViewById(R.id.main);
insertPoint.addView(view, counter++, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
}
}
Eclipse is probably right, and you are trying to access a class (MainActivity) that is inside it's own file from another class that is in its own file (BackgroundWorker) . There is no way to do that - how is one class supposed to know about the other's instance magically? What you can do:
Move the AsyncTask so it is an inner class in MainActivity
Pass off your Activity to the AsyncTask (via its constructor) then acess using activityVariable.findViewById(); (I am using mActivity in the example below) Alternatively, your ApplicationContext (use proper naming convention, the A needs to be lowercase) is actually an instance of MainActivity you're good to go, so do ApplicationContext.findViewById();
Using the Constructor example:
public class BackgroundWorker extends AsyncTask<Context, String, ArrayList<Card>>
{
Context ApplicationContext;
Activity mActivity;
public BackgroundWorker (Activity activity)
{
super();
mActivity = activity;
}
//rest of code...
As for
I'm not sure if I used the right way to get the context
It is fine.
Above example is inner class, here is standalone class...
public class DownloadFileFromURL extends AsyncTask<String, String, String> {
ProgressDialog pd;
String pathFolder = "";
String pathFile = "";
Context ApplicationContext;
Activity mActivity;
public DownloadFileFromURL (Activity activity)
{
super();
mActivity = activity;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(mActivity);
pd.setTitle("Processing...");
pd.setMessage("Please wait.");
pd.setMax(100);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setCancelable(true);
pd.show();
}
#Override
protected String doInBackground(String... f_url) {
int count;
try {
pathFolder = Environment.getExternalStorageDirectory() + "/YourAppDataFolder";
pathFile = pathFolder + "/yourappname.apk";
File futureStudioIconFile = new File(pathFolder);
if(!futureStudioIconFile.exists()){
futureStudioIconFile.mkdirs();
}
URL url = new URL(f_url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lengthOfFile = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream());
FileOutputStream output = new FileOutputStream(pathFile);
byte data[] = new byte[1024]; //anybody know what 1024 means ?
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lengthOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return pathFile;
}
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pd.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String file_url) {
if (pd!=null) {
pd.dismiss();
}
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(new File(file_url)), "application/vnd.android.package-archive" );
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(i);
}
}