Using Intent from non-activity class - android

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.

Related

How to access the Class of the Activity defined in parentActivityName

For every activity which has a logical parent we define that parent Activity in the Manifest like so:
<activity
android:name=".ui.activity.MyActivity"
android:label="#string/activity_title"
android:parentActivityName=".ui.activity.ParentActivity"
android:theme="#style/My.Theme" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.activity.ParentActivity" />
</activity>
Is there a way to access the Class referenced in either #parentActivityName or meta-data#value in MyActivity?
(Please note that I don't want to access the parent Activity instance, just the Class)
The reason is that for tracking purposes we want to generate a path-like String for each Activity. In this case this String would be /parent_activity/my_activity – and since the hierachy is already defined in the Manifest, best case would be to access it there then to define it twice.
Thank you for your help!
Maybe it will help you NavUtils.getParentActivityName(childActivityInstance)
You could always go with the easy way: Pass the parent activity name in intent extras as string, in ParentActivity
Intent intent = new Intent(ParentActivity.this, ChildActivity.class);
intent.putExtra("parent_activity_name", "ParentActivity");
...
startActivity(intent);
And then get it in the ChildActivity activity
Intent intent = getIntent();
String parentName = intent.getStringExtra("parent_activity_name");
Not sure if there is any other more elegant solution.

How to start an activity in an android Application from the Library

I have an Android application in Android Studio. And I've added a library into the application. The button, view, and activities are defined in the library. When I click on the button, I need to navigate to the activity defined in the application.
Usually, to navigate to another page, we used the intent, like this:
Intent intent = new Intent(MainActivity.this, Activity.class);
startActivity(intent);
But this is not a sufficient method to call the activity of the application from the library.
The problem is that the library and the application are independent; they have different packages. So the activity in the application cannot be recognized by the library.
How do I handle communication between the library and the application?
The normal way for doing this is to do this:
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.my.package","com.my.package.activity.ActivityName");
startActivity(intent);
This is an explicit reference to an activity within your library. You should ensure that when starting this Activity that you catch the ActivityNotFoundException as this can happen when the Activity does not exist in the system.
Ideally when building this Intent you should insure that you can resolve it by using PackageManager APIs.
However you should try to avoid hardcoding packages, but when it comes to a library, sometimes you don't have a choice.
Also one thing to note is that within the library you need to ensure that the Activity is exported so that you can access it outside of your application.
android:exported
Whether or not the activity can be launched by
components of other applications — "true" if it can be, and "false" if
not. If "false", the activity can be launched only by components of
the same application or applications with the same user ID. The
default value depends on whether the activity contains intent filters.
The absence of any filters means that the activity can be invoked only
by specifying its exact class name. This implies that the activity is
intended only for application-internal use (since others would not
know the class name). So in this case, the default value is "false".
On the other hand, the presence of at least one filter implies that
the activity is intended for external use, so the default value is
"true".
This attribute is not the only way to limit an activity's exposure to
other applications. You can also use a permission to limit the
external entities that can invoke the activity (see the permission
attribute).
Ref
http://developer.android.com/guide/topics/manifest/activity-element.html
Include the activity in AndroidManifest.xml.
To access an activity from any other project the easiest way is to
pass the whole class name (including package, e.g;
"com.myproject.MainActivitiy")
Calling from your library :
Intent intent= new Intent("com.myproject.MainActivitiy");
startActivity(intent);
And in your project manifest declare it like this
<activity
android:name="com.myproject.MainActivitiy"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.myproject.MainActivitiy" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
In this case, Intent can be used by providing the full class name including the package.
Let us suppose your current Activity class is MainActivity.java with package name com.app.myproject.
And you want to navigate to another Activity with class named Activity.java that is in another package com.app.external.
Include com.app.external.Activity.java in the manifest of your current project/library.
<activity
android:name="com.app.external.Activity"
android:label="#string/title_activity_login"
android:screenOrientation="portrait">
</activity>
And your Intent should be like this -
Intent intent = new Intent(MainActivity.this, com.app.external.Activity.class);
startActivity(intent);
In this case use Implicit Intent
Inside library Activity TESTActivity :
Intent intent = new Intent();
intent.setAction("com.myapp.myimplicit_action");
startActivity(intent);
and here is my manifest file declaration for some activity say 'ImplicitActivity' with the same action
<activity android:name=".ImplicitActivity">
<intent-filter>
<action android:name="com.myapp.myimplicit_action" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

How to Add Air Native Extension to Stage

I need to display an Activity written in Java using the Android SDK in my Flex Mobile app. I've seen it done with Map ANEs, but cannot find any example code or anything of the sort. I've already created the Java and ActionScript code necessary for my ANE to work (the activity is created and all the classes, events, and methods needed to truly bridge the Java and AS3 is there), I just cannot figure out how to add it to the stage. I know it cannot be added to the DisplayList and I am fine with it being a stage object.
If it helps at all, I am trying to display video using MediaPlayer (due to MP4 streaming issues when it is done using AS3/Flex).
For Michael (Aug 27, 2012 # 9:44AM MST):
08-27 09:27:07.836: I/CS VideoInit(2567): context is set
08-27 09:27:07.836: I/CS VideoInit(2567): intent is instantiated
08-27 09:27:07.836: I/ActivityManager(349): START {cmp=air.AndroidANETesting2/xi.video.android.extension.VideoActivity u=0} from pid 2567
The very first line of my Activity is
Log.i("CS VideoActivity","Made it inside the activity somehow");
Here is a look at my Java. This is the init function:
VideoInit.context = context;
Log.i("CS VideoInit","context is set");
Intent intent = new Intent( context.getActivity(), VideoActivity.class );
Log.i("CS VideoInit","intent is instantiated");
context.getActivity().startActivity( intent );
Log.i("CS VideoInit","Activity is started");
context.dispatchStatusEventAsync("PLAY", "PLAY");
And here is my VideoActivity onCreate():
super.onCreate(savedInstanceState);
Log.i("CS VideoActivity","Made it inside the activity somehow");
And my Manifest for good measure (just the application section):
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".VideoActivity"
android:label="#string/title_activity_video" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Update (August 27, 2012 # 10:52AM MST)
After further investigation (or trial and error, whatever you want to call it), I decided to throw the startActivity() line into a try{}catch(Throwable e) to see what, if any, errors it was throwing. Interestingly enough, it threw this.
08-27 10:49:41.406: I/CS VideoInit(7786): Unable to find explicit activity class {air.AndroidANETesting2.debug/xi.video.android.extension.VideoActivity}; have you declared this activity in your AndroidManifest.xml?
It would appear I need to recheck my Android Manifest file.
It's actually quite easy.
You need to create a class in an ANE that implements the android.app.Activity, then from a FREFunction, simply use the startActivity function of the base Activity instance from the FREContext.
So in a function, lets start an activity with an Intent:
public class ExampleFunction implements FREFunction
{
#Override
public FREObject call( FREContext context, FREObject[] passedArgs )
{
Intent intent = new Intent( context.getActivity(), ExampleActivity.class );
context.getActivity().startActivity( intent );
}
}
Then in the actual Activity implementation:
public class ExampleActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
// Do your stuff here, like create views, buttons etc
}
}
This activity will display ontop of your application. You can use a static reference to your FREContext to pass events / data back to your application if you wish.
You also need to add activity in your -app.xml inside manifest application-tag:
<application> <activity android:name="package.ExampleActivity"></activity></application>

ActivityNotFoundException invoking an inner-class activity

I have a non-Activity class (let's call it "NonActivity") that needs to post a message and get user feedback. I have a message activity (MsgActivity) class to do this. But only Activity classes can call startActivityForResult() so I made an inner helper class in NoActivity:
// just to provide an Activity to launch MsgActivity
class ActivityMsgClass extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent iMA = new Intent(this, MsgActivity.class);
iMA.putExtra("MsgText", mParams[0]);
...blah blah ...
iMA.putExtra("ButtonCode", iBtns);
startActivityForResult(iMA,3);
}
}
My Activity class is declared in the Manifest thusly:
<activity android:name="ActivityMsgClass"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:launchMode="singleInstance"></activity>
But when I try to invoke it . . .
Intent i = new Intent(ctx, ActivityMsgClass.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(i);
... I get an ActivityNotFound exception. I've also tried it without the FLAG_ACTIVITY_NEW_TASK, and I've also tried qualifying the name in the manifest, e.g.,
<activity android:name=".NoActivity.ActivityMsgClass"
. . . to no avail. What am I doing wrong?
Thanks in advance.
The technical solution is to specify the fully qualified activity path in the manifest.
The actual solution is to avoid doing this. Let activity be a public class, and not an inner class, this is just not good practice.
In your manifeast file change like below and try...
<activity android:name=".ActivityMsgClass"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:launchMode="singleInstance"></activity>
<activity android:name=".MsgActivity"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:launchMode="singleInstance"></activity>
your activity name declaration should start with a period. declare it this way.
<activity android:name=".ActivityMsgClass"
android:configChanges="orientation"
android:screenOrientation="portrait"
android:launchMode="singleInstance"></activity>
also make sure that the activity MsgActivity is also declared in the manifest.

Need gameover activity

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.

Categories

Resources