Does Android support window.location.replace or any equivalent? - android

It seems that the Android browser doesn't properly implement window.location.replace.
In most browsers, calling window.location.replace will replace the current URL with the URL passed to it.
When the user navigates somewhere else then clicks back, they'll be returned to the URL that was passed to window.location.replace, rather than the URL that they were at before window.location.replace was called.
The Android browser doesn't seem to implement this properly.
In the Android browser, the user will be directed back to the original URL rather than the one passed to window.location.replace.
You can test this for yourself here.
So is there any alternative way to re-write history in Android? Or will I just have to live without that feature, for Android users?

I had the same issue and ended up with code similar to chris suggestion, but I changed the if statement to use modernizr's feature detection.
If you're not using modernizr the code would look something like this:
if(!!(window.history && history.replaceState)){
window.history.replaceState({}, document.title, base + fragment);
} else {
location.replace(base + fragment);
}
Unless you have a specific reason for device detection, feature detection is preferred since it basically supports all devices, even future ones.

To make it work across all/most mobile platforms check out this link.
Shows how to handle redirect for Android, iPad and iPhone.
Android uses document.location whereas iOS supports window.location.replace

Will this work?
document.location.href = 'http://example.com/somePage.html';

You can try using the replaceState method on the history window.history
if (((navigator.userAgent.toLowerCase().indexOf('mozilla/5.0') > -1 && navigator.userAgent.toLowerCase().indexOf('android ') > -1 && navigator.userAgent.toLowerCase().indexOf('applewebkit') > -1) && !(navigator.userAgent.toLowerCase().indexOf('chrome') > -1))) {
window.history.replaceState({}, document.title, base + fragment);
} else {
location.replace(base + fragment);
}

Related

Pepper Robot - How to launch tablet applications through DialogFlow?

I'm trying to incorporate Pepper's built in Android tablet more in DialogFlow interactions. Particularly, my goal is to open applications installed on the tablet itself for people to use while they're talking with Pepper. I'm aware there is a 'j-tablet-browser' app installed on Pepper's end that can let a person browse the tablet like an ordinary Android device, but I would like to take it one step further and directly launch an Android app, like Amazon's Alexa.
The best solution I can up with is:
User says specific utterance (e.g. "Pepper, open Alexa please")
DialogFlow launches the j-tablet-browser behavior
{
"speak": "Sure, just a second",
"action": "startApp",
"action_parameters": {
"appId": "j-tablet-browser/."
}
}
User navigates the Android menu manually to tap the Alexa icon
My ideal goal is to make the process seamless:
User says specific utterance (e.g. "Pepper, open Alexa please")
DialogFlow launches the Alexa app installed on the Android tablet
Does anyone have an idea how this could be done?
This is quite a broad question so I'll try and focus on the specifics for launching an app with a Dialogflow chatbot. If you don't already have a QiSDK Dialogflow chatbot running on Pepper, there is a good tutorial here which details the full process. If you already have a chatbot implemented I hope the below steps are general enough for you to apply to your project.
This chatbot only returns text results for Pepper to say, so you'll need to make some modifications to allow particular actions to be launched.
Modifying DialogflowDataSource
Step 2 on this page of the tutorial details how to send a text query to Dialogflow and get a text response. You'll want to modify it to return the full reponse object (including actions), not just the text. Define a new function called detectIntentFullResponse for example.
// Change this
return response.queryResult.fulfillmentText
// to this
return response.queryResult
Modifying DialogflowChatbot
Step 2 on this page shows how to implement a QiSDK Chatbot. Add some logic to check for actions in the replyTo function.
var response: DetectIntentResponse? = null
// ...
response = dataSource.detectIntentFullResponse(input, dialogflowSessionId, language)
// ...
return if (reponse.action != null) {
StandardReplyReaction(
ActionReaction(qiContext, response), ReplyPriority.NORMAL
)
} else if (reponse.answer != null) {
StandardReplyReaction(
SimpleSayReaction(qiContext, reponse.answer), ReplyPriority.NORMAL
)
} else {
StandardReplyReaction(
EmptyChatbotReaction(qiContext), ReplyPriority.FALLBACK
)
}
Now make a new Class, ActionReaction. Note that the below is incomplete, but should serve as an example of how you can determine which action to run (if you want others). Look at SimpleSayReaction for more implementation details.
class ActionReaction internal constructor(context: QiContext, private val response: DetectIntentResponse) :
BaseChatbotReaction(context) {
override fun runWith(speechEngine: SpeechEngine) {
if (response.action == "launch-app") {
var appID = response.parameters.app.toString()
// launch app at appID
}
}
}
As for launching the app, various approaches are detailed in other questions, such as here. It is possible to extend this approach to do other actions, such as running or retrieving online data.

How to open Android Outlook application from an external one

I'm currently developing an Android application in order to display home screen widgets. Those ones are related to Microsoft Outlook (Events + Messages) in order to show incoming events and unread new messages in a kind of dynamic tiles.
The Msal graph library helps me a lot to authenticate and retrieve in formations which contains an identifier for each event / message results
But now I want to know if the outlook application is installed on the user device and if there is a way to open Outlook when the user click on the widget. Moreover if the user can open the corresponding clicked event or message with the identifier.
For example the Event widget currently displaying a birthday event. The user click on it. Then it opens Outlook and display directly that birthday event.
Regards
I don't think this is officially documented somewhere. But here's what you can do to find out about it.
You can list all Microsoft applications installed on your device...
val packages = context.packageManager
.getInstalledApplications(PackageManager.GET_META_DATA)
for (info in packages) {
if(info.packageName.startsWith("com.microsoft", true)){
Log.d("package name:" + info.packageName)
Log.d("Launch Activity: " + context.packageManager.getLaunchIntentForPackage(info.packageName))
}
}
Take a note of the "launch intent" displayed in the LogCat. You can use that to launch Outlook. Just make sure you don't hard-code those values because Microsoft can change those values at any point, for example the activity class can change. So, instead of doing this...
context.startActivity(
Intent().apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
setPackage("com.microsoft.office.outlook")
component = ComponentName("com.microsoft.office.outlook", "com.microsoft.office.outlook.MainActivity")
}
)
Do this...
context.startActivity(
Intent().apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
component = ComponentName(
outlookLaunchIntent?.component?.packageName,
outlookLaunchIntent?.component?.className
)
setPackage(outlookLaunchIntent.package)
}
)
Also, remember that getLaunchIntentForPackage and component can return null, so make sure you check for null values properly
I am relaying a suggestion from a couple of internal folks:
Please try to open the event using one of the following URLs:
ms-outlook://events/open?restid=%s&account=test#om.com (if you have a regular REST id)
ms-outlook://events/open?immutableid=%s&account=test#om.com (if you are using an immutable id)
Since immutable IDs are still in preview stage in Microsoft Graph, and customers should not use preview APIs in their production apps, I think option #1 applies to your case.
Please reply here if the URL works, or not, and if you have other related questions. I requested the couple of folks to keep an eye on this thread as well.
Well, i managed to open the outlook android application with the help of your code #Leo. As im not developping with Kotlin, ill post the JAVA code below :
Intent outlookLaunchIntent = context.getPackageManager().getLaunchIntentForPackage("com.microsoft.office.outlook");
if (outlookLaunchIntent != null) {
context.startActivity(outlookLaunchIntent );
}
Below code to open event/message in a web browser provided by webLink property of the graph API. (I only test for event and the url provided not working. Ill post a new issue on StackOverFlow for that but you already see the issue over there : https://github.com/microsoftgraph/microsoft-graph-docs/issues/4203
try {
Intent webIntent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(calendarWebLink));
webIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(webIntent);
} catch (RuntimeException e) {
// The url is invalid, maybe missing http://
e.printStackTrace();
}
However im still stuck on the decicive goal of my widget item click which is to open the relative event/email in the Microsoft Outlook Android application.
Microsoft Outlook Android app contains widgets which can achieve what im looking for. So i wonder if it is possible to list its broadcast receivers.
The best thing i found is an old manifest for that app but it doesnt help me.
https://gist.github.com/RyPope/df0e61f477af4b73865cd72bdaa7d8c2
Hi may you try to open the event using one of the url:
ms-outlook://events/open?restid=%s&account=test#om.com (If the
user is having rest id)
ms-outlook://events/open?immutableid=%s&account=test#om.com (If
the user is having immutable id)

How to Get info about phone calls

I have to develop a mobile application that monitors some info about calls, to limit users of a company to spend too much time with the phone near their ears. After x minutes, it should suggest to use earphones.
1st question: is it possible to monitor data like this? Phonecall time duration, start and end, if it's using earphones, internal or external speaker.. I mean, without using jailbreak or other hackings.
2nd question: is it possible doing this for IOS and Android?
3rt question: Do you know if Ionic has the capability to that?
Thank you.
Answering your questions:
Question1: Yes it's possible on Android. It's not possible on iOS. In Android, you can get call information if the user permits. You don't need to do jailbreaking or something. Whereas in iOS no way you can access call info.
Question2: Hope my first answer itself answers this. i.,e Android-Possible, iOS- not Possible
Question 3: AFAIK ionic framework is providing only basic details of Phone call time duration and contacts framework. You should explore more on Android to find out. Even if you use ionic framework you can't access this info at all on iPhone as native ios only not providing these details, we can't expect this from ionic framework.
For Android:
You can easily get the call history or incoming and outgoing call time.
So it is possible in android.
For iOS:
According to your question you want to limit the current calling time of phone near their ears.
So you also do it in iOS by some smartness.
In iOS 10 a new framework introduces for calling i.e. CallKit.
First, you have to get all contact in your application.
So user should call from your app.
For dialing also add the custom phone dialer.
By Some method of callKit you can do:
Add a call observer
#property ( nonatomic ) CXCallObserver *callObserver;
Initialize the call observer:
(instancetype)init
{
self = [super init];
if (self) {
//Initialize the call observer
_callObserver = [CXCallObserver new];
[_callObserver setDelegate:self queue:dispatch_get_main_queue()];
}
return self;
}
Add the delegate of call kit
#pragma mark - CXCallObserverDelegate
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call{
[self callStateValue:call];
}
#pragma mark - Callkit State
- (void)callStateValue:(CXCall *)call {
NSLog(#"Call UIID: %#", call.UUID);
NSLog(#"hasEnded %#", call.hasEnded? #"YES":#"NO");
NSLog(#"isOutgoing %#", call.isOutgoing? #"YES":#"NO");
NSLog(#"isOnHold %#", call.isOnHold? #"YES":#"NO");
NSLog(#"hasConnected %#", call.hasConnected? #"YES":#"NO");
if (call == nil || call.hasEnded == YES) {
NSLog(#"CXCallState : Disconnected");
[timer1 invalidate];
NSLog(#"%ld",(long)self.duration);
if(self.duration>1)
self.duration=1;
}
if (call.isOutgoing == YES && call.hasConnected == NO) {
}
if (call.isOutgoing == NO && call.hasConnected == NO && call.hasEnded == NO && call != nil) {
self.duration = 0;
NSLog(#"CXCallState : Incoming");
NSLog(#"Call Details: %#",call);
}
if (call.hasConnected == YES && call.hasEnded == NO) {
NSLog(#"CXCallState : Connected");
timer1 = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
self.duration++;
NSLog(#"%ld",(long)self.duration);
}];
}
}
You can get the time duration and also add the condition After x minutes, it should suggest to use earphones.

Disabling 'go' button form submission in Android

I have almost completed an ASP.NET webforms website using jQuery Mobile. I am stuck on one specific use case.
The site is scoped to support Android, iPhone, BlackBerry and Windows Mobile all of the functionality works great except for one specific use case.
The case is when a user is entering a value into one of the input boxes and then hits the native Go/Enter key. I am capturing this and throwing the appropriate event submit button click/tap with jquery.
function BindSubmit(textbox, button) {
$(textbox).unbind().keypress(function (event) {
var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
if (keyCode == 13) {
$(button).trigger('tap');
}
});
}
This works great on all devices but one, Android. The phone ends up submitting the entire form instead of following the use case. Grabbing the onsubmit event and returning false doesn't work either. After some digging I found this Disabling 'go' button form submission in Android when using webview .
I am hoping for a solution to this for a standard webform. Thanks.
Thank you for the help. The way we solved this is binding to the form.submit event and calling the mobile.changePage() ourselves. Then after the changePage() we return false; This prevented the full form submit and still allowed jquery mobile to complete its actions.
Try running $(button).trigger('click'). This might be a better, more cross-platform way of sending the event.
You should definitely try to test it like this on an Android phone and find out when and where execution fails:
function BindSubmit(textbox, button) {
console.log("BindSubmit()");
$(textbox).unbind().keypress(function(event) {
var keyCode = ...;
console.log("Key pressed: " + keyCode + ", isEnter: " + keyCode == 13);
if (keyCode == 13) {
console.log("Enter key hit, triggering event.");
...;
}
});
}
If you have a link to it, I'd be happy to test it on my Nexus One for you :)

android/iphone click to call in html

I am creating one HTML mobile website for android & ios device.
I know click to call for both.
ANDROID
2125551212
iOs
Live Support
Now, my problem is i have one webpage with click to call link and want that link work for both android / ios
Just use tel: it will work on iOS, android, blackbarry OS, windows and many more. Using this scheme will work on almost all mobile browsers on.
You have to recognize the client. Since different phones have different user agents, you can do something like this with JavaScript:
if (navigator.userAgent.indexOf("Android") != -1) {
txt = "2125551212";
} else if (navigator.userAgent.indexOf("iPhone") != -1) {
txt = "Live Support";
}
This works for me as well.
212-555-1212
The problem with this is it will break add-ons and extensions that people may use on desktop browsers.
The plain phone number will call on click for Android OS.
<p>212-555-1212</p>
You can also track this call with AdWords. I am working on getting it to work with Google Analytics.
In regards to MoyShe's post and not to steal her code (complements) I would add a conditional default for Desktop browsers and other as well using a default else statement.
if (navigator.userAgent.indexOf("Android") != -1) {
txt = "2125551212";
} else if (navigator.userAgent.indexOf("iPhone") != -1) {
txt = "Live Support";
}
<!--what about other devices OS-->
else {
txt = "<span><strong>Phone -</strong> 282-122-9627 ext.7877</span>";
}
That way desktop browsers users could also see a phone number as it would display a phone number by default if the device is not of the two handheld device queried.
I am not versed in android, blackberry, IOs, windows, etc...but I would also like to ask or point out my comment section.
<!--what about other devices OS-->
(For Newbs- the above line of commented code can be removed when pasting in the web page).
What about blackberry and all the other device OS's? Are they Android or IOs driven OS's? If not, additional code to specifically identify those devices would also need to be created and included in the (else if's) statements.
If I am correct in my unknown question, a Switch/Case statement might be cleaner and a better way to go.
as on
Msaccess Help Australia www.msaccess.com.au
You only want ordinary text showing on a PC browsers
so put this line in your page
<script type="text/javascript" src="javascript.js"></script>
and save the below in a file called javascript.js
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf ("mobile");
if (isAndroid)
{document.write('<a class="mobilesOnly" href="tel:++61476132591"> Click here to call tel:++61476132591</a>');}
else
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPad/i)))
{document.write('<a class="mobilesOnly" href="tel:++61476132591"> Click here to call now: tel:++61476132591</a>');}
else
{document.write('Call ++61476132591') ;}
don't forget to change the number :)

Categories

Resources