My play store account has over 100 apps published and all of them have this common user generation process which includes OTP verification. Interesting to note is all the apps have same user object with same properties for a particular OTP verified number, which gets stored in the respective SharedPreferences as string.
For better User Experience I would like to trim down the user generation process if there is any one app installed in the device and has done OTP verification. I want to share this user object, which is saved as string in each app's SharedPreferences.
So here's what I want when I install com.domain.app.cX app:
1) com.domain.app.cX -> (Do you have a verified user?) -> com.domain.app.cY
2.1) com.domain.app.cY -> (Yes I have, here is it "user json") -> com.domain.app.cX
or
2.2) com.domain.app.cY -> (No I don't have any user) -> com.domain.app.cX
3) Move to check if com.domain.app.cZ is installed and do over from step 1
Options I have:
1) I have read about ContentProvider and understood that you need to put in a URI of ContentProvider which is package name specific.
2) Use package name with createPackageContext and get SharedPreferences for any app.
In both the solutions I don't know which app is already installed on device and hence URIs of all ContentProvider and package name of the app.
Is there any solution in which I can leverage the signature of the app, since all the app are signed with same certificate.
Using Broadcast receivers and Custom Broadcasts.
with redundant common data across all apps with shared preferences.
All the apps contain a pair of broadcast receiver and sender.
The app which wants verification status will send a broadcast.
The other apps which listen to the broadcast will receive it and add the verification status in the intent and send again as a broadcast.
Now the 1st app which send the broadcast for verification status will receive the latest status and update the UI accordingly. If the default value is false then show the verification screen.
Related
For FirebaseCrashlytics i am setting the user id once user logged in then store its credentials in sharedpreference.
FirebaseCrashlytics.getInstance().setUserId("12345");
On next App launch User will be automatically logged in. So Should I set user id on every app launch or its the one time function call. What should I do in case on user logged out and switch to another account on same device
You will have to implement a method to associate User ID's with devices/users. You can do something like this UUID uuid = UUID.randomUUID();, to associate randomized UUID's to the setUserId method. You can read more about this here https://www.baeldung.com/java-uuid.
Depending on your method, you can log certain identifiable information based on how your user logs into your app. Such as via email or something, but that's discouraged for privacy reasons.
Let's say I have 2 apps for my school:
student.apk: Student logs in, check grades, check classes time, does a lot of stuff.
teacher.apk: Teacher logs in, lauches grades, attendence list, etc
Is it possible to create just 1 apk, with a login screen, detect whether it is a student or a teacher and than lauch the correct apk?
Basically what I'm asking is whether I can put these 2 apks (student and teacher) inside one code (login.apk).
The apps are totally different, and it would be very difficult to merge than into one, that's why I would like to launch them inside a simple "login.apk"
Not sure if that's possible. But I believe the better approach would be to use Dynamic Delivery to achieve this. Bundling the Teacher and Student as Dynamic Feature Modules and load them dynamically during runtime based on the login status.
You can find more info here :
https://developer.android.com/studio/projects/dynamic-delivery
And a tutorial here :
https://medium.com/mindorks/dynamic-feature-modules-the-future-4bee124c0f1
I would suggest playing around with intents: the concept is simple, put the login part in one of the two apps (in this example, it will be the student app).
when attempting to login, depending on the response from the server, if it is a student account, then it will simply login, otherwise, if it is a teacher account, you will verify if the teacher app is installed. if it is installed you will simply launch it and pass the needed parameters in an intent, otherwise, open the play store and install the needed app. Here is the code for that:
try {
//launch the app if it exists
Intent intent = new Intent("teacher app signature here");
intent.putExtra("some_parameter_name", "parameter value");
} catch (Exception e) {
// here is the case where the app is not installed
Uri marketUri = Uri.parse("market://details?id=teacher app signature here");
Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
startActivity(marketIntent);
}
on teacher app, you will need to intercept this intent and its parameters:
String param= (String) getIntent().getSerializableExtra("some_parameter_name");
you can then save the needed variables in the shared preferences to make sure the user stays connected.
Yes it should be possible. I haven't tested it though. Make a third app (login.apk) which contains both student.apk and teacher.apk. As soon as the user logged in within login.apk, the correct sub apk can be exported/saved
from the project to the device internal/external storage (read and write permission required for login.apk), then just launch the exported apk from login.apk by opening it -> Package installer will install it (user interaction required).
Prelude:
The client wants to install EMM for his owner devices. Sometimes the user wants to use the device as work device (only taxi and couriers apps) and sometimes the user wants to use the device as his own (install games, social apps, and his own Google accounts).
Situation:
The client wants to store his gsuite accounts in FRP storage (to have the ability to unlock a phone in case employee leave organization) but doesn't want an employee to unlock the phone after FR entering his personal account credentials.
Example:
I added two work account programmatically (like described here). But after the user gets the phone he entered his personal Gmail account to use Gmail, other apps. How can I programmatically or maybe from DPC app prevents user recover access to the phone using his personal account after Factory Reset?
I found the answer, finally. The link to the documentation.
I need just to create a bundle with google plus ids of accounts that will have the opportunity to recover device after factory reset.
And after that need to send a broadcast to notify the system that these values were changed.
val bundle = Bundle()
// list of recovery accounts
val recoveryAccounts = arrayOf(
"115273111154663031432",
"110369192556268846321",
)
bundle.putStringArray("factoryResetProtectionAdmin", recoveryAccounts)
mAdminComponentName = DeviceAdminReceiver.getComponentName(context)
// set restrictions
mDevicePolicyManager.setApplicationRestrictions(mAdminComponentName, "com.google.android.gms", bundle)
// send broadcast
val broadcastIntent = Intent("com.google.android.gms.auth.FRP_CONFIG_CHANGED")
broadcastIntent.setPackage("com.google.android.gms")
broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
applicationContext.sendBroadcast(broadcastIntent)
Off topic.
To get the id of recovery accounts try this: https://developers.google.com/people/api/rest/v1/people/get?apix=true&apix_params={"resourceName":"people/me","personFields":"metadata"}
Push "Execute" and login with needed account. It'll be shown in "id" field of response.
About ACTION_PACKAGE_NEEDS_VERIFICATION intent, the android docs says:
`Sent to the system package verifier when a package needs to be verified. The data contains the package URI.
This is a protected intent that can only be sent by the system.`
Found at https://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_NEEDS_VERIFICATION
But what kind of verification does it means? In what kinds of occasions or scenarios will android broadcast this intent?
Looking at the recent source code (around line 10669), it appears that the system will broadcast this intent during the installation of a new package if there are any package verifier installed:
/*
* Determine if we have any installed package verifiers. If we
* do, then we'll defer to them to verify the packages.
*/
As for an explanation of what package verifiers are and what they do, my understanding is that they will need to have the PACKAGE_VERIFICATION_AGENT permission (reserved for system apps) which gives them the ability to respond to the broadcast to accept or reject the installation of the new package. The Google Play Store app is a verification agent that appears to use Google's online app verification service to perform this function.
Here is a page that has a lot of interesting information on the subject (along with several other pages that comes up if you do a "android package verifier" search online).
I am trying to verify user by sending sms through twilio (Android Application).
Here is the Detailed summary-
(As in Snapchat)
During signup i want to validate user by sending dynamic run-time code to user mobile.
and after sending i have the verification field.
so what should i do ?
Twilio employee here.
This is a really common use case for Twilio and plenty of apps do the "phone number verification" thing you're looking for.
Let me boil down the steps on how to do this in human form, as this is much easier to explain than writing a bunch of code:
A user will type their phone number into a field to be verified.
When the user has typed in their number, you can compute a unique code (4 - 6 digits is all you need) however you like, and then use our REST API to send the number they entered the code.
At this point, you should save the unique code so you can reference it later.
Prompt the user to enter the code into a field within your app.
Compare the entered code to unique number you stored them and viola!
If the code is the same: you know that they own the phone number that you sent the message to. A very similar process is described in this 2-factor authentication how-to.
I hope that makes sense.
If you have any questions, please ask.
Disclaimer: I'm the maintainer of Django-phone-verify
While phait's answer is apt. People had asked in comments of the relevant apps with which they could accomplish user verification. Most of this is from my previous answer at https://stackoverflow.com/a/57461296/3535547 I'm just pasting an updated answer in this thread so that it is easier for users to find it.
What you're looking to accomplish is very easy with django-phone-verify app. It comes with Twilio and Nexmo already integrated and few endpoints which you can extend as per your use case.
This package aims at verifying if a phone number requested by a particular client belongs to them. It also takes care of ensuring that the same device provides the verification of passcode which initially requested a passcode to be sent, saving you a few hours of work.
This package also doesn't mess up with your current user model at all. You're free to use this package exactly for one thing: verifying phone numbers. Whether you do it for users, companies etc. depends on your use-case.
It follows Unix philosophy of Do one thing; do it well
Installation
pip install django-phone-verify
Configuration
Add app to INSTALLED_APPS:
# In settings.py:
INSTALLED_APPS = [
...
'phone_verify',
]
Add settings in your settings.py file:
# Settings for phone_verify
PHONE_VERIFICATION = {
'BACKEND': 'phone_verify.backends.twilio.TwilioBackend',
'TWILIO_SANDBOX_TOKEN':'123456',
'OPTIONS': {
'SID': 'fake',
'SECRET': 'fake',
'FROM': '+14755292729'
},
'TOKEN_LENGTH': 6,
'MESSAGE': 'Welcome to {app}! Please use security code {otp} to proceed.',
'APP_NAME': 'Phone Verify',
'OTP_EXPIRATION_TIME': 3600 # In seconds only
}
Migrate the database:
python manage.py migrate
You get two endpoints (Check API docs), one for registration of phone number and other to verify the passcode. You may override verify endpoint to also create a user as described in the usage docs: https://github.com/CuriousLearner/django-phone-verify/blob/master/docs/usage.rst