After open webpage in app browser where phone number is set I need get phone number in popup for call.
Any plugin for phonegap?
GL
Not sure what your question means, but as far as I understand you need to make a call to the number on button click. Try the following in your HTML file:
<a class="button" href="tel://123456">1234563</a>
If you are getting the number from controller, use:
<a class="button" href="tel://{{number}}">123456</a>
Today I came across a feature request that I had not done before – dialing a number from within an app. Some quick research shows that its possible using a specific URI scheme.
What are URI schemes? Honestly Wikipedia does a better job than I ever could in describing them but I think of them as something that allows a specific piece of functionality to happen over the internet, and thus they are usually referred to as protocols. You probably have already seen them – the most common ones are http: and https: (for web browsing), and ftp:, among others. Some are unique to an application and really don’t qualify as schemes and are definitely not a “protocol”, such as mailto: (to open up the mail client on a person’s computer), javascript: or about: – in fact, try typing about: in the address bar of your browser and hit “enter” on your keyboard, notice what happens…
In our case where we want to dial a number from within our app we need a way of telling the mobile phone that we want to make a call. There is a scheme for this purpose called tel:. A sample number using this scheme would look like this: “tel:+1-800-555-1234”. If you wanted a number to work around the world you would use an international number which includes the country code.
Implementing this is simple, we could do this within our mobile html5 app like so:
...
call this number
...
Ideally though we would delegate the event and fire a function to call our mythical phone number. To send the url (the “tel” url) to the browser we would write the following:
...
document.location.href = 'tel:+1-800-555-1234';
...
As of PhoneGap 3.6 all schemes are subject to whitelists. This means you have to add the tel scheme to a second whitelist that will allow your app to launch external applications. To do this you need to edit your config.XML to include the following (a mailto example is included):
Go here for more information: Cordova 3.6.0 Whitelist Guide.
Of interest to this topic is getting Android to treat phone numbers (as well as URLs and mailto schemes) as clickable links in text fields. I’ve not tested it but try adding the following to your config.xml.
Additional information on this can be found here: http://developer.android.com/reference/android/widget/TextView.html#attr_android:autoLink.
[EDIT: Note that what follows no longer applies but remains here for historical purposes.]
When we run the above code in Android 2.3.6 the phone dialer appears and does so with our number pre-populated ready to be dialed. Unfortunately on iOS 5 this doesn’t happen. A quick review of iOS documentation implies that it should work – so I suppose its just broken.
No need to panic, there is a PhoneGap plugin available which will take care of things. The plugin can be downloaded from here:
Click here to download the iOS Phone Dialer PhoneGap plugin
Its simple to install – just drag and drop the “m” and “h” files on to the classes folder of your xcode project. When you do this a dialog will appear with some options – be sure to click the radio button for copying “…files if needed..”.
Next, update the PhoneGap.plist file to reflect that you are adding a new plugin. The link for downloading the plugin explains the plist values as being “phonedialer > PhoneDialer”… but I think its easier to explain with an image:
The final step is to place the “PhoneDialer.js” javascript file somewhere within the root of your project and then to add it to your index.html file via a script tag.
Now that the Phone Dialer plugin is installed you’ll naturally want to know how to use it:
...
window.plugins.phoneDialer.dial('1-800-555-1234');
...
All in all pretty easy and straight forward, however now you have two methods of dialing a number within a single project. What you want is to use the tel: url scheme in Android and the Phone Dialer plugin in iOS.
Within Sencha Touch we have something called the Ext.is object whose attributes reflect everything that you could possibly want to know about the environment that your mobile app is living within.
For our purposes all we want to know is if we are in iOS or if we are in Android. These two lines provide us the answer:
...
Ext.is.Android // boolean, "true" for android, false otherwise
Ext.is.iOS // boolean, "true" for iOS, false otherwise
...
Thats all we need to impliment phone dialing across the two platforms within our mobile app. Lets build a function that makes use of one of the above (we don’t need both) and we should also give the user a choice in the matter, so the code below includes a message to the user to see if they really do want to suspend the app in favor of the device’s phone dialer:
...
function callSomeone(){
var msg = Ext.Msg.confirm('Please Confirm','Are you sure you want to make a phone call?',
function(r){
if (r == 'yes'){
if (Ext.is.Android){
document.location.href = 'tel:+1-800-555-1234';
} else { // we assume the device is running iOS
window.plugins.phoneDialer.dial('1-800-555-1234');
}
}
});
msg.doComponentLayout();
}
...
All done… I suppose the very last thing to do here is to provide a complete working Sencha Touch example, and some screen captures…
...
Ext.setup({
onReady: function(){
var rootPanel = new Ext.form.FormPanel({
fullscreen: true,
items: [
{
xtype:'button',
text:'Call 1-800-555-1234',
scope:this,
handler: callSomeone
}
],
dockedItems:[
{
xtype:'toolbar',
dock:'top',
title:'Phone Dialer Example'
}
]
}
);
function callSomeone(){
var msg = Ext.Msg.confirm('Please Confirm','Are you sure you want to make a phone call?',
function(r){
if (r == 'yes'){
if (Ext.is.Android){
document.location.href = 'tel:+1-800-555-1234';
} else { // we assume the device is running iOS
window.plugins.phoneDialer.dial('1-800-555-1234');
}
}
}
);
msg.doComponentLayout();
}
}
});
...
From http://rickluna.com/wp/2012/02/making-a-phone-call-from-within-phonegap-in-android-and-ios/
Related
Good afternoon,
I am trying to automate the following scenario on Android using Kotlin:
Start Appium driver and open React native app (driver1)
Perform some actions on React native app
Create driver2 with chrome options to open chrome and paste deep link there
Deeplink leads to the app automatically (but I suppose the current session uses driver2, not driver1 here)
I need to continue using the app further with driver1 however it is not working and not finding the element which is on the next screen where my deep link leaded me
I am using Appium v1,21,0
Language - Kotlin
App - React-native
I tried the following solutions:
getContext - does not work as this is not a hybrid app but two different mobile apps
startActivity - it actually launching the app from scratch, not continuing (i need to be on a particular screen after deep-link navigation, can't navigate anywhere else flow won't work)
startActivityCommand - this one did not work for me at all (it ignores the command but maybe anyone can give an example of its usage as I might use it wrong)
driver.switchTo().window("0") - did not work
assign to driver2(web) new capabilities - does not work as it is already defined so we cant change it
sessionId - I am not sure how it works exactly yet, but I tried to find a way to assign a driver to the particular session-id and was not successful (looks like AppiumDriver methods do not support it)
Would appreciate any ideas, links, or sources that can help archive the above
Good Day!
Solution that helped:
#AndroidFindBy(xpath = "//android.widget.EditText[#resource-id=\"com.android.chrome:id/search_box_text\"]")
#iOSXCUITFindBy(id = "")
lateinit var chromeURL: MobileElement
var deeplink = <your deeplink>
driver.activateApp("com.android.chrome")
chromeURL.sendKeys(deepLink)
var clickOnDeepLink = driver.findElements(MobileBy.AndroidUIAutomator("new UiSelector().text(\"$deepLink\")"))
clickOnDeepLink[0].click() //here we could not use Keys.ENTER so we just click on the element first in the list - default android google chrome behaviour
So there is no need for several drivers - same driver instance is fine
I'm integrating AppsFlyer with Android Native Application. And I want to use Deferred Deep Linking, when user click landing page ads and download the app and upon first app open the user lands directly on the activity I want.
Link docs: https://support.appsflyer.com/hc/en-us/articles/207032096-Deferred-Deep-Linking-Getting-the-Conversion-Data
But I have not found a way to check that my code is running correctly.
Please help me with this problem
What was working for me is:
Add physical device as a test device in AppsFlyer (here's how to do it)
Enable Debug Mode in AppDelegate.swift in didFinishLaunchingWithOptions
AppsFlyerTracker.shared().isDebug = true
Add AppsFlyer methods in your AppDelegate.swift (as per article)
Remove app (or test build) from physical device
Open Deep Link from physical device, you will be redirected to App Store. Don't install app from the App Store!!! (just close it)
Install app via XCode
After it, on a first install it will call onConversionDataReceived method and the rest staff.
You're going to have to implement the onInstallConversionDataLoaded listener:
public interface AppsFlyerConversionListener {
void onInstallConversionDataLoaded(Map<String,String> conversionData);
void onInstallConversionFailure(String errorMessage);
}
This will return a map of all the parameters on the link that you clicked.
The parameter you need to pay attention to is the af_dp parameter.
This parameter should contain the URI scheme of the activity you want to route your users to. Make sure that you have set up this URI scheme properly in the manifest.
To create a tracking link you can use Link Management. It doesn't matter if it's a single platform link or a OneLink, as long as you have the af_dp parameter on the link, that parameter (along with all other parameters on the link) will be part of the response.
If you're still facing issues, feel free to reach out to support#appsflyer.com.
FINAL EDIT
This was a bug. After filing the report it was addressed.
EDIT
I am trying to get user id in a webview of my facebook messenger bot. It works fine on mobile, yet fails on desktop (web). This should not be the case.
Messenger 2.1 release statement gives the following quote:
Desktop support for Extensions SDK: This new feature will extend functionality across mobile and web, creating a consistent experience across devices. Now, features like user ID and sharing that used to only be accessible on mobile will be available on desktop as well. This also provides developers with an easier way to test and debug when implementing webview and chat extensions.
There are two ways to get the user id with messenger extensions: getUserId() and getContext(). The docs state that getUserId() is not available on desktop, but make no mention of getContext().
Howevew, there is a bug report that states that getContext() call is not yet available on desktop.
The docs mention no other ways of getting user id. How is one supposed to do that?
As a kicker, if you read the original question, you will see that getContext() actually does work on desktop (web), but only if the webview is opened through a link sent directly by the bot.
ORIGINAL
I am working on a Facebook (messenger) bot using webview.
Now the most basic of all tasks is to get the userId.
This is where I hit a big problem. Having investigated it thoroughly, below I present cases and results.
case 1: my app sends me a generic template with a web_url button (that opens the webview) and a share button.
Everything works great. I get the user id.
case 2: I click share from the message in case 1, and share it with myself and my app.
from either message thread (I to myself, or the I to app) getContext() call return error 2018166 Permission not valid to call the SDK API. and askPermission() returns 2018154 Messenger Extensions unexpected error.
case 3: I click share from inside the webview using beginShareFlow() and share with myself and the bot.
same as case 2
case 4: here's the kicker.
activating the webview from case 2 or case 3 from Android, works and gives me the user id.
case 5: sharing to a friend who has interacted with the app before.
When that friend activates the webview, from desktop it fails, from android works.
case 6: sharing to a friend who has not interacted with the bot.
on desktop doesn't work (sharing by button or through beginShareFlow()), it works!
So, after writing all of this out, the pattern is:
on android, webview sharing works as expected: I can get the user id whether they have interacted with the bot befor or not.
on desktop, the only time the webview provides the user id, is when the message with the webview link was sent by the bot. Once it is shared by a user, the webview still opens, but does not provide context.
Just to clarify. I get the user id by using getContext, and not by getUserId which the docs specifically say doesn't work on desktop.
Is there anything I can do about this? I would like my bot's webviews to work both on desktop and mobile.
I can think of a workaround, but it's far from ideal
EDIT 2
As requested, the payload for sharing within webview is:
{
"attachment":{
"type":"template",
"payload":{
"template_type":"generic",
"elements": [{
"title":"Testing webview",
"default_action":{
"type":"web_url",
"webview_height_ratio": "full",
"messenger_extensions": true,
"url":"https://plenty.life/webview"
},
"buttons":[{
"type":"web_url",
"webview_height_ratio": "full",
"messenger_extensions": true,
"url":"https://plenty.life/webview",
"title":"Test"
}]
}]
}
}
}
Try this...
<script>
window.extAsyncInit = function() {
// the Messenger Extensions JS SDK is done loading
console.log("using getUserId in",window.name)
MessengerExtensions.getUserID(function success(uids) {
// User ID was successfully obtained.
var psid = uids.psid;
console.log(psid);
document.getElementById("userId").innerText="your User Id Is "+psid;
}, function error(err, errorMessage) {
// Error handling code
console.log("some Error",err,errorMessage)
});
MessengerExtensions.getContext('<appID>',
function success(result){
console.log("success",result)
},
function error(result){
console.log("error",result)
}
);
};
</script>
We are using Cordova along with AngularJS for iOS and Android applications.
One big disadvantage of iOS are the long review times from Apple. In Google's Playstore, your app is available nearly immediately, or within a few hours. But Apple takes ages to review your app, even when it's only a small change.
So I was thinking, if there is a way to support some kind of live update.
That means, I could provide a ZIP file or something else with a new codebase, my app checks for updates and then installs the new files.
I've read something from appmobi, but are there any open source solutions?
cordova-app-loader is an easy to use plugin to update app files via 3 simple steps:
check() for a new manifest
download() files
update() your app!
It supports android and iOS
I don't know of any ready made solutions for that, but it should be easy enough to program something like this on your own.
Here are some points to get you started and to consider:
If you want to distribute updates via zip, you need a nativ plugin which handles the extraction
You might not be able to override files in the default location of your app (depending on OS). So, all files you want to update in the future have to sit in a folder your app has read/write access to (iOS: e.g. Library or Documents folder)
Now you simply need to download the zip-package, unpack the zip to your chosen directory, and restart/reload your app.
you will not be able to update native plugins!
Apple probably doesn't like that, since you are able to change the whole application without passing
their review process
I'm doing this inside my cordova app and haven't had any issues with ios app store review.
I'm using Jquery's ajax function to download both a javascript and a css file from a server that I can change without an app store approval and then I can inject those scripts once they downloaded on app startup.
I tried using the cordova File api and I'd then save the file locally, but offline support ins't the important to me at the moment and Jquery's ajax is much simpler.
Here is the jquery code I use. I have a bundle id that I use to detect if a new javascript file is available, otherwise jquery's ajax caches the previous requests to speed up download time.
This solution lets you have a subset of your code be dynamic. I still have a base set of code that is bundled with the app, along with native plugin js and native code which would need to go through the app store. But this atleast lets me push bug fixes without going through the app store.
Otherwise, I'd look at a solution like this: http://docs.build.phonegap.com/en_US/tools_hydration.md.html
function insertScript(version) {
var scriptUrl = "";
try {
// get javascript file...
scriptUrl = mobileWebServiceUrl + "/DynamicContent/Bundles/Scripts/dynamic";
scriptUrl += "_" + bundleVersion.replace(/\./g, "_") + ".js?v=" + version;
console.log("downloading script: " + scriptUrl);
// Allow user to set any option except for dataType, cache, and url
options = {
dataType: "script",
cache: true,
url: scriptUrl
};
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return $.ajax(options).success(function(response) {
console.log("insertScript success");
dynamicContentScriptLoaded = true;
});
} catch (e) {
//console.error(e);
ReportError("problem downloading javscript: " + scriptUrl);
}
}
function insertCSS(version) {
try {
// get css file...
var cssUrl = mobileWebServiceUrl + "/DynamicContent/Bundles/Css/dynamic";
cssUrl += "_" + bundleVersion.replace(/\./g, "_") + ".css?v=" + version;
console.log("downloading dynamic css: " + cssUrl);
$.ajax(cssUrl)
.success(function (response) {
console.log("successfully downloaded dynamic css");
var script = document.createElement("style");
script.type = "text/css";
script.innerHTML = response;
$('head link').each(function () {
if ($(this).attr('href').search('MobileFrame') > -1) {
$("#MobileFrameCSS").before(script);
}
});
dynamicContentCssLoaded = true;
// TODO: implement caching at a later date
//if (isPhoneGap())
// saveFile("DynamicStyles", response);
});
} catch (e) {
ReportError("problem downloading css");
}
}
Well, Adobe offers exactly that service in their Phonegap Build service. It's called Hydration.
The example shows using it with Android and iOS platforms, so I guess they made it compatible with the iOS Dev Program License Agreement.
If you are using Cordova, you probably will have to switch to the Phonegap CLI if you want to use their build cloud services, which is basically the same as Cordova's with some extra commands to upload to their cloud, etc.
I think there are some plugin like Splashscreen wich also have some minor changes (using <gap>for params into config.xml instead of <preference>). Again, if Hydration solves the problem for you, the changes are minor and you get a really nice feature.
I think the best choice would be to not try to do this with Phonegap, but rather identify your dynamic parts and implement these in Javascript.
Yes, I mean you should indeed use Javascript yourself without Phonegap, for example via JavaScriptBridge:
https://github.com/kishikawakatsumi/JavaScriptBridge
It may require more work initially to redesign your app into a "static" part (your PhoneGap app) and dynamic part (dynamic created views via JavascriptBirdge), and interacte seemlessly between them. But in my opinion, that will be ultimately the best software design.
However, also make sure you still meet Apples AppStore requirements.
The Meteor framework provides exactly this functionality when combined with PhoneGap. It's even sanctioned by Apple in the latest Developer Agreement. Here are some technical details and then some about Apple's view on it.
I think there is no such solution is available, but you can do it by programmatic way.you can update your cardova app by fetching files from server and updating it.
Check out CodePush from Microsoft. Works with Cordova and React Native.
Appears to be very similar to the "live update" feature from Ionic Cloud.
If you migrate to capacitor, the successor of Cordova there open source solution now.
Capacitor-updater, is the only alternative to ionic AppFlow.
The updater allows you to manage update by yourself, store your zip update where you want and use the download method.
How to start
npm install #capgo/capacitor-updater
npx cap sync
Then in your main JS, this is required to let the updater know the update is valid
import { CapacitorUpdater } from '#capgo/capacitor-updater'
CapacitorUpdater.notifyAppReady()
And lately after checking yourself the current version need update:
const version = await CapacitorUpdater.download({
url: 'https://github.com/Cap-go/demo-app/releases/download/0.0.4/dist.zip',
})
await CapacitorUpdater.set(version); // sets the new version, and reloads the app
After many request of people didn't want to do that themselves, I started Capgo a business to manage all the update process.
All is open source and can be replicate on your own as well.
Doing things for Capacitor is now my main activity, I produce open-source plugin as my main channel of Marketing, I'm solo founder and bootstrapped.
Hope my tool will help you !
Not really sure how to correctly describe this so hopefully some of you know what I mean.
Our client is getting a mobile app for thier site, hopefully soon, and I have noticed on android devices and sure they probably exist on iphones too, a popup to inform you that said site has an app. I have seen it on forums that support tapatalk as well as the sammobile.com website. Its a small message and an "ok" and "cancel" button, ok takes you to the app in the market.
Googles only really helpful when you know or at least can correctly describe what you are looking for.
Does anyone know
A) Do iPhones also have this feature and
B) how would I go about triggering such a popup/notification?
Using some infor from a java push trigger as well as a few other Stacks I put this together.
if (/Android|iPhone|BlackBerry/i.test(navigator.userAgent)) {
var url = confirm("Would you like to download our mobile application?");
if (url === true) {
var url = window.location.href = 'http://www.google.com';
url.show();
}
}
Will test for the 3 devices mentioned, if so will create a confirmation box for which confirmation will direct the user to another url.