I am storing an intent in shared preferences like so :
new Intent(context, MainActivity.this);
and then when I try to open it I am getting the error :
android.content.ActivityNotFoundException: No Activity found to handle Intent { }
I assume it's because context is referring to the stored activity? when context should be the current activity.
My question is how do I get around this one? I have several buttons which is populated by objects stored in the preferences. Each of them opens different activities. Basically I am mapping activities to be opened to buttons.
To give you an idea :
public class Scene implements Serializable {
public String label;
public Intent intent;
public boolean isUnlocked;
public Scene(String lbl, Intent i) {
this.label = lbl;
this.intent = i;
}
}
for (Scene scene : savedScenesFromSharedPreferences) {
Button btn = new Button();
btn.setOnClickListener(new OnClickListener()) {
startActivity(scene.intent);
}
}
You can try this:
In your Scene class, instead of saving the Intent, save the activity name.
scene.setLabel("Button A");
scene.setActivityName("com.example...YourOtherActivityName");
To start the activity:
startActivity(new Intent(YourCurrentActivity.this, Class.forName(scene.getActivityName)));
Related
I have a very heavy Main Acitivty class which the first time you install the app , freezes until all the data is loaded , I want to show my Splash Screen activity while all the data is loading in the Main Activity and show my activity ONLY when the Main Activity has loaded everything :
Here is my current splash screen activity , currently it only does this:
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
How can I achieve this?
Regarding the comments on your question, it seems you're trying to update the UI of your MainActivity with the data you're loading. You can query/load your data on the splash activity, pass it on to the intent so you can gather it in onCreate of your MainActivity, or save all your data to SharedPreferences and access it from the MainActivity.
In SplashActivity:
Intent intent = new Intent(this, MainActivity.class);
// inside data loading completion callback or after synchronous data gathering methods
intent.putExtra("key","value");
startActivity(intent);
In MainActivity onCreate method
Bundle extras = intent.getExtras();
String value = extras.getString("key");
You can pass models as json formatted strings if you need.
if your splash screen named: spalsh.java
and your main activity named: MainActivity.java
first you create this class:
public class SliderPrefManager {
private Context context;
private SharedPreferences pref;
private static final String Pref_Name="slider-pref";
private static final String Key_Start="startslider";
public SliderPrefManager(Context context){
this.context = context;
pref = context.getSharedPreferences(Pref_Name,Context.MODE_PRIVATE);
}
public Boolean startSlider(){
return pref.getBoolean(Key_Start,true);
}
public void setStartSlider(Boolean start){
pref.edit().putBoolean(Key_Start,start).apply();
}
}
and in your splash screen add this code:
sliderPrefManager = new SliderPrefManager(login_Activity.this);
sliderPrefManager.setStartSlider(false);
and you checked boolean of view slash screen, add this code in your mainActivity:
if (sliderPrefManager.startSlider()) {
Intent intent = new Intent(choise_way_sec.this, login_Activity.class);
startActivity(intent);
finish();
}
How can I receive a custom ArrayList from another Activity via Intent? For example, I have this ArrayList in Activity A:
ArrayList<Song> songs;
How could I get this list inside Activity B?
The first part to understand is that you pass information from Activity A to Activity B using an Intent object, inside which you can put "extras". The complete listing of what you can put inside an Intent is available here: https://developer.android.com/reference/android/content/Intent.html (see the various putExtra() methods, as well as the putFooExtra() methods below).
Since you are trying to pass an ArrayList<Song>, you have two options.
The first, and the best, is to use putParcelableArrayListExtra(). To use this, the Song class must implement the Parcelable interface. If you control the source code of Song, implementing Parcelable is relatively easy. Your code might look like this:
Intent intent = new Intent(ActivityA.this, ActivityB.class);
intent.putParcelableArrayListExtra("songs", songs);
The second is to use the version of putExtra() that accepts a Serializable object. You should only use this option when you do not control the source code of Song, and therefore cannot implement Parcelable. Your code might look like this:
Intent intent = new Intent(ActivityA.this, ActivityB.class);
intent.putSerializableExtra("songs", songs);
So that's how you put the data into the Intent in Activity A. How do you get the data out of the Intent in Activity B?
It depends on which option you selected above. If you chose the first, you will write something that looks like this:
List<Song> mySongs = getIntent().getParcelableArrayListExtra("songs");
If you chose the second, you will write something that looks like this:
List<Song> mySongs = (List<Song>) getIntent().getSerializableExtra("songs");
The advantage of the first technique is that it is faster (in terms of your app's performance for the user) and it takes up less space (in terms of the size of the data you're passing around).
Misam is sending list of Songs so it can not use plain putStringArrayList(). Instead, Song class has to implement Parcelable interface. I already explained how to implement Parcelable painless in post here.
After implementing Parcelable interface just follow Uddhavs answer with small modifications:
// First activity, adding to bundle
bundle.putParcelableArrayListExtra("myArrayListKey", arrayList);
// Second activity, reading from bundle
ArrayList<Song> list = getIntent().getParcelableArrayListExtra("myArrayListKey");
I hope this helps you.
1. Your Song class should be implements Parcelable Class
public class Song implements Parcelable {
//Your setter and getter methods
}
2. Put your arraylist to putParcelableArrayListExtra()
public class ActivityA extends AppCompatActivity {
ArrayList<Song> songs;
#Override
protected void onCreate(Bundle savedInstanceState) {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), ActivityB.class)
.putParcelableArrayListExtra("songs", (ArrayList<? extends Parcelable>) songs));
}
});
}
3. In the ActivityB
public class ActivityB extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
final ArrayList<Song> songs = intent.getParcelableArrayListExtra("songs");
//Check the value in the console
buttonCheck.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (Song value : songs) {
System.out.println(value.getTitle());
}
}
});
}
to send a string arrayList in Java you can use,
intent.putStringArrayListExtra("key", skillist <- your arraylist);
and
List<String> listName = getIntent().getStringArrayListExtra("key");
Please note, bundle is one of the key components in Android system that is used for inter-component communications. All you have to think is how you can use put your Array inside that bundle.
Sending side (Activity A)
Intent intent1 = new Intent(MainActivity.this, NextActivity.class);
Bundle bundle = new Bundle();
Parcelable[] arrayList = new Parcelable[10];
/* Note: you have to use writeToParcel() method to write different parameters values of your Song object */
/* you can add more string values in your arrayList */
bundle.putParcelableArray("myParcelableArray", arrayList);
intent1.putExtra("myBundle", bundle);
startActivity(intent1);
Receiving side (Activity B)
Bundle bundle2 = getIntent().getBundleExtra("myBundle"); /* you got the passsed bundle */
Parcelable[] arrayList2 = bundle.getParcelableArray("myParcelableArray");
I have an Activity that uses the following code to retrieve information from another activity:
Bundle extras = getIntent().getExtras();
if (extras != null) {
int tok = extras.getInt("Token");
tempToken += tok;
}
This is the Code inside the first other class that sends this information:
final Button mainMen = (Button) findViewById(R.id.toMainMenu);
mainMen.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(),
Menu.class);
i.putExtra("Token", tok + teTok);
startActivity(i);
}
});
Now i have another Activity that also wants to sen information to the Main Activity like so:
maMenu.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Campaign.this, Menu.class);
intent.putExtra("Token", player.tokens);
intent.putExtra("Round", player.round);
intent.putExtra("Rank", player.rank);
intent.putExtra("Score", player.score);
intent.putExtra("Sec", player.secondsTapped);
intent.putExtra("Min", player.minutesTapped);
intent.putExtra("Hour", player.hoursTapped);
intent.putExtra("Day", player.daysTapped);
intent.putExtra("LifeTap", player.tapsInLife);
intent.putExtra("SecTap", player.tapsPerSec);
intent.putExtra("TapRo", player.tapps);
startActivity(intent);
}
});
Now my question is, how do i handle these different extras from multiple Activities inside the one Main Activity?
Thank You for your time :)
There are two ways to solve your problem..
1)
You can pass one boolean value to or and int variable with some value.. And retrieve this in your new Activity and check with boolean value or int value and get correct data correspond to Activity.
2) You can save your all Data in Shared Preference. And get your all Data in any Activity.
you can send one boolean value that data is in first class or second class and in MainActivity check the value and get the correct data
I have creted a program that has 3 Activities: MainActivity, UpgradeActivity and UpgradesActivity.
Main Activity contains a timer and it also contains an instance of a Vehicle class.
public class MainActivity extends Activity {
TextView vehicleSpeed, vehicleName, vehicleDistance, vehicleLocation,
vehicleStatus, vehicleNews, vehicleInfo, vehicleMoney;
ProgressBar vehicleFuel;
public static Vehicle vehicle;
boolean launched;
public static PartType selectedType;
Handler handler = new Handler();
I have a button in MainActivity, that when pressed will take me to a page where i can select which part of the vehicle i wish to upgrade. For example i select: Engine. The engine Button takes me to the Upgrade Activity. In this activity i can buy the upgrade which should be applied to the vehicle in MainActivity. For the purpose of this question, lets say it set vehicles speed to +3.
My question is in regards to how to access the vehicle instance inside the MainActivity from the UpgradeActivity. I've tried making the instance static but that didn't work. How do i gain access and how can i change the vehicles variables from the other activities.
Here is where i am making the instance:
#Override
protected void onCreate(Bundle savedInstanceState) {
this.selectedType = PartType.Antenna;
this.launched = false;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vehicle = new Vehicle();
vehicle.setupCar();
Here is where i am accessing the variable in Upgrades, it call the upgrade function inside of the Vehicle Class:
buyUp1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MainActivity.vehicle.upgradeEngine(MainActivity.vehicle.engineLvl + 1);
Intent activityChangeIntent = new Intent(UpgradesActivity.this, MainActivity.class);
UpgradesActivity.this.startActivity(activityChangeIntent);
}
});
And this is the function within the Vehicle Class:
public void upgradeEngine(int lvl) {
engineLvl += 3;
engine = parts.getEngine(lvl);
}
The vehicle Stores an integer called: EngineLvl. This determines what level the cars engine is. The level is incremented by +3 everytime the engine is updated.
The problem is that the engine level never changes. Even if i make the Vehicle instance and all of the variables within vehicle STATIC;
MAINACTIVITY:
Vehicle
Button to UpgradesActivity
UPGRADESACTIVITY:
Button to UpgradeActivity
UPGRADEACTIVITY:
Change vehicle enginelvl Int
Button back to MainActivity
Main>Upgrades>Upgrade
Thank you for your time
Hard to say what is wrong without seeing the code, but I would advise you to use the Intent extras to move your data between activities. You will need to make your Vehicle class implement Parcelable (there is an example of how to implement Parcelable on that page, and countless others on the net). You pass your object as extra to the intent launching your UpgradeActivity like this :
Intent upgradeIntent = new Intent(this, UpgradeActivity.class);
upgradeIntent.putExtra("com.example.model.Vehicle", yourVehicleObject);
startActivityForResult(upgradeIntent, UPGRADE_CAR_REQUEST_CODE);
//UPGRADE_CAR_REQUEST_CODE is a unique private static final int
Then you can retrieve it in your UpgradeActivity onCreate method :
Intent intent = getIntent();
Vehicle vehicleFromLastActivity = intent.getParcelableExtra("com.example.model.Vehicle");
Before going back to your MainActivity you do something like this :
Intent dataIntent = new Intent();
dataIntent.putExtra("com.example.model.Vehicle", yourModifiedVehicleObject);
setResult(RESULT_OK, dataIntent);
finish();
Then finally in MainActivity you need to handle the result, it is done like this :
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case UPGRADE_CAR_REQUEST_CODE:
if(resultCode == android.app.Activity.RESULT_OK) {
Vehicle modifiedObject = data.getParcelableExtra("com.example.model.Vehicle");
// Now you can use that object which is coming from UpgradeActivity
}
}
}
Of course this could cause issues if your Vehicle class takes a lot of memory. You could then consider passing only the relevant information through the Intent to rebuild the object in the UpgradeVehicle Activity, for example only the id & name.
I have 3 screens in my app, each of which are in their own classes. When the app launches, my Driver class sets up some GUI elements, and then launches the first Intent.
I have a separate GUI class (which Driver invokes) which handles everything from menu's to dialog boxes. Previously my app didn't use Intents so I could pass the activity/context from Driver to Gui in its constructor as an object of type Activity and as a result could define layouts etc like LinearLayout ll = new LinearLayout(activity) and everything would be operating in the same activity/context.
Since I've moved to using intents, each Activity/Class has its own context, thus the previous dialogs and popup boxes from the Gui class are in the background and not running. I get an error saying android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy#406629a0 is not valid; is your activity running? when I click on a button to launch a dialog.
To me, this indicates the new Intents have taken over the foreground and the objects from the previous context are out of scope.
So, is there a way I can still pass the same context through to the new Intents so I can still access these shared dialogs? Or will I have to bring the code into each class (duplicate code)?
In case thats a bit hard to understand, here is some basic source code:
public class Driver extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Gui display = new Gui(this);
display.showScreen();
}
}
/////////////GUI.java///////////////////////
public class Gui
{
private Activity activity;
private Gui()
{}
public Gui(Activity _activity)//,Context _context)
{
this();
activity = _activity;
}
public void showScreen()
{
if(isLocationMode())
{
Intent i = new Intent(activity,LocationScreen.class);
//i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(i);
//locatScreen = new LocationScreen(activity);
//mainLayout.addView(locatScreen.getView());
}
else if (isManageMode())
{
Intent i = new Intent(activity,ManageScreen.class);
//i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(i);
//manageScreen = new ManageScreen(activity);
//mainLayout.addView(manageScreen.getView());
}
else if (isForwardMode())
{
Intent i = new Intent(activity,ForwardScreen.class);
//i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(i);
//forwardScreen = new ForwardScreen(activity);
//mainLayout.addView(forwardScreen.getView());
}
}
}
Have a setContext(Activity _activity) method in your Gui and call this in the onCreate of each activity?