Suppose an user wants to download a music from example.com. User goes to example.com from browser and clicks "download sample.mp3".Now instead of downloading the sample.mp3,the browser downloads an android app. When the user installs the app, the app downloads exactly the same 'sample.mp3' that the user clicked from the browser.
So, how do i make an app like this? Note: i can use download Api to download a music inside onCreate of the app without any views or anything.
But the key challenge here is to get the data that the user clicked in the browser (when my app was not even installed). Is it do-able somehow?
You can use firebase dynamic links for that.
You can pass the songId with the link and google play will pass that link into the app after installation. There you can extract the songId and start downloading the song.
One more advantage of the dynamic link is that google play will check if your app is already installed or not. If it is already installed then it will open the app directly else it will redirect to playstore page of the app.
To extract the songId in the app you can use below code:
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
}
// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "getDynamicLink:onFailure", e);
}
});
Related
I have an Android mobile application that works with the membership system.
There are links to other mobile applications and games in my application.
With Packet Manager, I can check whether the application in the link is installed on the phone. My goal is to check whether users have downloaded the game and mobile applications on the device by clicking the links in my application.
If they downloaded the application in the given link once (first time), they will earn 10 points. If they download the same application many times, they will be considered as one time.
I wanted to ask you that If users download an app more than once, how do I count it just one time?
private boolean appInstalledOrNot(String uri) {
PackageManager pm = getPackageManager();
boolean app_installed = false;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
} catch (PackageManager.NameNotFoundException e) {
app_installed = false;
}
return app_installed;
}
public void go(View view) {
boolean installed = appInstalledOrNot("com.dousoftware.pubgtyolar");
//loaded
if (installed) {
Toast.makeText(this, "Loaded", Toast.LENGTH_SHORT).show();
} else {
Intent viewIntent = new Intent("android.intent.action.VIEW",
Uri.parse("https://play.google.com/store/apps/details?
id = com.dousoftware.pubgtyolar "));
startActivity(viewIntent); Toast.makeText(this, "Not Loaded", Toast.LENGTH_SHORT).show();
}
}
The short answer is: you can't.
There is no way to know, locally, on an Android device, how many times the user installed or uninstalled an app.
The long answer is that there may be some workarounds, each with its own advantages and disadvantages.
While your app is installed, you could register to ACTION_PACKAGE_ADDED and ACTION_PACKAGE_REMOVED broadcasts.
These will be called every time the user installs or removes any app.
They have EXTRA_PACKAGE_NAME that contains the app package name.
This however, presents some problems:
This will only work while your app is installed and the user has opened your app at least once.
You will receive this broadcast for any app, and will have to filter the results yourself.
If the user clears data or uninstalls and reinstalls your app, you will lose count.
Another way, and how most apps do it, is by using a referral framework.
One example is Iron Source which will let you set up rewards for installing and using different apps.
If the other app is also yours, you can simply use Firebase.
Note however, that referral tracking compromises user privacy, so you have to be careful to comply with any local laws such as GDPR.
Also, using these frameworks may cost money.
If user click link
Check that user don't have this application
Redirect to store page.
Set in the config file that this link has been clicked
If user install application and Script triggers (eg on app opening) add points. Add points only if Link has been marked as clicked.
Mark the link in config file as used to not give more points from the same app.
You can store this data on your server to avoid eg uninstalling abuse
Simply save somewhere information that link has been used
got some copy-paste code from firebaseauth tutorial to connect a client on my app with Microsoft authentication. problem is, login screen not showing
you can find the full tutorial here.
note, I did copy everything just to test connection (not including optional code, to simplify things)
the problem stats at firebaseAuth.startActivityForSignInWithProvider method. it always ends up with failure. trace show this message:
"FirebaseAuthException... There was an error while trying to get your package certificate hash."
I did everything in the tutorial including registration of my app at Microsoft and Firebase Authentication screen. I ran this code at android studio emulator and an actual device, same result
my sign in function:
public void signinToMicrosoft(Activity activity) {
OAuthProvider.Builder provider = OAuthProvider.newBuilder("microsoft.com");
Log.e(TAG,"Signing with microsoft");
Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
if (pendingResultTask != null) {
// There's something already here! Finish the sign-in for your user.
pendingResultTask
.addOnSuccessListener(
new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Log.e(TAG,"Pending Success");
// User is signed in.
// IdP data available in
// authResult.getAdditionalUserInfo().getProfile().
// The OAuth access token can also be retrieved:
// authResult.getCredential().getAccessToken().
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG,"Pending Failed: "+e.getMessage());
// Handle failure.
}
});
} else {
Log.e(TAG,"No Pending");
// There's no pending result so you need to start the sign-in flow.
// See below.
}
firebaseAuth
.startActivityForSignInWithProvider(activity, provider.build())
.addOnSuccessListener(
new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Log.e(TAG,"Auth Success");
// User is signed in.
// IdP data available in
// authResult.getAdditionalUserInfo().getProfile().
// The OAuth access token can also be retrieved:
// authResult.getCredential().getAccessToken().
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG,"Auth Failed: "+e.getMessage() + "\nTrace: "+ e.getClass().getCanonicalName());
// Handle failure.
}
});
}
a custom chrome tab was supposed to open and allow signing to Microsoft but it pops up for a split second and closes. if anyone had that problem or got a fix for me it would be much appreciated. thanks!
If anyone still has this problem, I just want to share my solution and my problem which is similar to this.
TL;DR
Your SHA-1 Fingerprint may be used by another Firebase project so either delete that fingerprint or sign with a different keystore
Long Version
I worked on a project that has a development and production environment using different Firebase projects. We use Firebase Auth to link Microsoft login for our Android app. I got the same error as above while trying to set up the development environment of the project. We used to only have one environment for Firebase so this was never a problem.
It turns out that when you don't provide an SHA-1 fingerprint when you create the project, Firebase automatically adds them when you run an authentication call. This meant that when we created debug APKs for testing, the SHA-1 fingerprint was recorded to the Firebase project that was intended for the live environment so when you try to add the same fingerprint in another project it won't let you. The solution would be to include the SHA-1 fingerprint in the development environment but to do so you would need to delete it the fingerprint from the live environment (in my case) and wait for that change to reflect. Or you could sign with a different, unused keystore.
You need to have microsoft (hotmail, outlook ...) account on your android, to solve this problem.
I am currently working on an Android app in which I want to use Google Play Games services (Achievements, Leaderboards, ...). After many iterations I finally got the code working to show the Google Play Games Login promt. The problem is now that after the user signs in it takes a while and then throws error code 4 with error message being empty. After doing a lot of research nothing really helped me solving this problem.
I have tried starting it directly out of Android Studio, installing the app manually or over Google Play, all on multiple devices, nothing worked.
Here's some code if required:
private static GoogleSignInClient mGoogleSignInClient;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mGoogleSignInClient = GoogleSignIn.getClient(this, new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).requestIdToken(getResources().getString(R.string.app_id)).build());
signInSilently(); // Can't be tested yet.
// isSignedIn() and loginDeclined are both false
if(!isSignedIn() && !loginDeclined) startSignInIntent();
}
...
private void startSignInIntent() {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
loginDeclined = true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
// resultCode = 0
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task =
GoogleSignIn.getSignedInAccountFromIntent(intent);
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
// Now this never happens :(
System.out.println("SUCCESS!");
} catch (ApiException apiException) {
System.out.println(apiException.getStatusCode() + " + " + apiException.getMessage());
// statusCode is 4, message is "4: "
String message = apiException.getMessage();
if (message == null || message.isEmpty()) {
message = "Error signing in to Google Play Games";
}
new android.app.AlertDialog.Builder(this)
.setMessage(message)
.setNeutralButton(android.R.string.ok, null)
.show();
}
}
}
Make sure that you use the SHA1 key.
The command "keytool -list -keystore [path to debug keystore]" may display a SHA-256 key.
To get your SHA1 key you can follow these steps:
Open your project
Click on "Gradle" (on the right side)
Choose your module
Tasks -> android -> (double click) signingReport
image: get your SHA1 key
After searching on the internet for hours and checking every step from the troubleshooting section in the google play game services documentation (https://developers.google.com/games/services/android/troubleshooting), I filled out the "OAuth Consent Screen" form and it finally worked.
Log in to the Google Play Console
Go to Game Services
Go to your game
On the Game Details page scroll all the way down to the linked API console project
Click the link to the linked API console project
Click "OAuth Conset Screen" in the left side bar
Choose external
Fill out the form and upload an icon
Send for verification
After that my Google Play Game Services Sign In worked instantly.
Please check the following details for GPG Sign in issues:
Make sure that you have followed the instructions to create your client IDs and configure the games services.
Your meta data Tag in manifest should match with your application's numeric ID, and it should only contain the numbers. Also double check your package name. Do not use the sample app package name. Use your own.
The certificate with which you are signing your game should match the certificate fingerprint associated to your client ID.
The last important thing, Check that test accounts are enabled. I keep forgetting this step.
Make sure that the fingerprint from App signing certificate matches with the linked apps from Game services. You can also verify these details by navigating to your Google API console -> Select your app -> Credentials -> OAuth 2.0 client IDs.
The other thing I noticed that, if the app is released, then you need to install the app from the Play Store for these credentials to work. If the app is not yet released, then make sure you are using the debug fingerprint and that matches in your Games services (Debug fingerprint).
As far as you have these fingerprints in place, you should be fine. If you are still having issues, I would recommend to go through the code lab to get step by step help on how to to extend an existing Unity game to run on an Android device and integrate Play Game Services.
https://codelabs.developers.google.com/codelabs/playservices_unity/index.html?index=..%2F..%2Findex#0
Or here are the sample apps to help with quick test -
https://github.com/playgameservices/android-basic-samples.
You can also help us with the logcat to better understand the issue.
Recently, I faced the problem when i was trying to write the user data on his drive using the saved game api. And i figured out the problem. Below are my observation hope it will help in general scenario:
You can test the play games api in debug build by adding testers in your play console.
If you want to test on signed apk, then you need to generate the SHA1 key by using your "app.keystore" keystore file and add the android app with this SHA1 key in play game services particular for that app. Now you would be able to get the expected result.(It was the problem in my case)
If you want to store the data on user drive, then you need to enable "saved games" api in play game services.
In my case everything looked fine but get error code, then i check Google Play Console> Play Game Service and publish the changes. The key is publishing things that i made.
Approaching to the final stage of the authentification, but something is going wrong in handleSignInResult method. It returns Exception code 10 (Developer error) in logs. Google provides comprehensive description:
The application is misconfigured. This error is not recoverable and will be treated as fatal. The developer is an idiot...
What should I do to handle this (get an account) and finally retrive values from account?
Thank you in advance for your help!!!
MainActivity:
package ru.podgorny.carcall;
import ...
public class MainActivity extends AppCompatActivity {
SignInButton signInButton;
public static final int RC_SIGN_IN = 07;
public static final String TAG = "MainActivity";
TextView tw1;
TextView tw2;
GoogleSignInOptions gso;
GoogleSignInClient mGSC;
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Activity Works");
findViews();
gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
//.requestProfile()
.build();
mGSC = GoogleSignIn.getClient(this, gso); //smth with mGSC variable....
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
onClick2(v);
}
};
signInButton.setOnClickListener(onClickListener);
}
private void findViews() {
Log.d (TAG, "findViews started");
signInButton = findViewById(R.id.idButtonGoogle);
tw1 = findViewById(R.id.textView1);
tw1 = findViewById(R.id.textView2);
Log.d(TAG, "Views finded");
}
public void onClick2(View view) {
Log.d(TAG, "onClick started");
switch (view.getId()) {
case R.id.idButtonGoogle:
signIn();
break;
}
Log.d(TAG, "OnClick Started");
}
public void signIn() {
Intent signInIntent = mGSC.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
Log.d(TAG, "startActivityForResult works");
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "OnActivityResult started");
// Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
// The Task returned from this call is always completed, no need to attach
// a listener.
Log.d(TAG, "TASK started");
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
Log.d(TAG, "OnActivityResult returned");
}
}
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);//ERROR -- Code 10
Log.d(TAG, "Account received");
updateUI(account);
Log.d(TAG, "updateUI Launched");
} catch (ApiException e) {
Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
updateUI(null);
}
}
private void updateUI(GoogleSignInAccount account) {
if (account!=null) {
tw1.setText("OK");
tw2.setText("Name: " + account.getGivenName() + ", Family name: " + account.getFamilyName() + ", Email: " + account.getEmail() /*+ " image: " +
account.getPhotoUrl()*/);
}else {
tw1.setText("SMTH wrong");
}
}
}
This error might happen if you are not using same project at console.developers.google and console.firebase.google.com. If project is same at both console make sure you have add your SHA1 Key properly. Get SHA1 from Android studio.
Open Android Studio
Open your Project
Click on Gradle (From Right Side Panel, you will see Gradle Bar)
Click on Refresh (Click on Refresh from Gradle Bar, you will see List Gradle scripts of your Project)
Click on Your Project (Your Project Name form List (root))
Click on Tasks
Click on Android
Double Click on signingReport (You will get SHA1 and MD5 in Run Bar(Sometimes it will be in Gradle Console))
Select app module from module selection dropdown to run or debug your application
You also need to get google-services.json from firebase console and put into your project.
I landed into the same problem and wasted hours. On digging deeper into OAuth and OpenId, I figured out the reason. We are doing a conceptual error here.
For android or any other platform (except web), you need to create at least two types of client id in the same project of google API console. These Client ID types are:
Web Application
Android
You can create them in any order. While creating Android type Client Id, you need to give package name and SHA1. While creating Web Application Id, you just need to give a name.
You don't need to do anything with any of these id's further until you want to verify the user at your backend. In other words, if you want your backend server to ask google server about this user's information, then only you would need Web Application Id. The conceptual flow is as follows:
First send Web Application Client Id from Android App to Google Sign-in Server as an additional option using requestIdToken(your_web_app_client_id).
You will get back a token in Android app upon user's sign in.
Send this token to your backend.
Now your backend can exchange this token with Google Servers to get user's information
Send this Web Appplication Client Id from Android App to backend server.
Use this Web Application Id if you want to verify user at your backend.
The answer for me was that you actually need to combine the two main answers given here:
Make sure that you created Google OAuth client ids for Android (one for Debug and one for release) and then assure that they have assigned the right SHA1 as described in the accepted answer.
Then you also need to create an OAuth client ID for Web and use that one for the actual SignIn:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(WEB_CLIENT_ID)
.requestEmail()
.build();
I fixed this problem by this way
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.AUTH_ID))
.requestEmail()
.build();
where my AUTH_ID is
I've found another source of the problem.
In my case the keys were alright, but applicationId field in build.gradle script differed from app's package name.
Small research showed that applicationId field value takes some kind of "precedence" before app's package name conserning Google autentication.
After commenting applicationId line in build.gradle, app autenticates itself in Google by package name.
Another source of this error is adding applicationIdSuffix to your Build Variants (Flavors) in the gradle file. If you had everything working and suddenly when adding flavors the Google Sign In broke, check this configuration variable.
The applicationIdSuffix parameter might require a unique certificate for each suffix. I simply removed it because I didn't need to deploy different products or releases yet. Also, you can set the same configuration for each flavor programmatically.
Configure certificates build types: Force to use same certificate to sign different "buildTypes" that are configured for a particular "productFlavor"?
Option: then keep in mind that google also signs the app with the another certificate. So, you need to add the 2nd fingerprints as well.
Otherwise, you will receive this error.
I paste the release keystore sha1 to google console, but forget add debug config !!
This solution assumes that the root cause of your problem is that you are debugging and in that case the fingerprints of the app are different than the final production builds. To over come that:
Add your debug.keystore's SHA1 and SHA256 fingerprint to your Firebase project with these steps:
Obtain the debug.keystore's fingerprints: Linux/Mac - keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore, Windows - keytool -list -v -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore
Add these fingerprint's to your Firebases project's Android app section: https://support.google.com/firebase/answer/9137403?hl=en
This Problem can be solved by using WebApplication ID and android Client ID
When ever you configure the project to generate id for android app , it generates 2 types of ids 1 Android 2 WebApplication ,
We need to use 2nd one (web oAuth id) and not the 1st one , it will be resolving your issue
I would like to add Supplemental Information as to Why #Patrick R answer (above works/marked as correct). To execute your project/practice, Google Console needs to ID your app via SHA-1 key when its distributed on Google Play Market, However, when your are simply experimenting with Login confirmation and Proof Of Concept, then it associates the debug SHA-1 key (your app automatically generates this) for this exact purpose, keeping your testing and production changes modular.
Had same issue. Code 10 in signed apk. I put all the four keys from Google Play Console (Setup -> App integrity -> Play App Signing) to Firebase project and pasted new Google-services.json in app folder in Android Studio and then after generating Signed Apk, Google sign in worked.
Make sure you use Web Client ID from https://console.cloud.google.com and not Android client.
Even if it is mentioned Web application in Type column:
enter image description here
Try adding .requestIdToken(getString(R.string.default_web_client_id)).
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id)) //add this line
.requestEmail()
.build();
atleast on the debug version, i didnt send any token and it worked...
ie,no 'requestIdToken' in GoogleSigninOptions.build()
It may not work in Release...will try ..
I had the same issue and non of the answers above worked for me:
If you get error code 10 that means for sure that you have a SHA problem. My solution was to go to the Firebase project, Settings Overview (top left cornet) -> Click on the Settings icon -> Project Settings. There, General tab will be first selected and you have to scroll down to SDK setup and configuration, select the Android app and make sure you enter the same SHA1/256 key that you've entered on the Google Cloud Platform when you've configured your OAuth consent screen and the credentials.
Hope this helps you too. Cheers!
Press "Sync Project with Gradle files."
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Open Facebook page from Android app?
Does the Android Facebook app have Intents that other apps can use to start the Facebook app and goto a specific page?
For example, when someone clicks a certain button in my app, I want them to be taken to Facebook to a specific company's public Facebook page. Starting a web browser activity for this is easy, but more than likely the user is not logged in the browser etc...
I was thinking it would be nice if I could instead use an Intent (if one exists...) to start up the Facebook app and take the user to the specific page in the app. That way the user is already logged in and can interact with the page, Like it, etc...
Does an Intent like this exist? If so, where would I find more information on it? I've been looking through Facebook's developer documentation but I'm not seeing anything about this.
Go to https://graph.facebook.com/<user_name_here> (https://graph.facebook.com/fsintents for instance)
Copy your id
Use this method:
public static Intent getOpenFacebookIntent(Context context) {
try {
context.getPackageManager().getPackageInfo("com.facebook.katana", 0);
return new Intent(Intent.ACTION_VIEW, Uri.parse("fb://profile/<id_here>"));
} catch (Exception e) {
return new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/<user_name_here>"));
}
}
This will open the Facebook app if the user has it installed. Otherwise, it will open Facebook in the browser.