How getIntent.hasExtra method works in android - android

I have been following a tutorial from this link which is basically about File browse concept in android. Everything works fine but I am getting confused of how passing intents between activities works in android after reading this link. The First activity is as follows,
public class MainActivity extends Activity implements OnClickListener {
private static final int REQUEST_PICK_FILE = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
filePath = (TextView)findViewById(R.id.file_path);
Browse = (Button)findViewById(R.id.browse);
Browse.setOnClickListener(this);
}
public void onClick(View v) {
switch(v.getId()) {
case R.id.browse:
Intent intent = new Intent(this, FilePicker.class);
startActivityForResult(intent, REQUEST_PICK_FILE);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
switch(requestCode) {
case REQUEST_PICK_FILE:
if(data.hasExtra(FilePicker.EXTRA_FILE_PATH)) {
selectedFile = new File
(data.getStringExtra(FilePicker.EXTRA_FILE_PATH));
filePath.setText(selectedFile.getPath());
}
break;
}
}
As far as I understood, its passing the intent "REQUEST_PICK_FILE" and based on what it returns from "FilePicker.Class" , it will perform the action because its StartActivityOnResult. Confusion starts from next activity. Here is the File Picker class,
public class FilePicker extends ListActivity {
public final static String EXTRA_FILE_PATH = "file_path";
public final static String EXTRA_SHOW_HIDDEN_FILES = "show_hidden_files";
public final static String EXTRA_ACCEPTED_FILE_EXTENSIONS = "accepted_file_extensions";
private final static String DEFAULT_INITIAL_DIRECTORY = "/";
.......
protected String[] acceptedFileExtensions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.........
// Initialize the extensions array to allow any file extensions
acceptedFileExtensions = new String[] {};
// Get intent extras
if(getIntent().hasExtra(EXTRA_FILE_PATH))
Directory = new File(getIntent().getStringExtra(EXTRA_FILE_PATH));
if(getIntent().hasExtra(EXTRA_SHOW_HIDDEN_FILES))
ShowHiddenFiles = getIntent().getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES, false);
if(getIntent().hasExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS)) {
ArrayList<String> collection =
getIntent().getStringArrayListExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS);
acceptedFileExtensions = (String[])
collection.toArray(new String[collection.size()]);
}
}
..............
Whats actually happening here? what does the lines ,
if(getIntent().hasExtra(EXTRA_SHOW_HIDDEN_FILES))
ShowHiddenFiles = getIntent().getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES, false);
actually mean? We are not passing any extras like, "EXTRA_SHOW_HIDDEN_FILES" from previous activity and even EXTRA_SHOW_HIDDEN_FILES has been declared in this class. I seriously don't understand what's happening between these two activities . I am not able to proceed before understanding what's actually going on. Any help would be really great !! Thanks.

what does the lines... actually mean?
It means that if the Intent used to start FilePicker has an EXTRA_SHOW_HIDDEN_FILES, hold onto that value in what I assume is a boolean field on the activity that is not shown in your redacted code listing.
We are not passing any extras like, "EXTRA_SHOW_HIDDEN_FILES" from previous activity
You could, though. You do not have to.
even EXTRA_SHOW_HIDDEN_FILES has been declared in this class
That is fairly typical. FilePicker is declaring an API, and so it exposes the names to be used for incoming and outgoing extras. EXTRA_SHOW_HIDDEN_FILES is public, and so it can be referenced from anywhere, including MainActivity.

Related

Custom Objects not being passed to other Activity via intent PutExtra

So I am making an android app that implements some custom classes. I want to create an object of class Menu_Organizer to other activities, but after I inizialize the object and send it to the next Activity the object is NULL. Here are the classes:
Menu Items class
import java.io.Serializable;
public class Menu_Items implements Serializable {
private String Name = "";
private String Description = "";
private float Price = 0.0f;
private String Category = "";
/* Getters and Setters*/
}
Menu Organizer class:
public class Menu_Organizer implements Serializable {
ArrayList<String> Categories;
ArrayList<Menu_Items> Food;
// EDITED
public Menu_Organizer() {
Categories = new ArrayList<String>();
Food = new ArrayList<Menu_Items>();
}
/* Other class methods */
}
First Activity (main)
public class MainActivity extends AppCompatActivity {
private Button btn;
public Menu_Organizer menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
onclick();
}
public void onclick() {
btn = (Button) findViewById(R.id. btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Menu_Organizer menu = new Menu_Organizer();
menu.New_Menu_Item("Carne", "Pollo", "Pollo Asado Rico!", 4.55f);
Intent activity2= new Intent(MainActivity.this,temp.class);
activity2.putExtra("Menu", menu);
startActivity(activity2);
}
});
}
}
Second Activity
public class temp extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_Second);
Bundle bundle = getIntent().getExtras();
Menu_Organizer menu = (Menu_Organizer) bundle.getSerializable("Menu");
String str= menu.Food.get(0).getName();
}
}
Alright, i think that the issue is, that when you pass your class object in a key value pair, you do it in an Intent object, but when you resolve your intent, you do that via a bundle object. So, in you temp Activity, you should resolve the intent like:
Intent intent = this.getIntent();
Menu_Organizer menu = (Menu_Organizer) intent.getSerializableExtra("Menu");
Try this, this should work. If you want to do it via a bundle, then create a bundle object first, then put whatever you want in that bundle. Add the bundle to your intent, and then resolve the bundle in your next Activity.
Just a tip, Class names generally do not contain _ in them, use CamelCase naming convention for all classes.
I would recommend using EventBus library for this kind of thing. It is quite easy to use and gives you exactly this: sending and receiving custom object classes from one place to another (Fragments, Activities, Services, whatever you wish can send and receive objects).
I personally don't like intents cause they have too many limitations.

Send and receive from Activity at the same time

I have 2 Activities.
When I click the Button in board Activity, main will open and execute, then send value (mark) to the board Activity
It works.
But I want also to send 3 arrays from the board Activity to the main Activity, as variables, according which Button is clicked (I have 3 Buttons in the board Activity, each array for Button).
This is the function I used in board Activity:
public void getMessage(View V) {
// Create The Intent and Start The Activity to get The message
Intent intentGetMessage = new Intent(this, MainActivity.class);
startActivityForResult(intentGetMessage, 2);// Activity is started with requestCode 2
}
// Call Back method to get the Message form other Activity override the method
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
// check if the request code is same as what is passed here it is 2
if (requestCode == 2) {
// fetch the message String
String message = data.getStringExtra("MESSAGE");
// Set the message string in textView
mm.setText(message);
and this is the submit function in the main Activity :
public void submitMessage(View V) {
String message = String.valueOf(mark);
Intent intentMessage = new Intent();
// put the message to return as result in Intent
intentMessage.putExtra("MESSAGE", message);
// Set The Result in Intent
setResult(2, intentMessage);
// finish The activity
finish();
}
The simplest way is to use a singleton, that is a class of which only one instance exists. And the simplest way to do that is to define a class containing three static arrays, with public (static) accessors. You can then reference this class from either activity, place arrays in from one and read them back from the other. For example,
public class SampleSingleton {
private static String[] _array1;
private static Integer[] _array2;
private static boolean[] _array3;
public static String[] get_array1() {
return _array1;
}
public static void set_array1(String[] _array1) {
SampleSingleton._array1 = _array1;
}
public static Integer[] get_array2() {
return _array2;
}
public static void set_array2(Integer[] _array2) {
SampleSingleton._array2 = _array2;
}
public static boolean[] get_array3() {
return _array3;
}
public static void set_array3(boolean[] _array3) {
SampleSingleton._array3 = _array3;
}
}
There are other more elegant, and complicated, methods and the answers to this question give a few pointers, but as a quick and simple approach this'll do.

Universal Image Loader: Save current image to SD-Card?

I'm using the Universal Image Loader library.I have a viewpager gallery of images and I want to be able to save the current image being viewed to the SD-Card. Below is the button i've implemented but it doesn't work. PLEASE HELP!!
private ViewPager gallery;
public class ImageGalleryActivity extends BaseActivity {
final String[] imageUrls = bundle.getStringArray(Extra.IMAGES);
.....
findViewById(R.id.btnSave).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int index = gallery.getCurrentItem();
ImageView img = imageUrls.get(index);
saveimage(img);
Toast.makeText(ImageGalleryActivity.this, "Image Successfully Saved", Toast.LENGTH_LONG).show();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://Pictures"
+ Environment.getExternalStorageDirectory())));
}
});
...
}
Make sure you added the appropriate permission in your app manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Bundle is generally used for passing data between various Activities of android. It depends on you what type of values you want to pass but bundle can hold all types of values and pass to the new activity.
You can use it like this,
Intent intent = new Intent(getApplicationContext(),ActivityName.class);
intent.putExtra("myKey",AnyValue);
startActivity(intent);
Now you can get the passed values by...
Bundle extras = intent.getExtras();
String tmp = extras.getString("myKey");
Have below line inside onCreate method after
public class MyActivity extends Activity
{
private static String imageURL;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageUrls = bundle.getStringArray(Extra.IMAGES);
}}
My best solution is don't pass anything via bundle to another activity.
Instead use this class,
public class MyGetSetMethod()
{
String[] imageURLS;
public void setImageURLS (String[] imageUrls)
{
this.imageURLS = imageUrls;
}
public String[] getImageURLS()
{
return imageURLS;
}
}
Now on your ImagePagerActivity,
MyGetSetMethod.setImageURLS(imageURLS);
On ImageGalleryActivity,
String[] ImageURLS = MyGetSetMethod.getImageUrls();
This should do.

Get startActivityForResult result in static function

I'm working from Unity and want to get the result of a file picking activity. Since I can't start activities from Unity itself, I created an "intermediant" static class called EclipseIntegration:
package com.Unity3D.EclipseIntegration;
public class EclipseIntegration {
public static String selectedPath = "really ";
public static void Launch(Activity activity) {
Intent target = new Intent(activity, MyActivity.class);
activity.startActivity(target);
}
}
activity is the Activity Unity is currently running in.
MyActivity is meant to start the real activity, because I need something that inherits from Activity to get the onActivityResult event:
package com.Unity3D.EclipseIntegration;
public class MyActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Launch();
}
public void Launch() {
Intent target = FileUtils.createGetContentIntent();
Intent intent = Intent.createChooser(target, "Select a movie");
startActivityForResult(intent);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 128:
if (resultCode == RESULT_OK) {
final Uri uri = data.getData();
File file = FileUtils.getFile(uri);
EclipseIntegration.selectedPath = file.getAbsolutePath();
}
else EclipseIntegration.selectedPath = "";
finish();
}
}
}
but nothing happens. If I start the final activity directly in the static class like this :
activity.startActivity(intent); it works though, so I suppose I made some error while setting up the MyActivity? Despite trying this for 2 days now I couldn't find it though, so any nudge in the right direction would be very appreciated :)
Thanks,
kiriri
Try this way
public void Launch() {
Intent target = FileUtils.createGetContentIntent();
Intent intent = Intent.createChooser(target, "Select a movie");
startActivityForResult(intent,128);
}

How to call startactivityforresult from a non-activity class to get the resuts

Is it possible to call startActivityForResult() from a non-activity class to get the results?
Scenario is something like this:
I have a class NonActivity (it doesn't derive from Activity as its not a UI).
This class will have bunch of functions(steps basically) to run.
One of the steps requires to show UI(Activity) and then get the result (user enter something).
Then been able to use that data in next following steps.
How can this be achieved without deriving from activity class as I don't have UI component?
Also since I don't want to derive from activity class that means I cannot override OnActivityResult(). Where results actually come from?
startActivityForResult() is only available from real on-screen activities, since it is a method in, well, Activity. Please redesign your application so that the user interface is driven from activities.
On the other hand, if your non Activity class is initialized and used from an onscreen Activity, you could pass that instance of the Activity to your class as a parameter in the constructor and use it to launch other Activities.
Be careful though. Using this method increases the risk of a memory leak, as the external class (Utils in my example) might keep a reference to the Activity even after its gone.
If all you want to do is access data, then you could try writing it to SharedPreferences or a Database or some files and then using the application context (passed in via a constructor again) to read it. This reduces the risk of a memory leak. Something like:
MyApiClass myApiClass = new MyApiClass(getApplicationContext());
EXAMPLE CODE
Main Activity:
public class Main extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Utils util = new Utils(this);
util.startTest();
}
#Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
Toast.makeText(this, "onActivityResult called", Toast.LENGTH_LONG).show();
super.onActivityResult(arg0, arg1, arg2);
}
}
Utils class (which launches for result):
public class Utils {
Activity activity;
public Utils(Activity ac) {
activity = ac;
}
public void startTest() {
Intent i = new Intent(activity, Test.class);
activity.startActivityForResult(i, 1);
}
}
Test Activity:
public class Test extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(this, "Test", Toast.LENGTH_LONG).show();
this.setResult(Activity.RESULT_OK);
this.finish();
}
}
StartActivityForResult from a class using a fragment with no visible GUI. You might find something like this in a utility class.
see runGetUserAccount below. It creates its own fragment and executes a startActivityForResult. Then it has it's own onActivityResult.
public class MyGooglePlay {
private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 31502;
private ActionBarActivity activity;
private FragmentManager fragManager;
public MyGooglePlay(ActionBarActivity activity) {
this.activity = activity;
this.fragManager = activity.getSupportFragmentManager();
}
/**
* Starts an activity in Google Play Services so the user can pick an
* account
*/
private String mEmail = "";
static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
public void runGetUserAccount() {
if (TextUtils.isEmpty(mEmail)) {
// run this code in gui less fragment so we can pickup the
// on activity result from inside the mygoogleplay class.
Fragment f = new Fragment() {
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
String[] accountTypes = new String[] { "com.google" };
Intent intent = AccountPicker.newChooseAccountIntent(null,
null, accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
if (resultCode == Activity.RESULT_OK) {
set_Email(data
.getStringExtra(AccountManager.KEY_ACCOUNT_NAME));
// getUsername();
}
super.onActivityResult(requestCode, resultCode, data);
}
//this is to verify the fragment has been removed.
//you can log or put a breakpoint to verify
#Override public void onDestroy(){
super.onDestroy();
}
};
FragmentTransaction fragmentTransaction = this.fragManager
.beginTransaction();
fragmentTransaction.add(f, "getusername");
fragmentTransaction.commit();
}
}
/**
* #param mEmail
* the mEmail to set
*/
private void set_Email(String mEmail) {
this.mEmail = mEmail;
if (!TextUtils.isEmpty(mEmail)) {
// TODO notify caller email is ready;
// activity.onEmailReady(mEmail);
}
//we are done with the "getusername" fragment
Fragment f = fragManager.findFragmentByTag("getusername");
if (f!=null) {
fragManager.beginTransaction().remove(f).commit();
}
}
}
U should pass context as Activity,then u will get solution.
try this below code.it will work
In non Activity class
public class nonActivity {
public static void method(Activity activity)
{
Intent intent = new Intent(activity, SecondActivity.class);
activity. startActivityForResult(intent, REQUEST_CODE);
}
}
In SecondActivity
Intent intent = getIntent();
intent.putExtra("data", "data"); //here u can pass data to previous activity
setResult(RESULT_OK, intent);
finish();
In firstActivity
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
try {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
String status = data.getStringExtra("data");
//Do what u want with data
}
} catch (Exception e) {
System.out.println("=====Exception=====" + e.toString());
}
}
If you want the result back from the activity to your normal class, supposed it is a class with a custom adapter within it.
you cannot use startActivityForResult because you are not in an activity
what I did is that i launched the activity from the class with an intent. Then I calculated or did what I have to. From this activity I send the information to the main class supposed with a method MainActivity.the_method() and in the main activity I changed the custom adapter o did what I have to using the adapter object and calling adapter.getItem(position)
Hope this can give you an idea

Categories

Resources