OK. Here is my scenario:
Somehow I open A Payment Gateway from my Android App. (So far So good!)
Payment Gateway > Android App
Then Depending on how payment interactions turns out for user (whether he pays or cancels) There must be two buttons:
ACCEPT-----------------------------CANCEL
When User Clicks on Cancel I want him to return to app with a message like (FAILED)
When User Clicks on Accept I want him to return to app with a message like (DONE)
So Based On The message I will Show him a page in my app notifying him with more info.
I Know How to Open My app using <Intent-Filter> But I want it more Specified!
I Know this That I need a referral link to put it in my <a href=''> </a> tag This Link must specify my package name and the activity I'm about to do.
Thank You in advance :)
You can use uni_links plugin to deep linking and app linking in flutter :
add this to activity tag in manifest:
<!-- Deep Links -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
<data
android:scheme="[YOUR_SCHEME]"
android:host="[YOUR_HOST]" />
</intent-filter>
then in dart side
Future<void> initUniLinks() async {
// Platform messages may fail, so we use a try/catch PlatformException.
try {
final initialLink = await getInitialLink();
// Parse the link and warn the user, if it is not correct,
// but keep in mind it could be `null`.
// navigate to every page you want
} on PlatformException {
// Handle exception by warning the user their action did not succeed
// return?
}
}
then your link can be like this
YOUR_SCHEME://YOUR_HOST/status
status can be FAILED or DONE
There are too much Deep Linking (Universal Links or App Links) tutorials. But most of them shows how to enable it in Android or IOS Apps. Also there are paid cloud solutions but they offer to much features. But there are three main problems I faced in real life:
Some browsers doesn’t allow App Links to work. For example you can configure http://example.com to be caught in app, but if this link is clicked by user through Facebook app it is not handled, and Facebook browser shows the web site.
There is no unique standard solution to handle links both for Android and IOS apps.
No practical solution if the App is not installed on mobile device and user clicks an App Link.
I wrote this Q&A which is the result of my studies (spent too many hours) to have a unique and working for all cases solution.
The codes are coming from my working solution, but I removed some parts just to show the idea. If there are some compiling problems, please follow the algorithm and write your own code
Here is the solution, go step by step even if you know some steps, because there are tricks in codes. Also some explanations are in comment lines of the code parts, please read them.
Examples are to handle deeplink http://example.com/v/ by your Android and IOS apps with an argument at the end, for example http://example.com/v/id-of-user?key=value.
1. Configuring Android
1.1 Add activity information to your AndroidManifest.xml file:
<activity
android:name=".appLinkHandlerActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="example.com"
android:pathPrefix="/v/"
android:scheme="http" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!—this intent is needed to handle links to myapp://share, I will explain later why we need it -->
<data
android:host="share"
android:scheme="myapp" />
</intent-filter>
1.2 Create an activity named appLinkHandlerActivity which will handle the links clicked
public class appLinkHandlerActivity extends AppCompatActivity {
/* assume that user is clicked http://example.com/v/my-user-id
actCode will be “v”, pCode will be “my-user-id” */
String actCode="", pCode="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ATTENTION: This was auto-generated to handle app links.
Intent appLinkIntent = getIntent();
String appLinkAction = appLinkIntent.getAction();
Uri appLinkData = appLinkIntent.getData();
String code = null;
try {
code = getIntent().getData().getLastPathSegment();
} catch (Exception e) {
}
if (code == null) {
Intent i = new Intent(this, {your main activity.class});
startActivity(i);
}
List<String> params=appLinkData.getPathSegments();
if (params.size()>0)
actCode=params.get(0);
if (params.size()>=2)
pCode=params.get(1);
/* assume that user is clicked http://example.com/v/my-user-id actCode is “v”, pCode is “my-user-id” Do now whatever you need. */
}
}
2. Configuring IOS
This is more complex than Android, I will explain the necessary points here. Please refer to documents:
https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html#//apple_ref/doc/uid/TP40016308-CH12-SW1
https://www.raywenderlich.com/128948/universal-links-make-connection
2.1 You have to enable Associated Domains while creating an App ID on Apple Developer Portal. Important issue: you need to have a purchased Apple Developer Account to enable this option, that means without purchasing a developer account, you can’t try AppLinks on your IOS project.
2.2 In XCode project, open “Capabilites” tab and switch Associated Domains to On. If you didn’t enable Associated Domains in Apple Developer Portal App ID section, this might not be selectable
Add an entitlement by clicking on + button under Associated Domains option, write “applinks:example.com”.
2.3 Create a file on your web server named “apple-app-site-association” and this file must be accessed through https://example.com/apple-app-site-association HTTPS is mandatory and if it is not a valid SSL certificate App Link might not work. Add following lines into apple-app-site-association file:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "6HY7TF56.com.example.app",
"paths": [ "/ios/*", "/v/*" ]
}
]
}
}
appID is format of {“Team ID”.”Bundle ID of your App”}. You can find your teamID under Membership Details section at Developer Portal.
We handle the link http://example.com/v/parameters, but here you see there is another path configuration for “/ios/*”. It is needed to bypass unsupported browsers, I will explain later.
2.4 In AppDelegate.m file add two methods to handle the user clicks on example.com
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
if ([userActivity.activityType isEqualToString: NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
[self parseUrl:url];
}
return YES;
}
- (void) parseUrl:(NSURL * )handledUrl {
NSString *urlStr=#"";
NSString *pCode=#"";
NSString *handledUrlStr=[handledUrl parameterString];
NSString *handledUrlQueryPart;
NSArray<NSString *> *pathsArray= [handledUrl pathComponents];
//remember that we only added paths “/v/*” and “/ios/*” to handle in apple-app-site-association file. If you want to handle more subpaths you can add them into apple-app-site-association file, then below if-else conditions. Don’t touch to config and code for “/ios/*” path, it is needed to bypass unsopported browsers.
if ([pathsArray[1] isEqual: #"v"]){
//sample url= http://example.com/v/menu?aaa=bbb
pCode = pathsArray[2];
handledUrlQueryPart=[handledUrl query];
} else if ([pathsArray[1] isEqual: #"ios"]){
//sample url= http://example.com/ios/deeplink-ios.php?/v/menu?aaa=bbb
NSArray *uriArray = [[handledUrl query] componentsSeparatedByString:#"?"];
NSArray *queryPathsArray = [uriArray[0] componentsSeparatedByString:#"/"];
if ([queryPathsArray count] > 2)
pCode = queryPathsArray[2];
if ([uriArray count] > 1 ){
handledUrlQueryPart=uriArray[1];
}
}
/* here pCode is the parameter what is passed from user. If the link clicked is http://example.com/v/menu it is “menu”. If the link clicked is http://example.com/v/menu?aaa=bbb it is “menu?aaa=bbb”. So you can do now what ever you need. */
}
3. Managing the unacught clicks.
3.1 Ok, Your android and IOS apps should handle the clicks on link http://example.com/v/blabla and pass the “blabla” parameter to pCode variable used in the methods I showed. But some browsers like Facebook app may disable App Links to work. In this case user click goes to your web server and the browser tries to show the content of http://example.com/v/blabla which is probably 404 Page Not Found. To handle these clicks we will configure Apache web server and redirect users to your App. If you use IIS or another, I don’t know how to do it, but you can take this as sample and use same algortihm to configure your web server.
3.2 Write the below lines in .htaccess file in root directory of example.com
#redirect to deeplink
<IfModule mod_rewrite.c>
#if there is a request to example.com/v/any-sub-path, redirect them to example.com/deeplink.php file. This rule is for both IOS and Android
RewriteRule ^(v)/.* /deeplink.php [L]
#if there is a request to example.com/ios/any-sub-path, redirect them to app installation page. That means your app is not installed on IOS device. This rule is for IOS devices only
RewriteRule ^(ios)/.* http://itunes.apple.com/install-of-your-app [L]
</IfModule>
4. Redirect users to Apps
4.1 The redirection rules in .htaccess file shown at step-3 redirects users to deeplink.php file. So here is the content of that file to redirect users to your App.
<?php
$request_uri=$_SERVER[REQUEST_URI];
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
if(stripos($ua,'android') == true){
//if user device is android, redirect it to intent url which is handled by Android.
$redir_tag="<meta http-equiv='refresh' content='0;url=intent://share$request_uri/#Intent;scheme=myapp;S.browser_fallback_url=http%3A%2F%2Fexample.com%2Fget-app%2F;package=com.example.app;end' />";
//scheme=myapp and host named “share” is configured in AndroidManifest.xml file to be handled by the activity.
//fallback url is the url, if your app is not installed on android device, so you can redirect them to a page to install android app. In some cases users are redirected to Play Store directly for application id of com.example.app
}
else if ( (stripos($ua,'iPhone') == true) || (stripos($ua,'iPad') == true) ) {
//if user device is IOS, redirect them to a web page to see. There will be a link here to the another handled link: http://example.com/ios/blabla.
// due to my experience there is no way to redirect IOS to app directly at this stage, user must click a link on browser and that link must be different than the link which was shown and clicked at first.
// another experience taught me ther ecan be problems if we redirect users to a web page under example.com which is configured as applink, so I redirect users to a page under deep.example.com here
$redir_tag="<meta http-equiv='refresh' content='0;url=http://deep.example.com/deeplink-ios.php?$request_uri' />";
}
else {
//If the device is neither IOS nor Android, redirect users to a web page which gives information that this link is for Android and IOS only
$redir_tag="<meta http-equiv='refresh' content='0;url=http://example.com/non-mobile' />";
}
?>
<html>
<head>
<!— add tags for no-caching, this is important, the date below is my son’s birth time and date, he is now 6, so you can use it as a date in the past -->
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="-1" />
<meta http-equiv="expires" content="Tue, 31 May 2011 10:15:00 GMT+3" />
<meta http-equiv="pragma" content="no-cache" />
<?php echo $redir_tag; ?>
</head>
</html>
5. Show IOS users a link to click
5.1 Here is the content of http://deep.example.com/deeplink-ios.php file. Users will see a page like below, when they clicked on the link, that request should be handled by your IOS app.
<?php
//we create a link to http://example.com/ios/… which is configure to be handled by IOS app. IOS needs to be a user click in some cases to handle the request, that is why this page is shown to the user
$request_uri=$_SERVER[REQUEST_URI];
$link="<div class='w3-container w3-card'><h1><a href='http://example.com/ios$request_uri'>Click here to open MyApp</a></h1></div>";
?>
<html>
<head>
<!—adding no-cache tags is also important here-->
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="-1" />
<meta http-equiv="expires" content="Tue, 31 May 2011 10:15:00 GMT+3" />
<meta http-equiv="pragma" content="no-cache" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3mobile.css">
</head>
<body>
<?php echo $link ?>
</body>
</html>
6. Case Analysis:
6.1 Android
6.1.1 Case-1 – app is installed on device
• Browser requests for http://example.com/v/blabla
• Android catches the link and create the activity configured in your manifest file
6.1.2 Case-2 - app is installed on device
• Browser requests for http://example.com/v/blabla
• Android can’t catch the link.
• Browser connects to web server, request for /v/blabla
• It is redirected to deeplink.php?/v/blabla due to configuration in .htaccess file
• deeplink.php learns it is android, and redirect to: intent://share/v/blabla/#Intent;scheme=myapp;S.browser_fallback_url=http%3A%2F%2Fexample.com%2Fget-app%2F;package=com.example.app
• Android catches the request which is for intent://, so due to configuration in manifest file myapp://share/v/blabla is handled by the activity
6.1.3 Case-3 - app is not installed
• Browser requests for http://example.com/v/blabla
• Android can’t catch the link.
• Browser connects to web server, request for /v/blabla
• It is redirected to deeplink.php?/v/blabla due to configuration in .htaccess file
• deeplink.php learns it is android, and redirect to: intent://share/v/blabla/#Intent;scheme=myapp;S.browser_fallback_url=http%3A%2F%2Fexample.com%2Fget-app%2F;package=com.example.app
• Android catches the request which is for intent://, but there is no app installed for id: com.example.app. It falbacks and redirect browser to http://example.com/get-app or Play Store installation page of your app in some cases
6.2 IOS
6.2.1 Case-1 – app is installed on device
• Browser requests for http://example.com/v/blabla
• IOS catches the link and call the continueUserActivity method in AppDelegate.m
6.2.2 Case-2 – app is installed on device
• Browser requests for http://example.com/v/blabla
• IOS can’t catch the link.
• Browser connects to web server, request for /v/blabla
• It is redirected to deeplink.php?/v/blabla due to configuration in .htaccess file
• deeplink.php learns it is IOS, and redirects to: http://deep.example.com/deeplink-ios.php?/v/blabla
• deeplink-ios.php file shows a URL to user. URL is: http://lify.me/ios/v/blabla
• User clicks the URL, and browser requests for http://lify.me/ios/v/blabla
• IOS catches the request due to configuration for path “/ios/*” in apple-app-site-association file and call the continueUserActivity method in AppDelegate.m
• If IOS can’t catch the request for http://lify.me/ios/v/blabla with any reason, it will behave as app is not installed on device. See that case.
6.2.3 Case-2 – app is not installed on device
• Browser requests for http://example.com/v/blabla
• IOS can’t catch the link.
• Browser connects to web server, request for /v/blabla
• It is redirected to deeplink.php?/v/blabla due to configuration in .htaccess file
• deeplink.php learns it is IOS, and redirects to: http://deep.example.com/deeplink-ios.php?/v/blabla
• deeplink-ios.php file shows a URL to user. URL is: http://lify.me/ios/v/blabla
• User clicks the URL, and browser requests for http://lify.me/ios/v/blabla
• If IOS can’t catch the request for http://lify.me/ios/v/blabla
• Browser connects to web server, request for /ios/v/blabla
• It is redirected to http://itunes.apple.com/install-of-your-app due to configuration in .htaccess file on web server
6.3 App Link is clicked on non Android or IOS device
• Browser requests for http://example.com/v/blabla
• Device OS can’t catch the link.
• Browser connects to web server, request for /v/blabla
• It is redirected to deeplink.php?/v/blabla due to configuration in .htaccess file
• deeplink.php learns it is nor IOS neither Android, and redirects to: http://example.com/non-mobile
Appcelerator 5.2.0 Facebook Module (Android) doesn't fire 'login' event after successful logged in.
What could it be?
var FB = require('facebook');
FB.initialize();
FB.permissions = ['public_profile', 'email', 'user_events'];
FB.forceDialogAuth = false;
FB.addEventListener('login', function() {
alert('login');
});
FB.authorize();
Thanks!
Hello Oxana,
Additional Android Setup Steps
Since Facebook module v4.0.0, for the Android platform, you need to:
Add the Facebook Login activity to the Android manifest
Add the Facebook App ID to the Android resources string.xml file
Create a Facebook proxy and associate it with the current active activity (you need)
Manifest:
<ti:app>
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<application>
<activity android:label="#string/app_name"
android:name="com.facebook.LoginActivity" android:theme="#android:style/Theme.Translucent.NoTitleBar"/>
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/>
</application>
</manifest>
</android>
<ti:app>
Add the Facebook App ID to Android Resources
Add a string element to the /platform/android/res/values/strings.xml file with the name attribute set to facebook_app_id and the node text set to your Facebook App ID. Create the file if it does not exist.
<resources>
<string name="facebook_app_id">FACEBOOK_APP_ID</string>
</resources>
**I think this step is that you need =D **
Create a Facebook Proxy
Use the createActivityWorker() method to create a Facebook proxy. Pass the method a dictionary with the lifecycleContainer property set to the current active instance of a standalone Window (window not contained in a tab group) or TabGroup. Create the proxy before calling the open() method on either the window or tab group.
The Facebook module needs to hook into the lifecycle events of the current active activity in order to synchronize its state between various activities in the application, for example, to update the label of the Login button when the user logs in or out of Facebook.
Attach the proxy to the Window or TabGroup object, so it does not get garbage collected.
win.fbProxy = fb.createActivityWorker({lifecycleContainer: win});
Documentation: Facebook module
i m getting error during shareing text and Image on Facebook. i used Facebook SDK 4.0 version to integrate into my app
Facebook Analytic showing no error. App opens : 58
when i click on image, Facbook opens and instantly closed, there is no post on my facebook wall. And error shwoing
BlueServiceQueue: Exception during service
java.lang.Exception: Invalid JSON result
at com.facebook.appcenter.protocol.FetchAppDetailMethod.a(FetchAppDetailMethod.java:59)
at com.facebook.appcenter.protocol.FetchAppDetailMethod.a(FetchAppDetailMethod.java:25)
at com.facebook.graphql.protocol.AbstractPersistedGraphQlApiMethod.a(AbstractPersistedGraphQlApiMethod.java:160)
at com.facebook.http.protocol.SingleMethodRunnerImpl.a(SingleMethodRunnerImpl.java:186)
at com.facebook.http.protocol.SingleMethodRunnerImpl.a(SingleMethodRunnerImpl.java:150)
at com.facebook.http.protocol.AbstractSingleMethodRunner.a(AbstractSingleMethodRunner.java:16)
at com.facebook.appcenter.service.AppDataServiceHandler.d(AppDataServiceHandler.java:223)
at com.facebook.appcenter.service.AppDataServiceHandler.a(AppDataServiceHandler.java:103)
at com.facebook.fbservice.service.BlueServiceQueue.e(BlueServiceQueue.java:296)
at com.facebook.fbservice.service.BlueServiceQueue.d(BlueServiceQueue.java:53)
at com.facebook.fbservice.service.BlueServiceQueue$3.run(BlueServiceQueue.java:230)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at com.facebook.common.executors.ListenableScheduledFutureImpl.run(ListenableScheduledFutureImpl.java:59)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
this is the code im using yo share text and Image
if (ShareDialog.canShow(ShareLinkContent.class)) {
ShareLinkContent content = new ShareLinkContent.Builder()
.setContentUrl(Uri.parse("https://developers.facebook.com")).build();
shareDialog.show(getActivity(), content);
}
here is minifest file code
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider#string/facebook_app_id"
android:exported="true" />
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:label="#string/app_name" />
i declared String facebook_app_id into string.xml file
i do not know why error is showing. i m doing nothing special.
Any suggestion will highly appreciated. thanks in Advance
The reason for opening and closing the Facebook Screen instantly is due to Sandbox settings.
You need to enable the SandBox mode in the Facebook Developer
Page.
Follow the steps here.
Open https://developers.facebook.com/ . Select your app from top navigation bar ( Apps ). Click on Status & Review (Left Sidebar). You will find a toggle button to do on/off your app from sandbox mode. [ From Google - This may help some beginners in future ].
#Ashu Kumar, Thanks for mentioning me to post an answer regarding this.
Best Wishes.
I guess the problem is, I'm not sure what I should be putting in the settings, so any help would be greatly appreciated, as when I run the app with all the setting below I get the Facebook screen opening with an error saying :
"Invalid Scope: public_info"
Here's my app code:
Config.xml:
<gap:plugin name="com.phonegap.plugins.facebookconnect" version="0.8.0">
<param name="APP_ID" value="**IS THIS MY FACEBOOK APP ID?**" />
<param name="APP_NAME" value="**HAVE NO IDEA WHAT I PUT HERE?**" />
</gap:plugin>
index.html
I read somewhere that I need these includes, but I have no idea if this is the case in PhoneGap Build?
<script src="cdv-plugin-fb-connect.js"></script>
<script src="facebook-js-sdk.js"></script>
index.js
I'm simply trying to log the user in, nothing more:
onDeviceReady: function()
{
var fbLoginSuccess = function (userData)
{
alert("UserInfo: ");// + JSON.stringify(userData));
}
facebookConnectPlugin.login(["public_info"], fbLoginSuccess, function (error) { alert("" + error) });
}
Facebook Developer
This is where I get even more confused, so any help, as I have no idea if these are correct?
Package Name : ped-test-app-1
Default Activity Class Name : ped-test-app-1.MainActivity
Key Hashes : I created this using the keytool and openSSL, and it looks to be in the same format, but do I need to compile my app with the signing key each time?
Sorry there's so much, but like I said, any help would be really appreciated.
Thanks
After all that; it's a simple documentation error:
facebookConnectPlugin.login(["public_info"] has been superseded with:
facebookConnectPlugin.login(["public_profile"],