Reorganizing activities in different folders - android

I want to change the structure of my android application to have the activites in a subfolder called activities. So, my code structure will become
com.example.myapp.activities.MainActivity
and all the activities will reside within com.example.myapp.activities
How do I achieve this ? Also, What changes will have to be made in the manifest for this to work ? How will I access other activity classes from within other activities ?
<activity
android:name=".activities.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>
EDIT : I achieved this using dragging and dropping the activities in the folders but now I am getting this error on setContentView(R.layout.main); : main cannot be resolved or is not a
field

If you organize all activities in same packages, then you have to define the activity without package declaration in Manifest file, example
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp.activities"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:name=".WorldClockApplication"
<activity
android:name=".WorldClockHomeActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".AddLocationActivity"/>
<activity android:name=".EditPreference"/>
</application>
</manifest>
Then you should call that activity inside another activity using intent. Consider I'm calling WorldClockHomeActivity from WorldClockApplication activity as follows:
Intent myIntent=new Intent(WorldClockApplication.this,WorldClockHomeActivity.class);
startActivity(myIntent);
Then do clean, refresh your project you wont get error in your project. If get error on
setContentView(R.layout.main);
that means you have problem in res/strings or res/layout or res/drawable folders not in manifest file

If you are using Eclipse create a new packet in your project and drag and drop your activities files in there. Eclipse will take care of all the necessary changes.
The changes are in your directory structure and in the manifest as you have posted in the question.
Activities can be launched (or new Intents can be sent to them) as usual through Intent(context, YourActivity.class);
I wouldn't move the activities though, rather I'd organize other Java classes in separate packages.

Related

Manifest file structured in android studio for different activities

I want to know how to set multiple activities by using different layouts and through intent filters
How to set pages in application and what we have to specify in section of activity in manifest file for action and category for different pages of activity.
Please help me on that. What should I follow, So that I can make proper flow of my application.
Any suggestion or references for the same would be appreciated.
Mainifest.xml is having more information about application.
Activity defining is also one part of Manifest.xml, So define all the activities which are used in your app flow here. Main launcher activity will have tag with action - MAIN and category type - LAUNCHER. And other activities are defined in a simple manner.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.LauncherActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.ActivityA" >
</activity>
<activity android:name="com.example.ActivityB" >
</activity>
....
</application>
There are several other attributes that you can include in this element, to define properties such as the label for the activity, an icon for the activity, or a theme to style the activity's UI.
Follow for more: Activity
Labels in Activity: Activity labels in Manifest.xml

How to use a different launcher activity in a product flavor?

I'm working on an Android library project, in the default src/main/AndroidManifest.xml, the MainActivity is the launcher activity.
For the sake of something else, I created product flavors. Yes, it works perfect if I want to trigger / show different activitis inside different product flavors. However, I wanna keep the default launcher activity from src/main/ folder, while register another flavored activity as the new launcher activity. So that for different product flavors, I could have different launcher activities, and from them I could still start original "launcher" activity in src/main/.
Could anyone kindly tell me how to achive that? Thanks a lot.
Notes:
Adding if (BuildConfig.FLAVOR.equals("flavorName")) code to original launcher activity is not prefered. Because I don't want to modify the production code from someone else (this is a library project).
I've tried manifestmerger and tools:replace, but seems like it doesn't work for intent-filter (I noticed that the element merging policy for intent-filter is always).
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
If this may work, could you please kindly guide me how to make it work? Thanks.
What I have tried:
Enabling Manifest Merger, which doesn't work;
Using activity-alias, which doesn't work either.
Finally I found out that the problem could be solved by just adding one line:
<category android:name="android.intent.category.DEFAULT" />
==================================================
To make it clear, I'll go through the problem and solution one more time:
Under src/main/java there is a MainActivity, and in corresponding src/main/AndroidManifest.xml it specifies MainActivity as the launcher activity:
<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>
That is a very easy part. Now we start with the product flavor part.
Due to some reason, in a product flavor, I don't want to overwrite the MainActivity, instead, I have a YetAnotherMainActivity. The goal is to set the YetAnotherMainActivity as the new launcher activity in the product flavor, and it should still be able to call MainActivity.
And here, is how you can set the new activity in product flavor as the new launcher activity:
flavorX/AndroidManifest.xml:
<activity android:name="com.example.YetAnotherMainActivity"
android:label="#string/title_yet_another_main_activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Yep, it turns out deadly easy. Just add android.intent.category.DEFAULT.
I think that <activity-alias> fits there more than any other solution (have no idea why #JingLi couldn't get it working. Maybe there were some troubles year ago, but for now it's okay).
For example, we have the following manifest in main:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.application">
<application>
<activity android:name=".InfoActivity"/>
<activity-alias
android:name="com.example.application.Launcher"
android:targetActivity=".InfoActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
</application>
</manifest>
And we want to replace launcher activity with DebugInfoActivity from debug flavor. So, we need to just replace the targetActivity attribute in the specified <activity-alias> tag:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name=".DebugInfoActivity"/>
<!-- to not litter the manifest -->
<activity
android:name="com.example.application.InfoActivity"
tools:node="remove"/>
<activity-alias
android:name="com.example.application.Launcher"
android:targetActivity=".DebugInfoActivity"
tools:replace="android:targetActivity"/>
</application>
</manifest>
Notes:
In the example we use the same package name for main and debug.
We have to enter the full name for activity-alias, so the merger can merge their correctly.
With the solution we also can inherit all attributes and childs from main activity-alias to not duplicate their in debug.
I guess I am not late :)
So today I got the same problem. #seroperson solution was correct but If you do not want the default launcher activity at all then just use the below code in your flavor's manifest:
<activity
android:name=".DefaultLauncherActivity"
tools:node="remove"
>
Android merger is merging intent-filter from main manifest lancher to flavors. I have not found way to prevent that. You end up with 2 app icons on device (each for launcher Activity).
Based on that, you cannot override completely settings from main manifest. Solition may be to keep only shell of manifest in main folder and implement manifest in each flavor or to remove conflict Activities from main folder and implemenent independently in each flavor.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.adamassistant.app">
<!-- empty shell, implementation in flavors folders -->
</manifest>
The simplest and cleanest solution is to keep only one Manifest and write two different MainActivity.java class one for each flavor in order to avoiding duplication of manifest nodes.
Given two flavors in gradle
productFlavors {
paid {
packageName "com.example"
}
demo {
packageName "com.example.demo"
}
}
Given this project structure
app/
|--libs/
|--src/
|--paid/
| |--java/
| |--com/example/
| |--MainActivity.java
|--demo/
| |--java/
| |--com/example/
| |--MainActivity.java
|--main/
|--java/
| |--...
|--res/
| |--...
|--AndroidManifest.xml
And this Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.flavors">
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<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>
</application>
</manifest>
Create a different AndroidManifest.xml file in your flavor. And there set your DifferentFlavorMainActivity.java as the launcher activity with full name like:
android:name="com.android.application.paid.MainActivity"
The working simplest solution is to use manifest merging and using
<intent-filter tools:node="removeAll">
as suggested in the following post :
Merging android manifest files, conflicting filter

Android Intent problems

I'm having an issue trying to go to a specific class within my android application using the Intent.
This is my code setup:
Intent Secondscreenintent = new Intent(this, Secondscreen.class);
The error that it gives me is
android.content.ActivityNotFoundException: Unable to find explicit activity class {/project10.aventus.quiz.Secondscreen}; have you declared this activity in your AndroidManifest.xml?
After looking at my manifest I could not see any mistakes that would indicate this message.
<activity
android:name=".Main"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="Quiz">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Secondscreen"
android:label="Secondscreen" />
<activity
android:name=".Quizclass"
android:label="Quizclass"/>
These are within the tag within the tag.
But somehow I'm still getting the class not found error. I have even tried to refer the intent to the Main.class and this has given the same error that it cannot find the Main class.
Does anyone have an idea on how to fix this?
Thanks,
Shams.
In you AndroidManifest.xml you will find some thing like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="project10.aventus.quiz"
android:versionCode="1"
android:versionName="your_version_code">
...
</manifest>
package defines the root of your implementation. So you don't have to write the full path name if you define Activities, BroadCastReceiver etc...
So you do it in this way:
<activity
android:name=".Secondscreen"
android:label="Secondscreen" />
This entry means - you will find my Secondscreen.java in my root folder aka package. In your case it would be project10.aventus.quiz.
So i quess your Secondscreen.java is not there. I'm creating allways a new subpackage ui in my root folder, so my activity entry looks like this:
<activity
android:name=".ui.Secondscreen"
android:label="#string/second_screen"
android:screenOrientation="portrait" >
</activity>
Now, this entry means - you will find my Secondscreen.java here: project10.aventus.quiz.ui.Secondscreen.java

Starting an Activity First in Android?

I'm having an issue starting activities in order, and I don't know if it is an issue in the manifest or in the code. I tested this code a while ago when it was working, but now it's not.
The first activity links to the second, which links to the third. I listed the first activity first in the manifest. However, when I start my emulator, it's the second activity that runs first. I am very confused. Here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hmdywifinal.com"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".Activity1"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Activity2"
android:label="Startpage">
</activity>
<activity android:name=".Activity3"
android:label="Activity3"></activity>
</application>
Do you think something is wrong with it?
Make sure you are running your program from Activity1 and not from Activity2.
If you run it from Activity2 it will skip Activity1 even though you have your manifest set like you described above.
Order in which Manifest file declares Activities has nothing to do with the runtime order.
First Activity gets launched from a Launcher ( which is Activity1 in your case )
I am assuming you are launching Activity2 and 3 using Intents in your code. So you are in control on the way these activities get launched.
Refer to the api Demos, Which has got a similar application Proof Of Concept. It will give you a better idea on mving from one application to other.

How do I load an Activity from within a Library?

I've got a projected marked as "Is Library" - it has all the activities. I've got a new Android project that references this library. How do I mark one of my library's activities as the first one that starts up?
EDIT
My original manifest looks like this:
<activity android:name=".Welcome" android:label="#string/app_name" android:theme="#android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
All my activities are in the package com.rjs.animator.
As long as you AndroidManifest.xml contain those Activity tag and reference to the correct namespace/class within your Library, you should be good to go.
You have to add all activities and other components to the new Android project's manifest, with whatever <intent-filter> elements you want. Just put the standard MAIN/LAUNCHER <intent-filter> on whichever activity you want.

Categories

Resources