I currently have three activities for my Android app, two of these are for logging in. The first is used for authorizing a device and requires the user to input more user information (FullLogin), the second is used once a device has been authorized (ReducedLogin).
The idea is to show the FullLogin activity all new users until their device has been authorized. The ReducedLogin activity will then show for all logins thereafter.
Is this possible and how would I go about doing this? I've seen some posts online for using/accessing values from a preferences.xml file but am not 100% sure if this is correct for my needs.
This scenario is formulated quite generally. There exist many possible solutions.
You could save the information whether a user is fully authorized on an external server and each time you start the app, you request the server and then show the corresponding activity.
You could store this information locally on the smartphone (e.g. in SharedPreferences), but for security reasons i would rather recommend the first way. One big advantage of local storage may be the avoidance of the additional internet permission as you don't have to request a server.
You could use cryptography to create a challenge that can only be solved by an authorized user.
You could combine these approaches.
You can't modify the manifest, and that's what's going to control what runs when the user presses your launcher icon.
What you can do is have a "router" Activity that inspects the state of the system and starts the real Activity you want. You do have to put in some extra effort here to ensure you don't get a screen flash between the router and real activity (starting with no animation, not setting a content view in the router, using a blank theme, and probably other things).
Another solution is to use fragments. The "main" activity just inspects the state and adds the correct fragment ... full or reduced.
Related
I made a small Google Home App and my service returns a response with a SimpleMessage + Card.
It works perfectly when running the app in the console.actions.google.com simulator. I get the card all good.
But when I test talking to the Google Home, it only sends the text, no trace of the Cards anywhere.
However If i talk to the Google home app on my phone, it does send the card correctly.
Is there something to enable to be able to receive cards sent by Google Home? Is it possible at all?
There is no way to make cards that were sent while the user is talking via Google Home visible, but there are several techniques that you, as a developer, can use if cards are necessary.
First of all - good design suggests that cards should be use to supplement the conversation, not be the focus of the conversation. Make sure the voice conversation itself is important and use the visual elements only when necessary. If your action is overly visual - it may be better suited as a mobile or web app, rather than an Action.
If your device requires a screen, then you can set this in the Action Console when you configure your question. This will, however, prevent it from being used on a Google Home device.
If you don't want to go this route, and want to allow it to be used on a smart speaker, but still take advantage of a screen where it is available, you have a few options.
First is that you can just send the cards. As you've discovered, they won't show up, but they won't cause any problems.
If you want to act slightly differently if a screen is available, you can check for the surface capabilities that the user's Assistant is capable of at that moment. If you're using the node.js library, you can have a command such as
let hasScreen = app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT)
to determine if a screen is available and take action based on the variable hasScreen. If you're using JSON, you need to check the array at surface.capabilities or data.google.surface.capabilities to see if "actions.capability.SCREEN_OUTPUT" is one of the available surfaces.
If not, and you get to a point in the conversation where you feel you need to send a visual result, you can also request to continue the conversation on a device that does support screen output.
First, you'll need to make sure that they have a screen available. You'll do this with the node.js library with something like
const screenAvailable = app.hasAvailableSurfaceCapabilities(app.SurfaceCapabilities.SCREEN_OUTPUT);
or by checking the availableSurfaces.capabilities or data.google.availableSurfaces.capabilities parameters in JSON.
If one is available, you can request to continue the conversation there with something like
app.askForNewSurface(context, notif, [app.SurfaceCapabilities.SCREEN_OUTPUT]);
where context is the message that will be said on the Google Home, and notif is the notification that will appear on their mobile device (for example) to let them continue the conversation. If using JSON, you'll need to use a actions.intent.NEW_SURFACE next intent.
Either way, the user will get a notification on their mobile device. Selecting the notification will start up the Assistant on that device and your Action will be called again with parameters that let you check if they are on the new surface. If so - you can send the card.
My app which pins multiple files at once on the home screen used to work pretty fine till Nougat. But Google changed internals in Oreo so those old methods of pinning shortcuts don't work but a new ShortcutManager class has been introduced. Read here.
Now even if I try, I can't pin multiple shortcuts at once using this class. I apply a loop and calls the defined method to requestPinShortcuts but it only accepts only one shortcut and ignores others. So I wonder if I missed something in the documentation. Is there some way out?
Document:ShortcutManager
It's up to the launcher to decide how to handle previous pending requests when
the same package calls this API multiple times in a row. One possible strategy
is to ignore any previous requests.
If adding pin shortcuts in loop, launcher may only accept 1st or latest request. It depends on devices. So the question is going to how launcher recognize different request window. It is recognize by different foreground component. If different foreground components sending request, launcher accept all requests. Even it is almost send in the same time.
Some launchers may not show dialog to ask if user agree adding shortcuts. Some launcher show dialog. Even you sends multiple requests, user may not have enough time to agree all your requests.
I'm curious about this. I have an app called GoSMS PRO and an app called Contacts+ installed in my phone. They both popup an alert notification when a text message is received. However, GOSMS PRO always beats Contacts+'s popup. I was wondering how this was happening in a programming perspective? Is there a way to give a certain app more preference than the other.
From security and permission side every app from Google Play has similar privilege, if they are not signed by the certificate of device manufacturer. This also means that none of the app will get extra preference.
Some time app do many type of checking/initialization/loading before showing their UI and when this type of things happens apps take longer period to load or display UI.
Most common things people do
Creating and initializing database
Reading database.
User validation (reading file)
Device state scanning(network)
Most common case is database access. I wonder if the app reading Content Provider before showing UI it might take long time depending on your device hardware and number of contacts.
Key strategy would be showing the UI right way and load data in background. Android has lots of Asynchronous api, just to avoid this type of scenario.
I would like to secure settings tab on lenovo tablet device with a password. What is a simple way of going about this? Code is welcome too (I think I might need to code but if you think an google play marketplace app would solve my problem please post your suggestion below).
Edit: I have researched and posted on lenovo forums already which I always do before posting here and it takes them a week just for simple question sometimes to respond.
Please if iam too vague say so below because -2 does not help me one bit.
Here's more more information for why iam trying to do this:
I work at a K-12 system with high students always testing my wits.
Without the password kids/students can add their own account or change settings for the tablet doing things that could hurt the school system legally (download playboy, using the devices to distribute viruses and malware, and the list goes on
Unfortunately for the purposes of what you're doing, Android doesn't really allow for keeping the "primary user", so to speak, out of the settings application. I'm not personally aware of any existing "lock" type applications, but they might exist; you might be better off asking on Android Enthusiasts for that.
There are a few hack-y type things you can do programmatically, however, without modifying the OS. The one I've seen work the most effectively for similar tasks is to code a Service with a Thread more or less continuously polling the ActivityManager for a list of running tasks (getRunningTasks()), checking on fixed intervals (perhaps once a second?) then, if the unwanted Activity is detected in the foreground (I believe that the Settings app component name is android.app.Settings), Launch a Password Activity. If the user successfully authenticates, simply finish() the password Activity. Otherwise, start the home activity (effectively clearing the Activity stack) with an android.action.HOME intent
I need my app to be the default action for opening a particular file type. How do I control this? Also, how can my app access the file being opened?
Thanks.
Have a look at android.content.Intent.
An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed. The primary pieces of information in an intent are:
action -- The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, etc.
data -- The data to operate on, such as a person record in the contacts database, expressed as a Uri.
Your activity can obtain the Intent that launched it by calling Activity#getIntent() and then use Intent#getData() to determine the URL of the data to open.
Your manifest should specify that one of your activities can view a specific type of data using an <intent-filter> element. If the user attempts to view this kind of data, the system will figure out which activity across all apps on the system should get to handle it.
If there is only one app capable of viewing the data it will be launched automatically. If more than one app can handle the intent, the user will be presented with a dialog asking which app they would like to use, along with a checkbox for making that choice the default for next time. Users can clear defaults from the systemwide Settings.
As Aidan noted there is no way to hijack the default. The user must choose to make your app default for handling that type of data.
As far as I'm aware you can't enforce it upon the user to make YOUR application the default for opening a particular file extension. The user must choose to make your application the default. As for the second question I don't know but thought I'd provide a partial answer. :)