Team
My question is, how do I read the result from the startAtcivityForResult.
When the button is pressed, it calls bStock(), which makes a URL call and retrieves data. I have verified the URL call is correct and that I do get data.
I have used finishActivity(1) to not display the actual content or result. For the sake of this message here is what I get when not using finishActivity(1)
My goal is to read the result and only display certain values like name and last price. Here is my code
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setContentView(R.layout.content_layout_id);
final Button buttonStock = findViewById(R.id.buttonS);
buttonStock.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
bStock();
}
});
}
static final int REQUEST_CODE = 1;
protected void bStock() {
String url = "http://dev.markitondemand.com/Api/v2/Quote/jsonp?symbol=AG";
Uri uri = Uri.parse(url);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
i.setPackage("com.android.chrome");
startActivityForResult(i, REQUEST_CODE);
finishActivity(1);
}
#Override
protected void onActivityResult ( int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
// Make sure the request was successful
//if (resultCode == RESULT_OK) { // 0 -1
// Get the URI that points to the selected contact
Uri o = data.getData();
Toast.makeText(MainActivity.this, "Name ", Toast.LENGTH_LONG).show();});
}
}
I am using a Toast (for now) just to display the name, but I do not know how to read data. Any help would be appreciated.
Jesse
That does not work as you expect, because the activity you are trying to start (chrome browser) is not prepared to return the result you want, to you. The intent (VIEW) tells the browser, to do just that -- view the given URL.
For activities that are not your own, you have to carecully check their description to see if they support any calls for results, and how they return it -- e.g. there is a 'take a picture' intent, that will return the picture taken to you via some uri data.
Most of the time, startActivityForResult is used to start your own activities, which you want to return data to the calling activity. In that case, you can define yourself, on how to pass the results back to the calling activity.
you may need to iterate through a cursor
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request it is that we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Get the URI that points to the selected contact
Uri contactUri = data.getData();
// We only need the NUMBER column, because there will be only one row in the result
String[] projection = {Phone.NUMBER};
// Perform the query on the contact to get the NUMBER column
// We don't need a selection or sort order (there's only one result for the given URI)
// CAUTION: The query() method should be called from a separate thread to avoid blocking
// your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
// Consider using CursorLoader to perform the query.
Cursor cursor = getContentResolver()
.query(contactUri, projection, null, null, null);
cursor.moveToFirst();
// Retrieve the phone number from the NUMBER column
int column = cursor.getColumnIndex(Phone.NUMBER);
String number = cursor.getString(column);
// Do something with the phone number...
}
}
}
Related
I have written below codes where when user click attach button to select photos.
Below is code for same.
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Select file to upload "), 1);
Below is code for OnActivityResult
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (null != data) { // checking empty selection
if (null != data.getClipData()) { // checking multiple selection or not
for (int i = 0; i < data.getClipData().getItemCount(); i++) {
Uri uri = data.getClipData().getItemAt(i).getUri();
Log.i(TAG, "Path" + getPath(uri));
filespath.add(getPath(uri));
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(getPath(uri), options);
bitmaps.add(bitmap);
}
} else {
Uri uri = data.getData();
}
}
}
}
Now user can select multiple photos and I realized that when photos are more than 10, I get warning too much work done on main thread. when user click on Done button after selecting photos, I have Recycler view where I am showing thumbnail of images selected by user before final upload.
Now issue is when user click Done and till it shows Thumbnail, how can I show ProgressDialog , handle freeze screen and avoid warning work done on main thread.
To keep the parsing and loading work off the main thread you can just wrap everything in an AsyncTask. Given the small amount of code shown, I don't know what functions do what in the above, so this might have to be adjusted a bit. Move all the parsing logic, etc to do in the background as such:
AsyncTask<Void, Void, List<Bitmap>>() {
#Override
protected void onPreExecute()
{
//show progress dialog
//Are you trying to prevent the user from clicking on the UI while updating?
//You can do something such as:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
#Override
protected List<Bitmap> doInBackground(Void... voids) {
//perform the logic, this will return a list of all the Bitmaps to onPostExecute
//Do NOT perform any ui logic here.
}
#Override
protected void onPostExecute(List<Bitmap> bitmaps) {
//cancel progress dialog.
//Update the UI with the response.
//Clear the window lock:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
};
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.
I have used the following code to get a picture from the gallery in an app on clicking a button. It works fine but I just wanted to know the meaning of the codes used. Could someone help me in it?
private ImageButton mSelectImage;
public static final int GALLERY_REQUEST =1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post);
mSelectImage = (ImageButton)findViewById(R.id.imageSelect);
mSelectImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, GALLERY_REQUEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == GALLERY_REQUEST && resultCode == RESULT_OK){
Uri imageUri = data.getData();
mSelectImage.setImageURI(imageUri);
}
}
This is the requestCode. It helps you to identify from which Intent you came back. For example if you have two or more intent for camera request and for the Contact request.Whenever the subsequently called finish and need to pass data back to Acivity, now you need to identify in your onActivityResult from which intent call you are returning from and put your handling logic accordingly.
public static final int CAMERA_REQUEST = 101;
public static final int CONTACT_VIEW = 202;
#Override
public void onCreate(Bundle savedState)
{
super.onCreate(savedState);
// For CameraRequest you would most likely do
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
// For ContactReqeuest you would most likely do
Intent contactIntent = new Intent(ACTION_VIEW, Uri.parse("content://contacts/people/1"));
startActivityForResult(contactIntent, CONTACT_VIEW);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == Activity.RESULT_CANCELED) {
// code to handle cancelled state
}
else if (requestCode == CAMERA_REQUEST) {
// code to handle data from CAMERA_REQUEST
}
else if (requestCode == CONTACT_VIEW) {
// code to handle data from CONTACT_VIEW
}
}
GALLERY_REQUEST is a request code which is used like token, imagine you go into mall with bag, but they can't let you in with the bag so you have to put your bag outside the mall and guy will gives you a token, so when you will come back you give him that token and he will give your bag.
This token is managed just because you are not the only one who came with the bag there may be more, as the rule all person have to put their bag outside mall, but how to identify which bag belongs to which person,they used token.
Just like that request code is used, you may going to several other apps via implicit intent from your activity but when you came back, one method called for all intent: onActivityResult now you have request code to identify that from which activity is user coming from.
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.
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