The dialer is not showing full ussd code eg: *123*1# - dart

I am using the url_launcher plugin for call, but the dialer is not showing the # character:
String url = 'tel:*123#';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}

You need to use URL encoding for special character in a URL.
So # equals %23
This will work launch('tel:\*123\%23');
Other Way is to encode the number typed by user and pass it through Uri.encodeFull(urlString) or Uri.encodeComponent(urlString)
Like this.
launch("tel:" + Uri.encodeComponent('*123#'));

Disclaimer: plugin author here.
Do you want the phone call user interface to open or would you rather make the request silently? If you prefer to do it without popping the phone call UI, Android introduced in API level 26 the method sendUssdRequest.
I made a Flutter plugin called ussd_service to be able to easily access it from dart in a Flutter application. It can be used in the following manner:
import 'package:ussd_service/ussd_service.dart';
makeMyRequest() async {
int subscriptionId = 1; // sim card subscription Id
String code = "*21#"; // ussd code payload
try {
String ussdSuccessMessage = await UssdService.makeRequest(subscriptionId, code);
print("succes! message: $ussdSuccessMessage");
} on PlatformException catch (e) {
print("error! code: ${e.code} - message: ${e.message}");
}
};
makeMyRequest();
Hope this helps! Let me know on the Github repo's issues if you have any issue with it.

Related

React native track player fails to add songs to playlist

I am working on a music player in react native and have been using the package react-native-track-player. I have so far not had a problem with the package in android. but when I try to run it on ios I get the error
You attempted to set the key0with the value
{"id":"0",
"url":{"uri":"https://urltosong.mp3"},
"artwork":"https://url_to_artwork.jpg",
"artist":"author",
"title":"song titile"
}
on an object that is meant to be immutable and has been frozen.
The code that generate the error is
async function togglePlayback() {
const currentTrack = await TrackPlayer.getCurrentTrack();
if (currentTrack == null) {
await TrackPlayer.reset();
await TrackPlayer.add(playlist); //this was never adding and die silently
await TrackPlayer.play();
} else {
await TrackPlayer.add(playlist); //adding this line the error above appeared
await TrackPlayer.play();
//console.warn(TrackPlayer.getCurrentTrack())
}
}
I am using this version of the package "react-native-track-player": "^2.0.0-rc13",
I don't know if there is something I am missing. I will appreciate your help in fixing this.
Change your track to this:
{"id":"0",
"url":"https://urltosong.mp3",
"artwork":"https://url_to_artwork.jpg",
"artist":"author",
"title":"song titile"
}
Urls should be either a string or a Resource Object

How to open Apple Maps using Flutter/Dart?

Our Flutter App shows a number of locations using Google Maps, if available, or else using the local browser.
Although we had already previously uploaded a binary code for iOS which was accepted by Apple and successfully published in the App Store, now that we have added some more locations and thus attempted to publish a new version, Apple has rejected our binary, stating that it is mandatory to use "Apple Maps" instead of anything that starts with a "G", like Google...
The rejection message reads as follows:
Your app's location feature is not integrated with the built-in mapping functionality, which limits users to a third-party maps app.
Next Steps
To resolve this issue, please revise your app to give users the option to launch the native Apple Maps app.
I have found that there exists some documentation about a Javascript library named MapKit JS, which serves precisely the purpose of interacting with Apple Maps: https://developer.apple.com/maps/mapkitjs/
<script src="https://cdn.apple-mapkit.com/mk/5.x.x/mapkit.js"></script>
<script>
mapkit.init({
authorizationCallback: function(done) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/services/jwt");
xhr.addEventListener("load", function() {
done(this.responseText);
});
xhr.send();
}
});
var Cupertino = new mapkit.CoordinateRegion(
new mapkit.Coordinate(37.3316850890998, -122.030067374026),
new mapkit.CoordinateSpan(0.167647972, 0.354985255)
);
var map = new mapkit.Map("map");
map.region = Cupertino;
</script>
Nevertheless, I could really use some help no how to connect with this MapKit JS using DART, instead of JAVA, for our Flutter application.
Thank you immensely for your kind help!
Daniel
Firstly, install the url_launcher plugin
Secondly, add the below code in Info.plist:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>googlechromes</string>
<string>comgooglemaps</string>
</array>
Thirdly:
var urlAppleMaps = 'https://maps.apple.com/?q=$lat,$lng';
if (await canLaunch(urlAppleMaps)) {
await launch(urlAppleMaps);
} else {
throw 'Could not launch $url';
}
We can use it like this:
_launchMap(BuildContext context, lat, lng) async {
var url = '';
var urlAppleMaps = '';
if (Platform.isAndroid) {
url = "https://www.google.com/maps/search/?api=1&query=${lat},${lng}";
} else {
urlAppleMaps = 'https://maps.apple.com/?q=$lat,$lng';
url = "comgooglemaps://?saddr=&daddr=$lat,$lng&directionsmode=driving";
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
if (await canLaunch(url)) {
await launch(url);
} else if (await canLaunch(urlAppleMaps)) {
await launch(urlAppleMaps);
} else {
throw 'Could not launch $url';
}
}
You could try to use a Map Launcher plugin to launch apple/google maps depending on a platform
import 'dart:io';
import 'package:map_launcher/map_launcher.dart';
if (Platform.isIOS) {
await MapLauncher.launchMap(
mapType: MapType.apple,
coords: Coords(31.233568, 121.505504),
title: "Shanghai Tower",
description: "Asia's tallest building",
);
} else {
await MapLauncher.launchMap(
mapType: MapType.google,
coords: Coords(31.233568, 121.505504),
title: "Shanghai Tower",
description: "Asia's tallest building",
);
}
Just an idea but maybe you can try to use the url_launch plugin to launch a url following the schemata given in the apple maps url schemata given here: https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html#//apple_ref/doc/uid/TP40007899-CH5-SW1
A simple solution I have found is to replace the google maps URL with a maps.apple.com equivalent, using the same url_launcher function.
For example, the original function for Google Maps:
void _mapaBethania() async {
const url = "https://www.google.com/maps/place/Panamanian+Institute+for+Special+Training/#9.0067418,-79.5300556,17z/data=!3m1!4b1!4m5!3m4!1s0x8faca84549395297:0x9c54b1fdb96ac590!8m2!3d9.0067365!4d-79.5278669";
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Lo sentimos, no es posible abrir: $url';
}
}
Has become:
void _mapaBethania() async {
const url = "https://maps.apple.com/?q=IPHE&ll=9.0067418,-79.5300556&z=16";
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Lo sentimos, no es posible abrir: $url';
}
}
Nevertheless, although this change does fulfill Apple's enforced obligation to use their own software instead of the competition's, the user experience with Apple Maps is very poor, because once the Map App is shown, it becomes a bit confusing and difficult to return back to the original App.
Therefore, I am planning to write code that enables both options, Apple Maps in order to comply with Apple enforcement, and also Google Maps in order to provide a better user experience, despite Apple.
Anyway, the latter is just a personal opinion; the true fact is that replacing the URL for a maps.apple.com equivalent using the same launch_url function, does seem acceptable to comply with Apple requirements.

Send notification from web to android device using Firebase

I am trying for a while now to implement this flow: When user adds some files on server app, notification should trigger and send from server to FCM and that from there to pass message saying something like: 'New file has been added'.
Basically I want to inform mobile device user that something on server has been changed.
I have tried many things, but nothing seems to work as I would expect, at least.
On the mobile side I have set up Firebase inside my Xamarin.Android project, and when I am sending notifications directly from Firebase console, I get notifications, and everything is good.
But I don't want to send notifications via Firebase console, I would rather send notification from server (which is ASP.NET MVC project) to Firebase console and then pass it from there to android device.
My first question would be: Has anybody got an idea how can I inform web app about device_id? Is there some way that android device send this information on server? And maybe from there I can store that data and update it occasionally, since it is basically a refresh token.
My second problem is this: Even when I hard code current device_id of an active android device and try to send a message from server whit this code:
public class FirebaseService : IFirebaseService
{
public void SendMessageToClientApplication(string message, string serverApiKey, string senderId, string deviceId)
{
AndroidFCMPushNotificationStatus result = new AndroidFCMPushNotificationStatus();
try
{
result.Successful = false;
result.Error = null;
deviceId = "eMk6mD8P8Dc:APA91bG5Lmqn4Hwb4RZJ1Mkdl8Rf_uYQsQCEfDJK334tzSvIGzdao7o2X6VmtcTEp_Li0mG8iUoUT7-_RnZxQKocHosZwx6ITWdpmQyCwUv60IIIy0vxNlEaccT6RqK6c-cE1C6I3FTT";
var value = message;
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
tRequest.Headers.Add(string.Format("Authorization: key={0}", serverApiKey));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message="
+ value + "&data.time=" + DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
result.Response = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
result.Successful = false;
result.Response = null;
result.Error = ex;
}
}
}
I get nothing both in Firebase console and of course nothing on device as well.
I have tried to implement Firebase web as javascript on my server app like this:
<script>
var config = {
apiKey: "mykey",
authDomain: "myauthdomain",
databaseURL: "mydatabaseurl",
projectId: "myprojectid",
storageBucket: "mystoragebucket",
messagingSenderId: "mysenderid"
};
window.onload = function () {
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function () {
console.log('Notification permission granted.');
return messaging.getToken()
})
.then(function (token) {
console.log(token);
})
.catch(function (err) {
console.log('Unable to get permission to notify.', err);
});
messaging.onMessage(function (payload) {
console.log('onMessage: ', payload);
});
}
</script>
But this code gets some kind of a different device_id(aka token), probably one generated for that server machine.
Does anybody has experience with sending device_id to server app and from there sending notification message to Firebase console? I would appreciate some code examples, tutorials or anything that can help, since I was unable to find something useful during my google search.
My first question would be: Has anybody got an idea how can I inform web app about device_id?
The most common approach is to store the list of device tokens (each device that uses FCM has such a token) in a database, such as the Firebase Database. There is an example of this in the Cloud Functions for Firebase documentation. In this example the devices receiving the messages are web pages, but the approach is the same for iOS and Android.
I also recommend reading Sending notifications between Android devices with Firebase Database and Cloud Messaging. In this article, instead of sending to a device token, each user subscribes to a topic. That prevents having to manage the device tokens in your code.

Delphi Send Device to Device message using firebase [duplicate]

Is there any way to send Upstream notification message through FCM from one android device to another devices connected with Firebase database.
I know that XMPP server can then receive the upstream messages and send the notifications to the other devices.To receive messages sent with the upstream API i need to implement an XMPP server but there is any other way???
Is there any way to send Upstream notification message through FCM
from one android device to another devices connected with Firebase
database?
Currently it's NOT possible to send messages directly from one device to another.
(or at least it's not possible without introducing a HUGE security vulnerability: more details below)
Full details:
Sending messages to a user device is a pretty serious action!
based on the payload a message can result in spam, phishing, execution of internal methods.
You want this operation to be allowed only be trusted entities, this is why the FCM send API requires the SERVER-API-KEY in the authentication header.
Adding the SERVER-API-KEY in your app code (or communicating it to the app in some other way) IS NOT SAFE. This because apk can be extracted, decompiled, inspected, executed on emulators, executed under debugging and so on.
The best way to implement this today: is to have some sort of server between the two devices:
[DeviceA] -- please send message to B --> [SERVER] -- fcmSendAPI --> [DeviceB]
The server can be as simple as a PHP page, or a more complex XMPP implementation.
An example in Node.js can be found here:
Sending notifications between devices with Firebase Database and Cloud Messaging
Finally, after 2 months of trying to maintain reliable server script myself, I suddenly found OneSignal. It's completely free, supports device-to-device push messages on iOS, Android, WP and browsers.
Hope, I won't get flag for promotion spam, but it's currently the only (and easiest) way to be completely "backendless".
Also, it's completely secure way. Nobody can send push unless he knows special OS user id, which you can store in Firebase Database protected by rules.
UPD: It's not a replacement for Firebase. It has only push service and nothing else
UPD2: Firebase now has Functions, and examples of it usage has sending FCM. You now don't need any other server or service. Read more in official samples https://github.com/firebase/functions-samples
After lots of try finally i got one solution and its work perfectly
Step 1 :Include two library.
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.google.firebase:firebase-messaging:9.2.0'
Step 2 : In your MainActivity or from where you want to send notifications.
OkHttpClient mClient = new OkHttpClient();
String refreshedToken = "";//add your user refresh tokens who are logged in with firebase.
JSONArray jsonArray = new JSONArray();
jsonArray.put(refreshedToken);
Step 3: Create one async task which sends notifications to all devices.
public void sendMessage(final JSONArray recipients, final String title, final String body, final String icon, final String message) {
new AsyncTask<String, String, String>() {
#Override
protected String doInBackground(String... params) {
try {
JSONObject root = new JSONObject();
JSONObject notification = new JSONObject();
notification.put("body", body);
notification.put("title", title);
notification.put("icon", icon);
JSONObject data = new JSONObject();
data.put("message", message);
root.put("notification", notification);
root.put("data", data);
root.put("registration_ids", recipients);
String result = postToFCM(root.toString());
Log.d("Main Activity", "Result: " + result);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
try {
JSONObject resultJson = new JSONObject(result);
int success, failure;
success = resultJson.getInt("success");
failure = resultJson.getInt("failure");
Toast.makeText(MainActivity.this, "Message Success: " + success + "Message Failed: " + failure, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "Message Failed, Unknown error occurred.", Toast.LENGTH_LONG).show();
}
}
}.execute();
}
String postToFCM(String bodyString) throws IOException {
public static final String FCM_MESSAGE_URL = "https://fcm.googleapis.com/fcm/send";
final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, bodyString);
Request request = new Request.Builder()
.url(Url.FCM_MESSAGE_URL)
.post(body)
.addHeader("Authorization", "key=" + "your server key")
.build();
Response response = mClient.newCall(request).execute();
return response.body().string();
}
Step 4 : Call in onclick of your button
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessage(jsonArray,"Hello","How r u","Http:\\google.com","My Name is Vishal");
}
});

C# - Xamarin - HttpClient - Operation is not valid due to the current state of the object - iOS

I'm working on a cross platform library that makes HTTP requests. It's working fine on Android, but when I try to use it on iOS I'm getting an exception and I can't figure out how to fix it.
Here is my code:
// method from cross platform library
Task.Factory.StartNew(delegate
{
try
{
var client = new HttpClient();
// some other setup stuff
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.post, "http://myurl.com...");
var task = client.SendAsync(request);
task.Wait(); // Exception thrown on this line
var response = task.Result;
var responseString = response.Content.ReadAsStringAsync().Result;
}
catch (Exception e)
{
}
}
On task.Wait(); I get a System.AggregateException with an inner exception of System.InvalidOperationException that says Operation is invalid due to the current state of the object.
Trying to find some solutions, I found that the issue could be cause by calling this on the UI thread. But that's the whole point of wrapping this all in Task.Factory.StartNew.
I've tried everything I know to do and have yet to solve the issue. Any help would be very appreciated.
Edit:
I decided to try my solution on an iPhone simulator. It's an iPhone 6 simulator running iOS 10. My physical device is the same. It works on the simulator, but not the physical device for some reason... very strange.
Edit 2:
Thanks to #YuriS for finding a solution.
From: https://forums.xamarin.com/discussion/36713/issue-with-microsoft-http-net-library-operation-is-not-valid-due-to-the-current-state-of-the-objec
What you can do is:
1) Go to References of ios Project
2) Edit References
3) Check 'System.Net.Http'
Behaviour for android is the same.
There can be few problems described here:
https://forums.xamarin.com/discussion/36713/issue-with-microsoft-http-net-library-operation-is-not-valid-due-to-the-current-state-of-the-objec
https://bugzilla.xamarin.com/show_bug.cgi?id=17936
"Operation is not valid" error at Xamarin.iOS project with HttpClient
http://motzcod.es/post/78863496592/portable-class-libraries-httpclient-so-happy
Seems all post pointing on System.Net.Http
Regardless of the problem there is a better ways doing this.One of them:
public static async Task PostRequest()
{
try
{
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://myuri");
//request.Headers.Add("", "");
var response = await client.SendAsync(request);
var responseString = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
}
}
If you want to wait till function completes you call
await PostRequest();
If you don't need to wait then just omit "await" in the call or use
PostRequest.ContinueWith((t)=>
{
});
Also you need to handle an exception within the function, so probably returning just Task is not the best. I was just basing my answer on original function signature

Resources