How do I switch between layouts properly? [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
So basically I am creating a very simple app that has only 2 layouts and I want to go from one to another properly. I know from what I have read that if you want to create a new screen/activity on the same project, you first have to create the new layout (which I already did), and I know that now I have to create the activity and do something to the manifesto, but I do not know what that is. I have seem some youtube videos about but I do not know if the fact that if I want my new activity to be the default one changes anything.
As you will be able to see in the attached pictures, "activity_questions" was the first layout that I had back when I created the project. Now I want to create a new screen/layout for the app which is the "noquestions_layout" one. However, I want to make the new layout that I created my main screen/activity for the user, and my "activity_questions" the one that will pop whenever my database feeds some information to the app.
How can I do all this? I know this is one of the things that you only need to learn once...and this might sound very simple, and I apologize if is something newbie. I basically started to learn android studio not too long ago.
You do not need to tell me all the code that I need to put in my app, just some basic examples with guidance... "create Y here, and then put X there"

For new screen layout create a new activity and call that layout file there.
To make any activity as your first activity when app starts, you have to go to manifest and cut paste the intent filter tag to the activity you want to start first
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Suppose you want to make another activity example .SecondActivity as starting activity cut above intent filter tag and paste it there like this
<activity android:name=".SecondActivity ">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity ">
</activity>

First Create two Activities, Say, Activity_A and Activity_B.
For the first activity, place this code in the manifest:
<activity android:name=".Activity_A">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
For the second activity, use this code:
<activity android:name=".SecondActivity ">
</activity>
Here, the Activity that launches when the app starts is the Activity_A, because of the intent filter in the manifest of the Activity_A:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
Now, Since you already have your Activities, the layouts ready, where Activity_A is started as soon as the app is started, to launch Activity_B from Activity_A, use this code:
Intent intentTour = new Intent(Activity_A.this, Activity_B.class);
intentTour.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); //This line is optional, better to use it because it won't create multiple instances of the launching Activity.
startActivity(intentTour);

When you create a new activity in Android Studio, Studio will create the corresponding resource file as well as manifest entry for your activity.
Say for example, you have two activities QuestionsActivity and NoQuestionsActivity. QuestionsActivity will be your default launch activity. To make NoQuestionsActivity your launch actvity. Open the manifest file and under activity tag of NoQuestionsActivity include the intent filter and remove intent filter from
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".QuestionsActivity"></activity>
<activity android:name=".NoQuestionsActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
To switch from one activity to another, say from NoQuestionsActivity to QuestionsActivity use intent the following code-
Intent questionsIntent = new Intent(NoQuestionsActivity.this, QuestionsActivity.class);
startActivity(questionsIntent);
If you want to pass value to QuestionsActivity pass it as extras in the intnet.
Hope this will help.

Related

The scope of loading a sub activity on onCreate()

I just need some information regarding the scope of execution. On my
To understand what is happening you need to know the Activity lifecycle
As you can see, when the app is launched, the first thing that's going to run is your onCreate() in this case, onCreate() has a method that inflates the view of your Activity, that method is called setContentView().
so, if you execute your code below setContentView, it will first inflate the view of MainActivity or the class you are in, and then just go to your other Activity.
If you want to start your Activity right when your app launches, just move your startActivity(...) above setContentView() in your onCreate(), but it will be better to do this in your manifest rather than just using a class to open another one.
To launch your WelcomeActivity just do this in your Manifest
<activity
android:name=".WelcomeActivity"
android:label="#string/app_name"
android:screenOrientation="sensorLandscape">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:screenOrientation="sensorLandscape"/>
<activity
So this
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
will define that WelcomeActivity executes first, then in WelcomeActivity do an intent to your MainActivity
Rather than load another activity within an activity, perhaps you should consider using a Fragment which are platform-defined modular sections of an activity with its own lifecycle and optional user-interface. See this for more info: https://developer.android.com/training/basics/fragments/fragment-ui
My advice would be to use support Fragments within your activity rather than another activity.

switching activities when 1 activity is out of memory

so I have an application with multiple activities. So when I switch from 1 activity to another and then click on the back button it works fine. But when I click on 1 activity then go out of the app and go back, it removes the main activity from memory so when you click on the back button, nothing happens. There are 2 possible solutions here, if there is somehow someway to detect if an activity is out of memory or if I can save the activity in memory. This is how I open the activity:
Intent intent = new Intent(context, QuoteActivity.class);
Gson gson = new Gson();
String quoteDataAsAString = gson.toJson(quoteData);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("QuoteData", quoteDataAsAString);
context.startActivity(intent);
And these are the 2 activities:
<activity
android:name=".MainActivity"
android:launchMode="singleInstance"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".quote.activity.QuoteActivity"
android:launchMode="singleInstance"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".user.UserFeedBackActivity"
android:launchMode="singleInstance"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
This is what I have in the main view:
#Override
public void onStart() {
super.onStart();
if (QuoteActivity.isChangedWithFavourites()) {
gridView.setAdapter(new QuoteImageAdapater(getApplicationContext(), reader.getCorrectData(currentSection), section));
QuoteActivity.setChangedWithFavourites(false);
}
}
A gif showing it: https://i.imgur.com/YZIkBU1.gifv
And this is how it should be: https://i.imgur.com/hghjB9L.gifv
This problem occurs on both activities even when I don't call the finish method.
Edit: I figured it out I had to change launchMode to singleTop
In Application class, You can override onLowMemory() method.
The documentation says,
This is called when the overall system is running low on memory, and actively running processes should trim their memory usage. While the exact point at which this will be called is not defined, generally it will happen when all background process has been killed. That is, before reaching the point of killing processes hosting service and foreground UI that we would like to avoid killing.
When OnLowMemory is called, Using EventBus you can trigger an event which should be caught by your Activity. Upon which you can perform your desired action.
If you looking to find, If the Activity has encountered OutOfMemoryException(OOM), then follow this answer.
How do I discover memory usage of my application in Android?

How to use non-main activity to capture custom url in unity game?

When someone clicks on a link in a webpage of form "com.foo.bar://testtest" I want it to open my unity game and for me to get the testtest data.
I'm an experienced programmer, but when it comes to android I kind of google my way around rather than really understanding anything. Bare that in mind. :)
I can react to links on android using intent-filters. However all the resources I've found have assumed you can extend your main activity to capture the new intent. It's possible to do that with unity, but for various reasons I'd rather not. I tried creating a new activity, exporting it to a jar, and adding this to my manifest in the application tag:
<activity android:name="com.foo.ProtocolCatcher"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="com.foo.bar" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
Clicking on a link successfully launches my game, but onto a black screen.
Edit: I've also tried this format to no change:
<activity android:name="com.foo.ProtocolCatcher"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="com.foo.bar" />
</intent-filter>
</activity>
What are the magic incantations to make the whole game boot, along with my custom activity, and let my custom activity read the incoming URL, without touching the main activity?
I suppose that you are missing a part of the boot sequence; the steps required are the following:
Define the ProtocolCatcher Activity with te proper scheme (OK)
Define the MainActivty, which represents your Unity3D game main Activity (OK)
Start the MainActivity when the ProtocolCatcher Activity gets started (MISSING)
Implementing the third step is super easy; just edit your ProtocolCatcher Activity's onCreate() method:
//ProtocolCatcher
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
Intent gameIntent = new Intent(this, MainActivity.class);
/*
//Pass the extra data to the game if needed
Intent sourceIntent = getIntent();
Uri data = sourceIntent.getData();
gameIntent.putExtra("uriData", data != null ? data.toString(): null);
*/
startActivity(gameIntent); //start the real game
finish(); //close the ProtocolCatcher activity
}
Considering the fact that you are "injecting" the ProtocolCatcher Activity manually, if you have problem to refer MainActivity from the ProtocolCatcher onCreate() you can lookup the relative Class using reflection.

Android:app creation malfunction(Implicit Intent)

I have two applications where the one opens by implicit intentthe other one.So in the first application I create an Intent and where I wrote i.setAction("com.example.secondApp");and I launch it through startActivity(i);
Then on the second app I change the manifest(filter) like:
<intent-filter>
<action android:name="com.example.secondApp" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
plus I do all the creation intent in the java section.
*code tested because everything was done by explicit intent in the first place and worked fine
So my point is when I try to run them both the first app installs nicely where the second one says that
No Launcher activity found!obviously cause I changed it but despite it installs it isn't shown on the phone nor the first App detects the second one,any clue?
*Also when I leave the manifest(filter) of the second app at default values it installs fine.
If you want an activity to appear in the launcher, it needs the appropriate <intent-filter>:
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
If you want that activity to have another <intent-filter>, that is fine. An <activity> can have as many <intent-filter> elements as needed.

Android homescreen shortcut permission error

In my program it adds a shortcut to the screen. I get the icon on the screen fine, but when I tap it, I get:
03-01 20:00:29.410: ERROR/AndroidRuntime(796): java.lang.SecurityException: Permission Denial: starting Intent { data=http://www.example.com/ flags=0x14000000 comp={com.isaacwaller.example/com.isaacwaller.example.ExampleCut} } from ProcessRecord{435c7398 796:android.process.acore/10005} (pid=796, uid=10005) requires null
Do you know the problem? Thanks,
Isaac
I had something like this happen when I had accidentally duplicated the activity tag for one of my activities in my manifest. I had something like this in my application section.
<activity android:name=".ConventionHome" 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="ConventionHome"></activity>
When I removed the second activity tag, things started working normally.
Figured it out, added this under <activity> tag of activity:
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
</intent-filter>
Something like this should work:
<intent-filter>
<action android:name="com.example.Project.Action"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
inside of the Activity declaration in the manifest.
I ran into this problem too, and it turned out it was because the Activity wasn't exposed to other processes. I had to add the android:exported="true" attribute to the activity tag in my manifest.
See http://developer.android.com/guide/topics/manifest/activity-element.html#exported for more information.
I haven't run into this personally but I did do some research and found the following.
Apparently whatever is attempting to invoke your app or if your app has a call to create an intent and start an activity of some intent the UID is not the same.
In ActivityManagerServer.java there are below judgement in it.
int checkComponentPermission(String permission, int pid, int uid, int reqUid)
// If the target requires a specific UID, always fail for others.
if (reqUid >= 0 && uid != reqUid) {
return PackageManager.PERMISSION_DENIED;
}
I'm going to do some testing on this and see if I can reproduce this in a test application and provide any additional feedback.
Make sure you are only trying to invoke publicly exposed activities through any intents.

Categories