I'm new to android, and I'm trying my best to create a game. I'm trying to create a gameover screen for my game, and I though the best way to do that was to create an activity for a gameover screen. However, I'm not sure how to go about doing this.The problem seems to be that I cannot create an intent anywhere other than the activity class. So I can't see when the game should end, and then create a new activity without it being in the activity class. So I'm having trouble connecting my game model to my activity class, so that when the player dies, it would trigger a gameover activity. Where in my activity class should I put this information?
You would place code such as (assuming your activity is GameOverScreen extends Activity):
Intent gameOverScreen = new Intent(this, GameOverScreen.class);
startActivity(gameOverScreen);
To do so from outside the activity (since startActivity() is a public method of the Activity class), you'd just do like this, using the instance of your game activity that I call gameScreen in this example:
Intent gameOverScreen = new Intent(gameScreen, GameOverScreen.class);
gameScreen.startActivity(gameOverScreen);
You should probably have a reference to the instance of your game activity stored to the model as a Context object at least for resources.
</activity>
<activity android:name=".gameoveractivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="name-of-activity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Add this in your Manifest.xml...
Then from the code invoke this activity like this
Intent i = new Intent("name-of-activity-you-declared-in-the-manifest");
this.startActivity(i);
I guess you should put this after reaching conditions for game over. Let's say after loosing 3 lives, you get game over activity.
If you are doing game over with something like TRY AGAIN. Then you should use this.startActivityForResult(i, result). And then, override the onActivityResult() method in the class from where you call the game over activity.
Related
I would like to launch my application and check the connectivity state in application's onCreate method then decide which activity to start! I know that I could finish() a default MAIN/LAUNCHER activity before to setLayout while starting another if it's relevant but that seems messy to me!
So, I would like to know if it is possible to start an application whose doesn't manifest an activity with action.MAIN / category.LAUNCHER? I tried this way but it doesn't work! I mean the application seems to start but no activity is shown!
(This is not a sample from my real code, I'm not at home right now! Some arguments and stuff may be missing but I think you get the point!)
public class MyApp extends Application {
onCreate() {
Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.NEW_TASK);
this.startActivity(intent);
}
}
Also, the first activity of my application may be an AlertDialog and I'm wondering if I can start one while no activity is started or if I'm forced to set an activity's theme with #android:style/Theme.Dialog?
I tried the same as for the above example but same result : logcat saying application alive while no printing at all...
Tell me if I'm not clear enough and in which way! I'm not an english speaker and I'm not used to ask in forums!
You will have to go this way:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.some_empty_or_loading_view); //optional probably, not sure
//TODO: check whatever you want
if(condition) {
startActivity(this, SomeActivity.class);
} else {
startActivity(this, AnotherActivity.class);
}
finish();
}
}
Specify Your App's Launcher Activity
When the user selects your app icon from the Home screen, the system calls the onCreate() method for the Activity in your app that you've declared to be the "launcher" (or "main") activity. This is the activity that serves as the main entry point to your app's user interface.
You can define which activity to use as the main activity in the Android manifest file, AndroidManifest.xml, which is at the root of your project directory.
The main activity for your app must be declared in the manifest with an that includes the MAIN action and LAUNCHER category. For example:
<activity android:name=".MainActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Note: When you create a new Android project with the Android SDK tools, the default project files include an Activity class that's declared in the manifest with this filter.
If either the MAIN action or LAUNCHER category are not declared for one of your activities, then your app icon will not appear in the Home screen's list of app
I have an app with some activities. These activities need common resources (matrix arrayLists), so in order to avoid reload several times this resources (when change to another activity or on an orientation change), I've created a service.
Firstly I call it with startService(Intent) for let it be sticky.
After that, I bind the service to the activity, bindService(sIntent, mConnection, BIND_AUTO_CREATE);
Finally, I have some code which try to get data from the service, but it generates a NullPointerException. I know that's because (as I see with logs) the service starts after the app has crashed, although I put startService and bindService before the accessing data code.
Anyone knows how can I ensure to get loaded data before trying to access it?
Thanks in advance.
It might be easier for you to save your common resources in SharedPreference, The SharedPreference is accessible by all threads of your application, and is persistent between runs. This depending on what your resources are.
If you want your services to work for your method you could do this with a transparent Activity. AsyncTask might be an easier and simpler solution though.
Try to load your data with an AsyncTask, you can choose whatever you want what the Activity does while loading (Progress dialog? ) and make sure you continue your app using your data after when your AsyncTask calls the ready method ( onPostExecute() ). This means AsyncTask will replace your idea of a service as background thread, managing your resources. (loading, downloading, etc).
Also post your logs next time, they might help.
Start your Service in the onCreate() of a class that extends Application. Or even better, do the work the Service is doing in your Application class, which is guaranteed to be created before any other part of your app. A Service may take a while to start up and you may encounter a race condition, but the class extending Application is always the first part of an app to be launched.
I recently came across this problem and created a solution. Similar to the invisible activity, but the idea is to create a "loading" activity that does not need the service. Here is an example:
in AndriodManifest.xml:
...
<application
... >
<activity
android:name="com.example.LoadingActivity"
android:label="#string/app_name" >
<!-- A do-nothing activity that is used as a placeholder while the service is started. -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.MyActivity"
android:label="#string/app_name" >
<!-- The real activity, started by the loading activity. -->
</activity>
<service
android:name="com.example.MyService" >
<!-- The background service, started by the loading activity. -->
</service>
</application>
...
com/example/LoadingActivity.java:
package com.example;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class LoadingActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_loading);
super.startService(new Intent(this, MyService.class)); // listed first so it will start before the activity
Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // makes it so the 'loading' activity is not kept on the back-stack
super.startActivity(intent);
}
}
The MyActivity.java and MyService.java files are just standard. You also need an activity_loading.xml layout resource, probably just an ImageView.
I've been trying to find the solution for the following problem, but with no success:
I have an activity class that is showing web pages(presentation) which need to be logged (what user entered, duration, etc.). On some pages there are buttons which should open new presentation.
Calling activity - CLMWebView.class:
Intent intent = new Intent(this, CLMWebView.class);
this.startActivity(intent);
Between those lines of code are some intent.putExtra which are, I belive, not relevant for this.
As you can see, I am trying to start new activity with the same class as the calling activity. However, nothing happens. Any ideas?
EDIT:
Android manifest for CLMWebView.class
<activity android:name="com.msoft.views.CLMWebView"
android:configChanges="orientation|keyboard"
android:icon="#drawable/svicon"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.PICK"/>
<action android:name="android.intent.action.CHOOSER" />
<action android:name="android.intent.action.WEB_SEARCH" />
</intent-filter>
</activity>
singleTop activity, visible, and in same task is not recreated.
Quoting the official docs:
Similarly, a new instance of a "singleTop" activity may also be
created to handle a new intent. However, if the target task already
has an existing instance of the activity at the top of its stack, that
instance will receive the new intent (in an onNewIntent() call); a new
instance is not created. In other circumstances — for example, if an
existing instance of the "singleTop" activity is in the target task,
but not at the top of the stack, or if it's at the top of a stack, but
not in the target task — a new instance would be created and pushed on
the stack.
A better alternative will be to place the functionality in a fragment, and add a new fragment to back stack each time.
I have written a few Android apps, and have always declared a starting Activity as the:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
It would be great for scoping some global methods, statics, shared prefs, etc if I could start my app using an Application that then calls the first Activity from it's onCreate() after setting up prefs, etc, but I haven't been able to find any examples of this design pattern... when I try this in code, I get a ClassCastException:
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// do stuff (prefs, etc)
// start the initial Activity
Intent i = new Intent(this, InitialActivity.class);
startActivity(i);
}
}
InitialActivity.class is indeed an Activity that works fine if I set it to be MAIN, but trying to start it from MyApplication that is declared MAIN generates the error. Probably a very silly question, but am I tackling this all wrong?
Thanks,
Paul
You can fix this by using FLAG_ACTIVITY_NEW_TASK flag:
Intent intent = new Intent(this, ApplicationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
That's because you need to start new task when Activity is started outside of Activity context. But I strongly recommend to not start Activity from your Application's onCreate().
Android has 4 components: Activity, Service, ContentProvider and Broadcast.
When Android needs to activate one of this components from your application, it looks if there is already existing running process with your application. If not, then Android starts new process, initializes it, then it initializes your custom Application instance. And then it activates one of needed components.
Now, let's consider next scenario: your application declared content provider in AndroidManifest.xml, and Android just about to start your application so you can provide some data to another foreground application.
Content Provider request is sent
Your application wasn't running, and Android starts new process for it.
Your custom Application instance is created
Application.onCreate() is called.
You start an activity
Your Content Provider receives request
Somebody just wanted to connect to your content provider, but your application started an Activity instead. Same true for starting background Service and sometimes broadcast receivers.
And also consider if some other application's activity A wanted to started activity X from your application. But in onCreate() you started activity Y, and then X is also started by Android. Then user presses back. What should happen? Its tricky...
Starting activities from Application's onCreate may result in quite weird user experience. So don't do it.
UPDATE:
Because Android guarantees that Application will be created only once and before any other component, you can use next code to access your Application's single instance:
public class MyApplication extends Application
{
private static MyApplication s_instance;
public MyApplication()
{
s_instance = this;
}
public static MyApplication getApplication()
{
return s_instance;
}
}
Did you set it in you manifest activity tag for this intent you are starting (another one besides your main) ?
</activity>
<activity android:name=".InitialActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="com.package.INITACT" /> <--- this is only name by which you activity can be called.
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
I have three classes one main-activity(named MainMap), one non-activity class(named MyItemizedOverlay), and one activity class(named AudioStream).
I want to start AudioStream activity from non-activity class but i don't know how to.
i tried
this is in third class(called MyItemizedOverlay):
Intent myIntentA = new Intent(MainMap.this, AudioStream.class);
myIntentA.putExtra(AUDIO_STREAM,AUDIO_STREAM_URL);
MojProg.this.startActivity(myIntentA);
but it doesn't work, says: No enclosing instance of the type MainMap is accessible in scope
What should i do? What shoul i write instead of MainMap.this?
This isn't so much an Android question as it is a Java question. Unless you were to make "MyItemizedOverlay" an inner class of "MainMap" (see http://forums.sun.com/thread.jspa?threadID=690545), what you really need is for MyItemizedOverlay to store an internal reference to the MainMap object that it wants to use for the inent.
Regards,
Mark
Intent myIntentA = new Intent(MainMap.this, AudioStream.class);
myIntentA.putExtra(AUDIO_STREAM,AUDIO_STREAM_URL);
MojProg.this.startActivity(myIntentA);
This won't work. Because "this" means "this class". You cannot use it on another class (Yes, you can, but there are different ways for it. Please study on "this" at forums, this site or oracle web site.). It is the reason of that warning.
Well it looks like your question is "How can i pull the context to a non-activity class?". (First parameter of Intent() is Context).
To do this you can create a Context instant in your Main Activity and assign your base context to it like:
static Context context;
....
context = this.getBaseContext();
Don't forget that was your Main Activity. Then in your non-activity class, you can pull this context and use it with intent like:
Context context;
Intent intent;
....Constructor:
context = MainActivity.context;
intent = new Intent(context, YourSecondActivity.class); // you have to declare your second activity in the AndroidManifest.xml
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // this is required to call "Intent()" in a non-activity class.
//And then you can call the method anywhere you like (in this class of course)
context.startActivity(intent);
Ok. You are ready to go after one more step. In AndroidManifest.xml, declare your second activity like first one like;
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".YourSecondActivity"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
</activity>
You are ready now. But a last warning, dont forget to dispose your activity before opening another to avoid lagging.
Have fun.