Retrieving String From Java Class - java

I am fairly new to java / android programming and have mostly been following tutorials / reading. I have 2 classes called MainActivity and Homeactivity, the MainActivity is where the user logs in and HomePageactivity is opened via intent if the login is correct.
The username is passed through an edit text to which i have used the following code in the main class
String CurrentUser = editTextusername.getText().toString();
public String GetCurrentUser ()
{
return CurrentUser;
}
And this in the homepage class
MainActivity testing = new MainActivity();
String x = testing.GetCurrentUser();
CurrentUserName.setText(x);
This seems like it should work to me, how ever when launching my application it just crashes, and without the lines of code in the main activity it works fine
Any ideas as to what im doing wrong here guys

The String may be null during setting to TextView check before setting to textView
String CurrentUser = editTextusername.getText().toString();
public String GetCurrentUser ()
{
if(currentUser.length>0&&currentUser!="")
return CurrentUser;
else return "empty";
}
String x = testing.GetCurrentUser();
CurrentUserName.setText(""+x);

You can use intent to carry info from one Activity to another.
Read this: Intents
It is quite easy to transfer strings and primitive data types via intent, using putExtra() .
Some example code to make it more clear:
//this runs, for example, after a button click
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("username", userName);
startActivity(intent);
At the other end you can take them as like this:
String username = getIntent().getStringExtra("username");

Related

Getter returning null in different class

while making an Android app, I have ran in the following problem:
My MainActivity looks like this:
...
private String token;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
tokenSetter();
}
private void tokenSetter() {
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Log.w("TRAZENITOKEN", "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = Objects.requireNonNull(task.getResult()).getToken();
setToken(token);
Log.d("TRAZENITOKEN", "onGetToken: " + token);
// Log and toast
// Log.d("TRAZENITOKEN", "onComplete: " + token);
});
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
I know that the token value is being set as in an another method inside this MainActivity class, when I call getToken(), I get the value.
However, when I try to call getToken from an another Activity, something like this:
...
button.setOnClickListener(view -> {
FirebaseActions firebaseActions = new FirebaseActions();
MainActivity mainActivity = new MainActivity();
//firebaseActions.setUserNameOnToken(editText.getText().toString());
if(mainActivity.getToken() != null) editText.setText(mainActivity.getToken());
else editText.setText("Skafiskafnjak");
});
(I opted for the editText.setText method for debugging purposes, I am going to use it in the commented way)
The code snippet above always goes to the else part as the getToken is null.
Why does it return null in this class, if it returns a value in it's own class?
Could it be perhaps because I did
MainActivity mainActivity = new MainActivity();
An answer would be appreciated.
Thanks in advance!
MainActivity mainActivity = new MainActivity();
This activity instance is not the same one that the Android system created where you see the token being set. Besides, we never create an activity with new. The Android system creates activities according to the activity lifecycle and your code must work within this structure. To pass data between activities, you need to send it in the Intent when you call startActivity(). See the documentation for an example of how to do this.
Creating new activity causes new instance of that activity, therefor a new token which would be null
Send the token through the intent as String data from your MainActivity, and then from the second Activity, grab that String data(token), and do with it whatever you want.
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("token", yourTokenValue);
startActivity(intent);
and in onCreate method of your SecondActivity,you can use getIntent().getStringExtra("token"); to retrieve the token value which was passed from the first Activity
String token= getIntent().getStringExtra("token");

Checking Azure connected Database onClick for login

So Azure spit the following code for me to insert into an activity (Android Studio is what I'm using)
Add the following line to the top of the .java file containing your launcher activity:
import com.microsoft.windowsazure.mobileservices.*;
Inside your activity, add a private variable
private MobileServiceClient mClient;
Add the following code the onCreate method of the activity:
mClient = new MobileServiceClient("https://pbbingo.azurewebsites.net", this);
Add a sample item class to your project::
public class ToDoItem{ public String id; public String Text;}
In the same activity where you defined mClient, add the following code:
ToDoItem item = new ToDoItem();
item.Text = "Don't text and drive";
mClient.getTable(ToDoItem.class).insert(item, new TableOperationCallback<item>(){
public void onCompleted(ToDoItem entity, Exception exception, ServiceFilter response)
{
if(exception == null){
//Insert Succeeded
} else {
//Insert Failed
}
}});
My goal is to create a login page. I understand that the above was probably offered up more with a ToList in mind. I just want to get the syntax correct today. The problem I think, is my basic class structure. I have created an OnClick Listener within my on create that gets the ID from a button in my layout. I don't need it checking for anything in the database until the button has been actually clicked to either login or register.
public class LoginClass extends AppCompatActivity{
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.MyLoginLayout);
MobileServiceClient mClient = null;
try {
mClient = new MobileServiceClient ("myAzureWebsite", "AzureKey", this);
} catch (MalformedURLException e) {
e.printStackTrace();
}
Button Attempt = (Button) findViewById (R.id.mySubmitButton);
final MobileServiceClient finalMClient = mClient; // finalized so I can use it later.
Attempt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
final View thisView = v;
final MyToDoItemClass item = new MyToDoItemClass();
In MyToDoItemClass I have two variables (Both String) Just left over from
the example of a ToDoList (they are String ID and String Text)
item.Text = "Filler";
item.ID = "Fill";
finalMClient.getTable(MyToDoItemClass.class).insert(new Table OperationCallback<item>() { //<--- I'm getting an error that the variable, item
is from an unknown class...
public void onCompleted (Item entity, Exception exception, ServiceFilterResponse response){
if(exception == null) {
Intent i = new Intent (LoginClass.this, MainActivity.class);
startActivity(i);
}else{
Toast.makeText(thisView.getContext(), "Failed", Toast.LENGTH_LONG).show();
}}
});
}
});
}}
The problem is with that the TableOperationCallback is saying that the item from MyToDoItemClass class is from an unknown class.
There are many issues in your code, as below.
According to the javadoc for class MobileServiceClient, there is not a method insert(TableOperationCallback<E> callback), so the code finalMClient.getTable(MyToDoItemClass.class).insert(new Table OperationCallback<item>() {...} is invalid.
The generics E in Table OperationCallback<E> means that you need to write a POJO class name instead of E, not an object variable name like item, so the correct code should be new Table OperationCallback<MyToDoItemClass>, please see the Oracle tutorial for Generics to know more details.
The figure below shows all methods insert of class MobileServiceClient. The bold word Deprecated under the method name means that you should not use it for developing on new project, it‘s only compatible for old project on the new version of Java SDK.
Please follow the offical tutorial to develop your app. Any concern, please feel free to let me know.

Null pointer exception when I pass data from another actitvty

I have a activity where you select a number in a spinner(dropdown-list in AndroidStudio) and sends it to a new activity/another class, before it is sent to a server. The array-adapter works fine, but using the getExtra Intent in the receiving activity is a lot of trouble for me.
The app crashes and logcat give this message:
NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Intent.getStringExtra(java.lang.String)' on a null object reference.
MainActivity.(MainActivity.java:76)
Line 76 in MainActivity String avd_nr= getIntent().getStringExtra("getData");
This is my code for passing the array value, and the line Log.i("data",avd); posts the spinner value(avd) in the logcat.
btnAvdeling.setOnClickListener(new View.OnClickListener()
{
final String avd = dropdown.getSelectedItem().toString();
#Override
public void onClick(View v)
{
Intent i = new Intent(getApplicationContext(), MainActivity.class);
i.putExtra("getData",avd.toString());
startActivity(i);
Log.i("data",avd);
}
}
This is my code where I receive data
String avd_nr= getIntent().getStringExtra("getData");
private SurveyResponse fillInResponsData(Integer answer) {
surveyResponse.setAvdeling(avd_nr);
return surveyResponse;
}
Please give some help on what i need to add or change
in onCreate() Method put the following :
String avd_nr =getIntent.getExtras("getData");
String avd_nr =getIntent.getExtras("getData");
Its should be on onCreate() method

Android: Logout system and the android lifecycle

on the weekend I started to build my first android app. As I need to ask the user of my app for user credentials [which are used for further webservice usage] I want to simulate a "login system". On the start of my app the user should be told to enter his credentials. When the user is inactive for too long I want to dismiss the entered credentials and to "log out" the user.
While coding and afterwards while testing I realized that the way I thought I could go doesn't work. After reading the docu and several SO-questions again and again I question myself more and more if I have understand the app / activity life cycle and its possibilites fully. So I wanted to ask for help in understand the life cycle and its linked influences on my app. So yes this might be several questions in one :/
For the moment my app consists of the following activities:
a search activity (which is opened once the app is started)
a settings acitivy (which can be accessed from the search dialog and has a link back to the search dialog)
After the user has entered an ID in the search dialog I want to open an activity regarding to the search result (NYI).
When starting to implement the user auth, my idea was the following:
Everytime onResume() of an activity is called I need to check a) if user credentials are already stored and b) if the last action of the user is less then X minutes ago. If one these fails I want to show a "log in panel" where the user can enter his credentials, which are then stored in the SharedPreferences. For that I did the following:
I first build an parent activity which has the check and a reference for the SharedPreferences in it
public class AppFragmentActivity extends FragmentActivity {
protected SharedPreferences sharedPref;
protected SharedPreferences.Editor editor;
protected String WebServiceUsername;
protected String WebServicePassword;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_appfragmentactivity);
}
#Override
protected void onResume () {
super.onResume();
// Check if user is "logged in".
// Meaning: Are there given user credentials and are they valid of was the user inactive for too long?
// We only do this "onResume" because this callback is the only one, which is called everytime an user
// starts/restarts/resumes an application
checkForUserCredentials();
// Set new "last action" now "now"
setLastAction(new Date().getTime());
}
#Override
protected void onStart () {
// Fill content
super.onStart();
// Set global sharedPreferences
sharedPref = this.getSharedPreferences(getString(R.string.FILE_settings_file), Context.MODE_PRIVATE);
}
/*
* Checks if user credentials are valid meaning if they are set and not too old
*/
private void checkForUserCredentials() {
long TimeLastAction = sharedPref.getLong(getString(R.string.SETTINGS_USER_LAST_ACTION), 0);
long TimeNow = new Date().getTime();
// Ask for User credentials when last action is too long ago
if(TimeLastAction < (TimeNow - 1800)) {
// Inactive for too long
// Set back credentials
setUsernameAndPassword("", "");
}
else
{
WebServiceUsername = sharedPref.getString(getString(R.string.SETTINGS_USER_USERNAME), "");
WebServicePassword = sharedPref.getString(getString(R.string.SETTINGS_USER_PASSWORD), "");
}
}
/*
* Saves the given last action in the sharedPreferences
* #param long LastAction - Time of the last action
*/
private void setLastAction(long LastAction) {
editor = sharedPref.edit();
editor.putLong(getString(R.string.SETTINGS_USER_LAST_ACTION), LastAction);
editor.commit();
}
/*
* Saves the given username and userpassword sharedPreferences
* #param String username
* #param String password
*/
private void setUsernameAndPassword(String username, String password) {
editor = sharedPref.edit();
editor.putString(getString(R.string.SETTINGS_USER_USERNAME), username);
editor.putString(getString(R.string.SETTINGS_USER_PASSWORD), password);
editor.commit();
WebServiceUsername = username;
WebServicePassword = password;
}
/*
* Method called when pressing the OK-Button
*/
public void ClickBtnOK(View view) {
// Save User-Creentials
EditText dfsUsername = (EditText) findViewById(R.id.dfsUsername);
String lvsUsername = dfsUsername.getText().toString();
EditText dfsPassword = (EditText) findViewById(R.id.dfsPassword);
String lvsPassword = dfsPassword.getText().toString();
if(lvsUsername.equals("") || lvsPassword.equals("")) {
TextView txtError = (TextView) findViewById(R.id.txtError);
txtError.setText(getString(R.string.ERR_Name_or_Password_empty));
}
else
{
// Save credentials
setUsernameAndPassword(lvsUsername, lvsPassword);
setLastAction(new Date().getTime());
// open Searchactivity
Intent intent = new Intent(this, SearchActivity.class);
startActivity(intent);
}
}
The "log in mask" is setContentView(R.layout.activity_appfragmentactivity);.
The two other activites I created are then extending this parent class. This is one of it:
public class SearchActivity extends AppFragmentActivity {
SearchFragment searchfragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
}
#Override
protected void onResume() {
super.onResume();
if(WebServiceUsername.equals("") && WebServicePassword.equals("")) {
// Username not set. Re"login".
Intent intent = new Intent(this, AppFragmentActivity.class);
startActivity(intent);
}
}
#Override
protected void onStart() {
super.onStart();
}
// ...
}
As far as I understand the lifecycle now this should work as the following: When my app starts (the SearchActivity is set for LAUNCH) the app should step into the onResume() of my parent class. There it sees that the credentials are not yet stored and opens the layout of the AppFragmentActivity which is the login. When entered, the user is redirected to the SearchActivity which now sees "ok credentials are there, lets move forward". But this doesnt't happen as the login is not shown up. So I think my onResume() might be wrong. Perhaps my full idea is bad? Up to here I thought I also understand the life cycle, but obviosly I don't?
I then had a look around on SO for similar problems. One thing I saw here was a comment to an user which wanted to build a similar "logout" mechanism as mine, that he has to implement this in every activity. I thought about that and ask myself "Why do I have to override the onResume() in every of my activites, when they are all from the same parent? When theres no onResume() in the child, the one of the parent should be called". The user in the SO-question was advised to use services as background threads to count down a timer in there for the logout. I then read the services article in the docu and then fully got disoriented:
There are two types of services: Started and bounded ones. A started service is once started by an activity and then runs in the background until hell freezes when it doesn't get stoped. So it's fully independed of any app, but the programmer has to / should stop it when it's not longer needed. A bounded services is bounded to one or many app components and stops when all bounded components end. I thought this might be a good alternative for me, but when I thought further I ask myself how: If one of my starts it (let's say the login dialog) and then is closed the service is stoped and the other activites always start there own ones which can't be the sense of it. So this service must be bounded not to any component but to my app. But whats the life cycle of an android app? How can I keep information "global" inside my app. I know I can switch data between actitivites using 'Intents'.
This more and more "foggy cloud" lead to ask myself: "Shall I use only one activity and try to switch in/out everything using fragments?"
So my questions are (I think that's all of them, but I'm not sure anymore):
Does my idea of writing an parent class which does the checks for all extended childs ok or bad AND does it work as I understood it?
Do I have to override every onResume() in the childs just to call the parent one for the checks?
Can you give me a tip why my "login systems" doesn't work?
What's the life cycle of an android app and how can I interact with it?
Shall I only use one activity and switch in/out everything using fragments or is it a good way to have several activities and some of them use fragments (to reuse often used parts)?
Thanks in advise
What I've done in the end is the following:
I removed the "login" thing from the parent class into a stand alone activity. This activity is called when the credentials are not valid together with an finish() of the calling one. So I don't build a loop and drop unused activites.

How can I start a new android activity using class name in a string?

I'm having a problem with an android application that I'm working on.
My application has several sections and the next screen that loads is based on a string. So, screen 1 of section 1 would be, S1S1.
My question is, how can I start an activity based on a string. I have S1S1 saved in a string, let us call it next activity. Rather than having to type S1S1.class, I need it to come from the string. I've tried everything I can think of and google hasn't helped much.
Some things I've tried are
Intent myIntent = new Intent(nextactivity);
Intent myIntent = new Intent(v.getContext(), getClass().getName().valueOf(nextactivity));
Intent myIntent = new Intent(v.getContext(), Class.forName(nextactivity));
and tried running with
startActivityForResult(myIntent, 0);
but nothing seems to work. Any ideas?
Here is a code by which you can start activity using the name of the activity
String activityToStart = "com.example.MainActivity";
try {
Class<?> c = Class.forName(activityToStart);
Intent intent = new Intent(this, c);
startActivity(intent);
} catch (ClassNotFoundException ignored) {
}
EDIT
Here class name will be full name of the class with the package name.
For example if your package name will be x.y.z and if you have Activity name called A then the full name of the Activity A will be x.y.z.A.
An even better way (and one that is used in the system to launch Browser.apk along with other apps that aren't bundled with AOSP):
Intent intent = new Intent();
intent.setClassName("com.android.browser","com.android.BrowserActivity");
context.startActivity(intent);
Alternatively, if you want to check that you can start the Activity from the command line, you can do something like this from your shell:
adb shell
am start com.android.browser/.BrowserActivity
I am not aware of solution but i have an alternative.. the way similar to div hide and show in web pages.
if your s1s1 is to loaded low content have them in a linearlayout and keep their visibility gone on loading form s1. when you click on s1 to reach s1s1 hide s1 and set the params of visibility to "visible".
By doing this you can avoid creating a separate activity and this way is also easy to navigate back.
Use Enums!
public enum SectionActivity {
S1S1(MyS1Activity.class),
S1S2(S2Activity.class);
private Class<? extends Activity> activityClass;
private SectionActivity(Class<? extends Activity> clazz) {
this.activityClass = clazz;
}
public Class<? extends Activity> getActivity {
return activityClass;
}
}
Then somewhere in your code:
SectionActivity act = SectionActivity.valueOf(string);
Intent intent = new Intent(this, act.getActivity());
startActivity(intent);

Categories

Resources