Why do we need a UserHandle in many API declarations - android

In Android Open Source Project, a lot of core API declarations have an integer parameter userId in the end. I traced back and figured out the integer comes from a class called "UserHandle.java". There is a simple comments saying this class represents a user on the device. It still confuses me. Why do we need such a class? What's the difference between different values of the class, such as "USER_OWNER", "USER_CURRENT", "USER_CURRENT_OR_SELF"?
Thanks in advance!!!

Ever since Jelly Bean, Android platform has supported multiple users. This means that multiple users may be able to use one device, yet not be able to access other user's files or communicate with another user's app.
The first user on the device is user 0. The rest start their numbering from 10,11,... (In JB the numbering was 1,2...).
USER_OWNER is user 0.
He has some extra privileges over the other users (mostly access certain settings that others can't or uninstall an app for all users).
Multiple users on one device requires that only one user can be active in a specific point in time, this user is referred to as USER_CURRENT (since Kitkat().
In general one user's application can't send a broadcast message or an Intent to other user's apps.
Only apps with system permissions can do that (for example when the battery is running low, an intent will be sent to all).
Whenever you send an Intent from your app, the system service verifies whether this is a valid Intent i.e. if its supposed to reach all users then it's not.
This means that even if you were to use a certain api with the wrong userId (for example you force userId=0 even though this is user 10), then your call will receive a SecurityException.
To avoid such exceptions, there is also the option to send an Intent with USER_CURRENT_OR_SELF.
This means you're trying to send to the current user, but if he's not allowed to receive the Intent, let the same user who sent the Intent receive it.

Related

Best way to link a FCM token to a device?

I'm making a server that sends messages using FCM to clients depending on what happens (temperature and/or humidity change, a door is opened, etc.).
But if the token can change, how can I keep track of the device to send messages to the correct one (w/o using a login system)?
I was thinking to link the token to the sim iccid in a database, is this correct?
Use device's advertising id. It won't change unless the user manually changes it. Please check the thread How to get Advertising ID in android
Update 05/18/2017:
Starting Android O, ANDROID_ID will now be different per app per user in the device.
Original Answer:
If you're looking for a long lasting (possibly permanent) ID that you can use, I guess you can make use of ANDROID_ID:
String ANDROID_ID
A 64-bit number (as a hex string) that is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device. The value may change if a factory reset is performed on the device.
Note: When a device has multiple users (available on certain devices running Android 4.2 or higher), each user appears as a completely separate device, so the ANDROID_ID value is unique to each user.
Constant Value: "android_id"
However, there are still some factors that you should consider depending on your use-case. I recommend going through the Best Practices for Unique Identifiers documentation.
FCM wise, it is usually associated with a user, hence it is commonly paired with the user details.

How to persist data between app installs on Android?

I thought there would be some straight forward solution to this.
Requirements:
Uniquely identify device across app install/uninstall sessions.
Options:
Use some kind of Android's device-identifier-API each time when needed (read it every time from Android's API). According to Identififying-app-installations blog post this is not recommended and not reliable solution.
Generate UUID once (on first app start) and persist it somewhere somehow that it would be preserved across multiple app installs/uninstalls. This "somewhere somehow" part is the mystery. Solutions like storing onto the SD card or Cloud are not an option. iOS has keychain that can be used for this kind of stuff but I didn't find Android's equivalent of it.
What are my other options here? I prefer going the (2) route because of my server implementation (server is generating UUID for the first time if not present). But if it is not an option, I can fallback to (1) and modify the server.
Thanks.
To uniquely identify an application between application installs/reinstalls, you need to get it's hardware ID and use that as your credentials/key.
To fetch the hardwareID, you can use the following method:
public static String getHardwareId(Context context) {
return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
it's partially equivallent to a UUID with the following exception: The value may change if a factory reset is performed on the device.
The reason why i call it "partially equivallent" is this:
The HardwareID is a 64-bit number (as a hex string) that is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device. The value may change if a factory reset is performed on the device.
Note: When a device has multiple users (available on certain devices running Android 4.2 or higher), each user appears as a completely separate device, so the ANDROID_ID value is unique to each user.
But this hits the #2 problem: where and how to store it; storing it in SharedPreferences is useless as that is wiped if the app is uninstalled. Same for /data/data/your.package.name/my_stored_keys folder as that one gets deleted from the phone during uninstallation as well.
You will need to save it server-side if you wish to persist between uninstalling and reinstalling the app.

Samsung Chord as a Backgorund Process

I am going to enter the Samsung 2013 app contest, and one of the requirements is that you use their Chord API http://developer.samsung.com/chord.
I plan on allowing users to send messages to all phones that have my app installed. From what I gathered from the information in the previous link, this means that I will need to have a constantly running background process for users to receive the messages when they are not looking at the app at the time.
I want to know if this is true, and if so, is this viable? I am considering using the method detailed here: Android: keeping a background service alive (preventing process death) if I go ahead with this.
I'm trying to use Samsung Chord too. I thing you don't need to do this. Samsung's API Chord already provides this control.
According Chord's API:
"If a Chord node doesn’t receive a UDP signal within a specified amount of time, it considers the “missing”
node to no longer be part of the network."
And, the only thing you have to do is:
"A node cannot receive a UDP broadcast if it is in LCD-off status. Therefore, if developers want the node to discover other nodes while the application is running, the node’s status should be set to LCD-on. To do this, use Android’s PowerManager.WakeLock."
Best regards,
Adriano

Start Android application from NFC-tag with extra data

I can start my application by simply putting the phone on a NFC-tag. But I would like to take the idea one step further. Imagine a simple time-tracking application with two NFC-tags. The first will start (and download) the application and register a starttime. The other will also start (and download) the application, but register a stoptime.
My problem I'd like to solve is that I don't want my phone to know about these tags. The application should not need to have a list of tag-ids programmed and know what actions that is connected to each id. The tag should carry the information needed to start the action on the phone with the correct parameters.
Are there any information about how to accomplish this scenario? I have installed "nfc-eclipse-plugin" but doesn't understand how to use it to get my goal and even less how to get my application to read the extra data.
Thanks in advance
Roland
Your tags should be capable of storing NDEF messages. Such messages are automatically read out by Android and passed to your app in an Intent. Automatically installing and/or starting your app can be accomplished by putting an Android Application Record in your tag. Any additional information ("start" or "stop" indication) can be stored in a proprietary record.
You probably want to put the AAR as the last record of the NDEF message, as it is detected and acted upon by Android automatically, but is only supported since ICS. To make automatic installation work with Gingerbread, you can put an additional URI record or SmartPoster record with a Google Play Store link in it as the first record of the message. Your app should then filter (ACTION_NDEF_DISCOVERED) for this URI, so it will also start automatically on Gingerbread.

Intent resolution in Android

If I want to create custom address book (which overrides my phone's default address book), and if I want it to be used by all applications, what should be my intent-filter? Does Android allow me to do such a thing considering the fact that such a third-party app could potentially be malicious?!
And, if I want to have yet another address book application, I suppose the second app also has same intent-filter, isn't it? How does the framework decide which app to pick if I click on Contacts button when making a call? In other words, how does the framework resolve intents in case,there is a conflict between multiple intent-filters?
You can replace any application on Android platform, even Home. Android documentation explains everything there is to know about Intents and Intent Filters and there is a section called Intent Resolution that answers your question. Intent Resolution section for Intent class has some additional information.
As far as I can tell Android doesn't try to resolve a conflict. It ask the user which application to run and gives them the choice to mark this Activity as the default for this Intent. They give an example about mail app here.
While Mr. Smiljanić is basically correct, there is no Contacts application in Android for you to replace. There is Dialtacts, which is the application supporting the contacts, call log, and dialer. That application cannot be replaced, mostly because the dialer cannot be replaced.
So, while you may be able to override some intent filters and get control on some contacts-related requests, you will be unable to get the contacts portion of Dialtacts overridden, which will confuse users.

Categories

Resources