How to access the Class of the Activity defined in parentActivityName - android

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.

Related

Meaning of this line of code in android given below...?

startActivity(new Intent(this, Class.forName(getPackageManager().getApplicationInfo(getPackageName(), 128).metaData.getString("com.sadaf.javafiles.MAIN_ACTIVITY_CLASS_NAME"))));
This code is to create and add another activity to the top UI level
startActivity()
Can be called from any context/activity, mostly used like
finish()
startActivity(new Intent(this, NewActivity.class));
This is used to close the current activity and begin the next
For a more detailed explanation please refer to :
https://developer.android.com/training/basics/firstapp/starting-activity#BuildIntent
startActivity(new Intent(this, Class.forName(getPackageManager().getApplicationInfo(getPackageName(), 128).metaData.getString("com.sadaf.javafiles.MAIN_ACTIVITY_CLASS_NAME"))));
The intent requires a context and a class as parameter, the context is “this” (the current context from the activity that is currently being displayed)
The class is from Class.forName(String) which requires a String value to get the class name from an activity
It gets that String value from calling :
getPackageManager().getApplicationInfo(getPackageName(), 128).metaData.getString(stringKey)
stringKey is the from the projects AndroidManifest.xml file android:name:
<activity android:name="com.sadaf.javafiles.MAIN_ACTIVITY_CLASS_NAME" >
</activity>
So essentially what that piece of code is doing is getting the .class of your declared “main activity” programatically instead of using the “standard” way of just going MainActivity.class

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>

Launch Main Activity with Implicit Intent in Service

I have an implicit intent in a service that sends information to my main activity, as well as to another class. I also now want that intent to launch my main activity. I've looked at the myriad posts related to this, and tried lots of different things--addCategory, setAction(MAIN; the activity's name; you name it, I've tried it...), category.DEFAULT in the manifest, and several other things that either resulted in ActivityNotFoundExceptions (most commonly) or behavior that was otherwise undesirable.
Here's where the intent is set up and the relevant part of the manifest. The receiver for the intent is registered in the main activity.
final String NEW_DOSES = "changed to protect the innocent";
Intent bluetoothBroadcast = new Intent();
several putExtra lines here
bluetoothBroadcast.setAction(NEW_DOSES);
sendBroadcast(bluetoothBroadcast);
<activity
android:name=".AsthmaAppActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Is it possible to get this intent to launch my main activity with relatively minor changes? Thanks in advance.
Yes it is possible but no with sendBroadcast(bluetoothBroadcast); sendBroadcast does not launch an activity. You must use startActivity to achieve this. For example here is what a launcher application will do in order to launch an application:
public static void LaunchApplication(Context cx, String packagename) {
PackageManager pm = cx.getPackageManager();
Intent i = pm.getLaunchIntentForPackage(ai.packageName);
if (i != null) cx.startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
You can easily adjust the extras and the data needed in order to launch the activity. For example if your activity is named myActivity then you can go like this:
Intent i = new Intent(cx, myActivity.class);
//Put the extras and the data you want here...
//If you are launching the activity from a receiver component you must use
//i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
cx.startActivity(i);
Hope this helps...

Can multiple Activity declarations share the same class name?

For example
<manifest>
<activity android:label="MyActivity1" android:name=".MyClass">
</activity>
<activity android:label="MyActivity2" android:name=".MyClass">
</activity>
</manifest>
Yes and no. When you prepend the Activity name with a ., it looks at the Manifest's default package to get the whole class path, such as com.example.android.MyClass. Thus, if instead you have one .MyClass and another com.example.android.other.MyClass, then this should work.
<manifest>
<package="com.example.android">
<activity android:label="MyActivity1" android:name=".MyClass">
</activity>
<activity android:label="MyActivity2" android:name="com.example.android.other.MyClass">
</activity>
</manifest>
I'm not 100% sure if this is possible, but perhaps there is a better way to go about this. If you need the same activity you can call it in both situations like you normally would but pass in data during the call as well. In your MyClass you can read the data and decide how to handle it.
Example:
//Activity 1
Intent i = new Intent(this, MyActivity.class);
i.putExtra("open", "activity1data");
startActivity(i);
//Activity 2
Intent i = new Intent(this, MyActivity.class);
i.putExtra("open", "activity2data");
startActivity(i);
And in MyActivity do something like this in onCreate()
Intent intent = getIntent();
Bundle extras = intent.getExtras();
String action = intent.getAction();
if(extras.containsKey("open")){
if(extras.getString("open").equals("activity1data")){
//DO activity 1 stuff
}
}
This is a pretty rough example, you could use ints and switch on those etc. But the real goal is to let one activity handle a variety of cases. This seems to be what you want since your going to use the same class anyway.

Using Intent from non-activity class

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.

Categories

Resources