Why does this throw a 'null object reference' error? - java

I'm trying to pass a string from another activity to this one and then send it into an array and then into a listview. whenever i run this i get "Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference"
it seems like the error has something to do with the fourth line with the 'extras' bundle but how is that a null object reference i defined it right there no?
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Bundle extras = intent.getExtras();
switch(requestCode) {
case ACTIVITY_EDIT:
String title = extras.getString(add.TITLE);
String password = extras.getString(add.PASSWORD);
adapter.add(title);
break;
}
}
Here's where the 'PASSWORD' and 'TITLE' variables are defined in the other Activity:
public void onClick(View v) {
EditText titleBox = (EditText)findViewById(R.id.titleText);
TITLE = titleBox.getText().toString();
EditText passBox = (EditText)findViewById(R.id.passwdText);
String pass = passBox.getText().toString();
EditText confBox = (EditText)findViewById(R.id.editText3);
String conf = confBox.getText().toString();
if (pass.equals(conf)) {
PASSWORD = pass;
this.finish();
} else {
Toast.makeText(this, "Passwords don't match", Toast.LENGTH_SHORT);
}
}

When you pass data from one activity to another using a Bundle, the data is received inside onCreate() method of the second activity not inside onActivityResult() unless you've specifically implemented that.
Check this answer on how to start another activity and how to pass data to another activity : https://stackoverflow.com/a/20170125/1239966

Related

Passing bundle instance to place picker intent

I am working on an android app whose main purpose is to update the working location of the employees by admin. Now when I want to change/update the location of an employee from my recycler view(list of employees connected with my UserManagerAdapter), I have to pass the user name of that employee to the place picker intent so that when the admin pick the desired location, the database of that user will be changed accordingly.
My Steps(2 Steps)
I have passed the username to the place picker intent as bundle.
My UserManagerAdapter
holder.locationTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
launchPicker(data.get(position).getUserName());
}
});
private void launchPicker(String userName) {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
Bundle bundle = new Bundle();
bundle.putString(USERNAME,userName);
try {
fragment.startActivityForResult(builder.build(fragment.getActivity()),PLACE_PICKER_REQUEST,bundle);
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
}
I received the location request inside of a fragment and update the location of that particular user
My ManageUserFragment
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == PLACE_PICKER_REQUEST){
if(resultCode == RESULT_OK){
Place place = PlacePicker.getPlace(getContext(),data);
address = place.getAddress().toString();
String latLng = place.getLatLng().toString();
latLang = latLng;
//update user's decided location
Bundle bundle = data.getExtras();
String userName = bundle.getString(USERNAME);// it returns null, Why?
updateLocation(latLang,userName);
Toast.makeText(getContext(), latLng, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getContext(), getContext().getText(R.string.locationError), Toast.LENGTH_SHORT).show();
}
}
}
My constant is
public static final String USERNAME="Username";
Now,
My problem is
Why bundle.getString(USERNAME) always return null?
How to pass data to place picker intent so that we can receive it in
onActivityResult ?
After replicating your case and researching for a little bit, I found out that the third parameter in startActivityForResult() is not used to pass a bundle of values to the onActivityResult, it's used to pass options to Android itself, you can find those here. So if you want to pass any data you have to use an intent with putExtra("USERNAME", username), and you can retrieve it with getStringExtra("USERNAME"). It's explained in this answer as well.

Can I pass an Intent extra on finish()?

I'm wondering, is it possible to send information to the activity that I return to after calling finish()?
For example, I have an Activity SendMessageActivity.class which allows the user to post a message to their feed. Once that message has been saved to the server, I call finish(). Should I instead just start my MainActivity.class with a new Intent? Or is it better for life cycle development to just finish SendMessageActivity.class?
I don't see the point of starting a new activity since closing the current one will always bring you back to MainActivity.class. How can I just send a String extra after finishing the current Activity?
Use onActivityResult.
This might help you to understand onActivityResult.
By using startActivityForResult(Intent intent, int requestCode) you can start another Activity and then receive a result from that Activity in the onActivityResult() method.So onActivityResult() is from where you start the another Activity.
onActivityResult(int requestCode, int resultCode, Intent data) check the params here. request code is there to filter from where you got the result. so you can identify different data using their requestCodes!
Example
public class MainActivity extends Activity {
// Use a unique request code for each use case
private static final int REQUEST_CODE_EXAMPLE = 0x9988;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an Intent to start AnotherActivity
final Intent intent = new Intent(this, AnotherActivity.class);
// Start AnotherActivity with the request code
startActivityForResult(intent, REQUEST_CODE_EXAMPLE);
}
//-------- When a result is returned from another Activity onActivityResult is called.--------- //
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// First we need to check if the requestCode matches the one we used.
if(requestCode == REQUEST_CODE_EXAMPLE) {
// The resultCode is set by the AnotherActivity
// By convention RESULT_OK means that what ever
// AnotherActivity did was successful
if(resultCode == Activity.RESULT_OK) {
// Get the result from the returned Intent
final String result = data.getStringExtra(AnotherActivity.EXTRA_DATA);
// Use the data - in this case, display it in a Toast.
Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show();
} else {
// AnotherActivity was not successful. No data to retrieve.
}
}
}
}
AnotherActivity <- This the the one we use to send data to MainActivity
public class AnotherActivity extends Activity {
// Constant used to identify data sent between Activities.
public static final String EXTRA_DATA = "EXTRA_DATA";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);
final View button = findViewById(R.id.button);
// When this button is clicked we want to return a result
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Create a new Intent as container for the result
final Intent data = new Intent();
// Add the required data to be returned to the MainActivity
data.putExtra(EXTRA_DATA, "Some interesting data!");
// Set the resultCode to Activity.RESULT_OK to
// indicate a success and attach the Intent
// which contains our result data
setResult(Activity.RESULT_OK, data);
// With finish() we close the AnotherActivity to
// return to MainActivity
finish();
}
});
}
#Override
public void onBackPressed() {
// When the user hits the back button set the resultCode
// to Activity.RESULT_CANCELED to indicate a failure
setResult(Activity.RESULT_CANCELED);
super.onBackPressed();
}
}
Note : Now check in MainActivity you startActivityForResult there you specify a REQUEST_CODE. Let's say you want to call three different Activities to get results.. so there are three startActivityForResult calls with three different REQUEST_CODE's. REQUEST_CODE is nothing but a unique key you specify in your activity to uniquely identify your startActivityForResult calls.
Once you receive data from those Activities you can check what is the REQUEST_CODE, then you know ah ha this result is from this Activity.
It's like you send mails to your lovers with a colorful covers and ask them to reply in the same covers. Then if you get a letter back from them, you know who sent that one for you. awww ;)
You can set result of an activity, which allow you to data into an initent.
In your first activity, call the new one with startActivityForResult() and retrieve data in method onActivityResult. Everything is in documentation.
try this:
in First Activity:
Intent first = new Intent(ActivityA,this, ActivityB.class);
startActivityForResult(first, 1);
Now in Second activity: set Result during finish()
Intent intent = new Intent();
intent.putExtra("result",result); //pass intent extra here
setResult(RESULT_OK,intent);
finish();
First activity Catch the result;
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// check if the request code is same as what is passed here it is 1
if(requestCode==1)
{
String message=data.getStringExtra("result");
//get the result
}
}
If you call finish() to avoid that the user go back to SendMessageActivity.class, you can set this flags to your intent:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
This will open the MainActivity and remove the SendMessageActivity from the activities stack.

After calling startActivityForResult() subsequent code still runs

So basically I want the app to: after pressing a button opens the gallery, the user selects one image and after that saves the uri in a variable. That's all it needs to do but what I found is that after calling startActivityForResult() subsequent code still runs in the background creating a NullPointerException error, since the variable I wanted has not yet been retrieved from the intent.
public class MainActivity extends AppCompatActivity {
final static int PICK_IMAGE_REQUEST = 1;
private String imageUriStr;
SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs = this.getSharedPreferences("MyPreferences",MODE_PRIVATE);
ImageView addImgButton = (ImageView) findViewById(R.id.add_img_button);
addImgButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
if (prefs.contains(imageUriStr)) {
imageUriStr = prefs.getString("imageUriStr", ""); //Get the data from prefs
}
Log.d("Value",imageUriStr); //verify if it is correct
prefs.edit().clear();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
imageUriStr = data.getData().toString(); //convert to string to use it with SharedPreferences
prefs.edit().putString("imageUriStr",imageUriStr).apply();
}
}
}
One solution would be to do everything inside the onActivityresult, but I also want to later user another intent to crop the image based on that uri, but I think an Intent inside an onActivityresult will be too messy or is it acceptable? I guess I'm missing something.
Keeping with my code will generate this
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.prototypeapp, PID: 17826
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.d(Log.java:154)
at com.example.android.prototypeapp.MainActivity$1$override.onClick(MainActivity.java:41)
at com.example.android.prototypeapp.MainActivity$1$override.access$dispatch(MainActivity.java)
at com.example.android.prototypeapp.MainActivity$1.onClick(MainActivity.java:0)
at android.view.View.performClick(View.java:5264)
at android.view.View$PerformClick.run(View.java:21297)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
Your private String imageUriStr; is null.Since it is null you are getting null pointer exception. Assign it with the empty string like : private String imageUriStr = "";.
AND
Check in shared preference like :
if(prefs.contains("imageUriStr"))
Your Code is crashing on this line:
Log.d("Value",imageUriStr);
Reason: imageUriStr value is null and a valid message is required to print the log
You can either use Log as :
Log.d("Value","Image URI Value: "+imageUriStr);
or you can put your Log inside if block like:
if (prefs.contains(imageUriStr)) {
imageUriStr = prefs.getString("imageUriStr", "");//Get the data from prefs
Log.d("Value",imageUriStr); //verify if it is correct
}

Android: cannot get values using .getStringExtra

I'll just go straight to the problem. In UploadNotesActivity.java....
First, I pick a .pdf file using intent
chooseNotesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Create intent to Open Image applications like Gallery, Google Photos
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
// Start the Intent
startActivityForResult(intent, RESULT_LOAD_FILE);
}
});
and then, in `onActivityResult, I save the filePath of the picked file.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_FILE && resultCode == RESULT_OK && data != null) {
data.putExtra("filePath", data.getData().getPath());
choosenFile.setText(data.getStringExtra("filePath"));
} else {
Toast.makeText(this, "Error in choosing file",
Toast.LENGTH_LONG).show();
}
}
click Upload button to start upload the file
uploadNotesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onUploadButtonClick();
}
});
the onUploadButtonClick()
private void onUploadButtonClick() {
final String serverUrlString = "http://XXXX/uploadNotes.php";
if (getIntent().getStringExtra("filePath").isEmpty()) {
Log.d(TAG, "filePath is null");
} else {
Log.d(TAG, getIntent().getStringExtra("filePath"));
}
final String fileToUploadPath = getIntent().getStringExtra("filePath");
final String paramNameString = "uploaded_file";
String fileName[] = fileToUploadPath.split("/");
final MultipartUploadRequest request =
new MultipartUploadRequest(this, UUID.randomUUID().toString(), serverUrlString);
request.addFileToUpload(fileToUploadPath, paramNameString,
fileName[fileName.length-1]+".pdf", ContentType.APPLICATION_OCTET_STREAM);
request.setNotificationConfig(R.drawable.ic_launcher,
getString(R.string.app_name),
getString(R.string.uploading),
getString(R.string.upload_success),
getString(R.string.upload_error),
false);
// if you comment the following line, the system default user-agent will be used
request.setCustomUserAgent("UploadServiceDemo/1.0");
// set the intent to perform when the user taps on the upload notification.
// currently tested only with intents that launches an activity
// if you comment this line, no action will be performed when the user taps
// on the notification
// request.setNotificationClickIntent(new Intent(this, MainActivity.class));
// set the maximum number of automatic upload retries on error
request.setMaxRetries(2);
try {
request.startUpload();
} catch (Exception exc) {
Toast toast = Toast.makeText(getApplicationContext(), "Malformed upload request. " + exc.getLocalizedMessage(), Toast.LENGTH_LONG);
toast.show();
}
}
But the problem is, it will throw null pointer exception, which I don't quite get the reason.
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.isEmpty()' on a null object reference
at com.fyp.mycyberlaw.Lecturer.UploadNotesActivity.onUploadButtonClick(UploadNotesActivity.java:73)
at com.fyp.mycyberlaw.Lecturer.UploadNotesActivity.access$100(UploadNotesActivity.java:19)
at com.fyp.mycyberlaw.Lecturer.UploadNotesActivity$2.onClick(UploadNotesActivity.java:53)
line 73: if (getIntent().getStringExtra("filePath").isEmpty())
line 19: public class UploadNotesActivity extends Activity
line 53: onUploadButtonClick();
Seems like the filePath in line 73 is empty and the way I save filePath into bundle (?) is incorrect. How to get the filePath from onActivityResult? Here's the .java class, just in case. Thank you in advance. Really need your help.
An Intentobject is used to pass params between activities. Ones you receives the file path you must to keep it in your activity.
Create a filePathvariable inside your activity, set it on onActivityResult and read it on onUploadButtonClick.
Notice that must save variable value during the onSaveInstanceState callback and restore it in onCreate because every time you turn your phone the activity is destroyed and recreated. Check this for more information: Recreating an Activity

How to start an activity which calls a method from a different class?

I have an activity which transfer a string datatype to another activity which then uses that string and calls a method from another class which returns a string. I want to use that method to display the string in the current activity.
So visually it goes (activity 1) -- string--> (activity 2). Activity 2 uses that string to call a method in a different java class which returns a type string which i want to display on the screen along with a few buttons.
So some pseudo code:
say The method in a different java class is:
public static String getStringexample(String n) {
return "hello" + " " + n;
}
and my activity class is:
public class manage extends Activity {
protected void onCreate(bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContainerView(R.layout.activity_manage);
Intent intent = getIntent();
String example = intent.getExtras().getString("intentid");
i'm lost after this..not sure how to use what i got from the intent to display it on the screen in java code.
Information between activities is passed in 'extras'. That is just a collection of string keys and values.
Both sides need to use the same keys, so define static final strings with they keys that your destination activity expects.
Then read the values from the extras using the key and go from there:
public class DestinationActivity extends Activity {
// let your callers know how to pass you the information you need
public static final String EXTRA_N = "n";
private TextView resultText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_destination);
resultText = (TextView) findViewById(R.id.resultText);
// get the information you was passed
Intent intent = getIntent();
String n = intent.getStringExtra(EXTRA_N);
// do your transformation using the other class
String example = DifferentClass.getStringexample(n);
// display the transformed string
resultText.setText(example);
}
// ...
}
The calling activity sends the information like this:
Intent intent = new Intent(this, DestinationActivity.class);
intent.putExtra(DestinationActivity.EXTRA_N, "foo");
startActivity(intent);
Good luck
You can start activity as
Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, 1);
Then return to first activity from second activity
Intent returnIntent = new Intent();
returnIntent.putExtra("result",yourdata);
setResult(RESULT_OK,returnIntent);
finish();
In your first activity you will get result by using below code
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
String result=data.getStringExtra("result");
}
if (resultCode == RESULT_CANCELED) {
//Write your code if there's no result
}
}
}

Categories

Resources