How to use WindowManagerPreference:FreeformWindowSize and WindowManagerPreference:FreeformWindowOrientation - android

I'm puzzled about how to use WindowManagerPreference:FreeformWindowSize and WindowManagerPreference:FreeformWindowOrientation mentioned in the official Android on ChromeOS guide.
When I use it, it seems like the window is always maximized, e.g. if I set it up like this:
<meta-data android:name="WindowManagerPreference:FreeformWindowSize"
android:value="phone" />
<meta-data android:name="WindowManagerPreference:FreeformWindowOrientation"
android:value="portrait" />
If I at the same time specify layout for an activity and starts it directly, the window is not maximized anymore.
Does anyone know how the two meta tags can be used? When I google them, the only results is the guide mentioned above and a few other projects using them.

I am seeing the same. Adding these parameters seems to have no effect on Chrome OS.

Answer for a Xamarin context, and with a different meta data option. (Although technique should work for all development environments)
Note the metadata needs to be under the Activity element in the AndroidManifest.xml
Using C#/Xamarin one can add the MetaDataAttribute to main Activity.
[MetaData("WindowManagerPreference:SuppressWindowControlNavigationButton", Value = "true")]
[Activity(Label =...
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
This removes the backbutton from android apps running on chromeos, but has no effect on android apps running on android devices.

Related

In which lifecycle method are manifest properties applied to activity? and are those inherited from other extending activities?

We know that xml layout code gets parsed to java view object in setContentView call. But I was just curious to know when are the manifest properties (like windowSoftInputMode, screenOrientation etc) are applied to the activity. I mean what lifecycle method?
Any practical explanation is more than appreciated, TIA!
Well, I think manifest will get attached to the app in its installation period. like when we start installing an app , it will read its manifest file to check ;
where to install
What permissions to show
which activity is a launcher for the app
for more information:
https://developer.android.com/guide/topics/manifest/manifest-intro

ActivityView and launching activities on secondary display

I'm trying to display (as a system-level application) multiple activities. There's an hidden AOSP class called ActivityView meant to do just that. Here's how you would use it, as far as I understand:
findViewById(R.id.view1).setCallback(object: ActivityView.StateCallback() {
override fun onActivityViewReady(view: ActivityView?) {
view?.startActivity(InnerActivity.getIntent(view.context, "my extra"))
}
override fun onActivityViewDestroyed(view: ActivityView?) {
// Cleanup
}
})
Note that the inner activity has to be declared with the attribute allowEmbedded set to true. It is in my case. My application also has the permission android.permission.INJECT_EVENTS (and is built as a system application, with the ROM certificate and installed in /system/priv-app)
Now, for the problem: when I call startActivity, the inner activity is displayed as a new activity on the stack, like any standard Context.startActivity call would do (the ActivityView.startActivity method actually does exactly that, but adds some options to the bundle before that, to display the activity on a virtual display). I also have a system Toast displayed that tells me that my App does not support launch on secondary displays.
In regard to this Toast, I tried giving my application the android.permission.CAPTURE_SECURE_VIDEO_OUTPUT permission, to no help.
I'm probably missing something related to the virtual display, but I can't see what…
(I know ActivityView is hidden, and that actually could be a bug, I'm just being curious of what it can or cannot do.)
I have already used ActivityView successfully on Android 9 (Pie). I noted some key points that you can refer to use ActivityView.
The application which use ActivityView need to be private application (installed in /system/priv-app) and must use system uid (declare in AndroidManifest.xml) as below
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.packagename"
android:sharedUserId="android.uid.system">
Noted that you need to replace "your.packagename" by package name of your application
You need config Android framework to support secondary display by copy file android.software.activities_on_secondary_displays.xml to /system/etc/permissions/
Content of android.software.activities_on_secondary_displays.xml
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<feature name="android.software.activities_on_secondary_displays" />
</permissions>
You should config in makefile to copy this file in building process of Android image from source code using PRODUCT_COPY_FILES
Enable resizeable mode and using singleTask for the Activity need to be placed inside an ActivityView
In AndroidManifest.xml
<activity
android:name=".YourActivity"
android:resizeableActivity="true"
android:launchMode="singleTask">
You must add these two attributes to the Activity tag in your manifest for any activity which should be allowed to be placed inside an ActivityView:
android:resizeableActivity="true"
android:allowEmbedded="true"
As you know, this is not documented, since ActivityView is not part of the Android SDK.
In my case I was using Flutter and its PlatformView API to display ActivityView as a widget. Unfortunately, both ActivityView and PlatformView are using virtual displays as the underlaying technology, and maybe it's not possible to show one virtual display inside another.

Android Application without Classes?

I have seen a JS talk about Redux recently. The speaker programmed a working application without any classes, just with const variables. He even excluded classes in his lint file (https://github.com/MartinSeeler/redux-presentation/tree/master/demo).
So I tried to do the same in my Android apps, which are written in Kotlin. Unfortunately, I get the following error when I try to make my MainActivity class an object:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{blog.app.niklas.flyingbytes/blog.app.niklas.flyingbytes.MainActivity}: java.lang.IllegalAccessException: void blog.app.niklas.flyingbytes.MainActivity.<init>() is not accessible from java.lang.Class<android.app.Instrumentation>
Caused by: java.lang.IllegalAccessException: void blog.app.niklas.flyingbytes.MainActivity.<init>() is not accessible from java.lang.Class<android.app.Instrumentation>
Is there a way to work around this? I really like the idea of having as many singleton objects as possible in my app.
Thank you in advance,
Niklas
You can't replace Activity class by kotlin object on Android, for the same reason you don't instantiate Activities by calling it's constructor:
activities are managed by the platform.
When you ask (via an Intent) the platform for an Activity, the platform will try to instantiate it by calling it's constructor with zero parameter. Which doesn't exist for an object, giving the mentioned error.
That's said, some developer dodge around the frame given by Android, like mortar, by having only one activity and using custom logic for navigation between views.
As Geoffrey said, the Android platform manages your activities, but that also means that the platform is responsible for keeping track of your Activity's instances - which is the purpose of Singleton.
So, while you can't make your Activity an object, you can still make it a Singleton by using the android:launchMode attribute in your AndroidManifest:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleInstance">
For more information on the launchMode attribute (including other possible values), check out the Official Documentation

Android application vs activity in the manifest

In Android Studio there is a manifest file where I can give attributes to either the application tag or the activity tag.
I'm just struggling to understand what the difference is between these two things.
In a tutorial I followed, orientation was fixed by forcing Portrait at the activity level. Why not do this at the application level?
What is the difference between giving a label attribute at the application level vs. the activity level? Or both?
There is no option to force screen orientation on <application>.
The label on <application> controls things like how your app appears in Settings in the list of installed apps, or any other place where we deal with things at the app level. It also is the default label for activities. Activities can specify a separate label, overriding the application-level default, if they so choose.
Starting with Question 2:
The manifest is the dictionary/table of contents for your android app, one of the first files that are looked at by the system when the your app is loaded/started is the manifest file
application and activity are totally different things
The application tag is your whole app overall(think of it as a Book), and the label in the application is your app title/name (Book title)
The activity tag is your context/content of your app (your Book chapters/sections), so when you define label for your activity as if you are naming that Chapter (example Chapter 1).
Summary: The application (book) must at least have label/title, and so activity/chapter, and sometimes your activities/chapters don't have titles but would be not good practice.
Question1: Its part of the Android framework (rules) that you have to specify what on the activities (chapters) level 1 by 1 not application (Book) level

App with multiple .action.MAIN

I have an app ready and working well, and now I want to add a widget to it. The thing is, Im not sure, if I am doing this thing right, because:
my widget would have 4 buttons, each starting a different activity from the original app
Im aware of the additional neccessary initializations, this thing would cause, since 3 buttons would start 3 activities, that would skip the main activity
I did add the .action.MAIN tag to my manifest, to the corresponding activities, thus I can access them
Is this the correct way to do this? Or is there any other, recommended way? The tag that I added to the manifest:
<action android:name="android.intent.action.MAIN" />
EDIT: forgot to mention in the original post, that the widget is a completely separate app, you would have to download it separetely from the market.
I did add the .action.MAIN tag to my manifest, to the corresponding activities, thus I can access them
That's not a good idea, as nothing can then distinguish between them (such as your buttons in your app widget). Either use unique actions (good) or hard-wire in class names to the activities in your app widget code (not so good).

Categories

Resources