Failure to pass # as input in dialer application - android

I am building an android dialer application, but when my input contains string of form *123# the number which gets dialed is *123.
How can I pass # also in the dialer application?
Below is the code:
public void onDial(View v) {
if (input.getText().length() <3) {
Toast.makeText(this, "Please Enter the Valid Number", Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent(Intent.ACTION_CALL);
String hash = input.getText().toString();
if (hash.contains("#")) {
hash.replace("#", "%23");
}
intent.setData(Uri.parse("tel:" + hash));
if (ActivityCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
startActivity(intent);
}else{
requestCallPermission();
}
}
}

You where close! Encoding will work, but the replace method returns a new string! :-)
if (hash.contains("#")) {
hash = hash.replace("#", "%23"); // Need to set the hash reference to the new string generated by replace()!
}
intent.setData(Uri.parse("tel:" + hash));
Refs:
http://zetcode.com/kotlin/strings/
How to use Uri.parse() with # at the end

Related

xamrin android visual studio 2019 community version for WhatsApp chat with button click on specific number

I want to add button in my app. when I click on the button this will redirect me to WhatsApp chat having that specific number and chat with that number. I have the following code but its not working :(
public void Button1_Click(object sender, System.EventArgs e)
{
string phoneNumberWithCountryCode = "+9233623xxx";
string message = "Hallo";
StartActivity(new Intent(
Intent.ActionView, Android.Net.Uri.Parse("https://api.whatsapp.com/send?phone=" + phoneNumberWithCountryCode + "&text=" + message)));
}
Button button1 = FindViewById<Button>(Resource.Id.watsapp_op);
button1.Click += (sender, e) => {
Button1_Click(sender, e);
};
I saw the working sample , it sets Package in Intent , so try the following code .
private void OpenWhatsApp(Activity activity, string number, string message)
{
try
{
PackageManager packageManager = activity.PackageManager;
Intent i = new Intent(Intent.ActionView);
String url = "https://api.whatsapp.com/send?phone=" + number + "&text=" + URLEncoder.Encode(message, "UTF-8");
i.SetPackage("com.whatsapp");
i.SetData(Uri.Parse(url));
if (i.ResolveActivity(packageManager) != null)
{
activity.StartActivity(i);
}
else
{
//Error message
}
}
catch (Exception e)
{
// exception
}
}
Update
Does the button on the current content view or not ?
You can see SetContentView(Resource.Layout.activity_main) in OnCreate method .
You have to ensure the button is placed in activity_main.xml , if the button is in another layout , you have to find the view first .
var view = LayoutInflater.Inflate(Resource.Layout.anotherlayout,null);
var button = view.FindViewById<Button>(Resource.Id.button);

Flutterwave Android payment integration - cannot process payment - error unable to retrieve transaction fee

I'm using Rave for the first time, it looked so flexible and easier to integrate, but along the line. I got stuck with testing, I'm using only card and bank payments methods.
when I choose the card to and enter some test cards from the test card link https://developer.flutterwave.com/reference#test-cards-1
I get 2 errors, => "unable to retrieve transaction fees" but in my logcat I see => " only test cards ree allowed," of which were using the test cards. And am also on staging mode which I assume is correct while testing with test keys.
When I use the bank tab I get some error in JSON toasted, but display later => "parents_limit not defined". Not just that I give this errors, I still found transactions of the bank payment types recorded on my dashboard. This confuses me more since I didn't get the payment success message so I can verify and give value to the customer.
I have integrated everything as per guideline in Rave docs, which calls my make payment. from https://github.com/Flutterwave/rave-android
variable for implementation
//online payment
String[] fullname;
String email = "";
String fName = "";
String lName = "";
String narration = "Payment for Riidit App activation";
String txRef;
String country = "NG";
String currency = "NGN";
private String mUsername, userID, mEmail;
the payment method
private void makePayment(int amount) {
txRef = email + " " + UUID.randomUUID().toString();
try {
fullname = mUsername.split(" ");
fName = fullname[0];
lName = fullname[1];
} catch (NullPointerException ex) {
ex.printStackTrace();
}
/*
Create instance of RavePayManager
*/
new RavePayManager(this).setAmount(amount)
.setCountry(country)
.setCurrency(currency)
.setEmail(email)
.setfName(fName)
.setlName(lName)
.setNarration(narration)
.setPublicKey(RiiditUtilTool.getPublicKey())
.setEncryptionKey(RiiditUtilTool.getEncryptionKey())
.setTxRef(txRef)
.acceptAccountPayments(true)
.acceptCardPayments(true)
.acceptMpesaPayments(false)
.acceptGHMobileMoneyPayments(false)
.onStagingEnv(false)
.allowSaveCardFeature(true)
.withTheme(R.style.DefaultTheme)
.initialize();
}
//called from below
private void payOnline()
{
makePayment(amount);
}
public void onActivateOnlineClick(View v) {
payOnline();
}
// expecting result of payment here either fail or success
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RaveConstants.RAVE_REQUEST_CODE && data != null) {
String message = data.getStringExtra("response");
if (resultCode == RavePayActivity.RESULT_SUCCESS) {
Toast.makeText(this, "SUCCESS " + message, Toast.LENGTH_LONG).show();
// get a PIN and SERIAL no when payment succeeds
getGetPinAndSerialForPaidUser();
} else if (resultCode == RavePayActivity.RESULT_ERROR) {
Toast.makeText(this, "ERROR " + message, Toast.LENGTH_LONG).show();
} else if (resultCode == RavePayActivity.RESULT_CANCELLED) {
Toast.makeText(this, "Payment CANCELLED " + message, Toast.LENGTH_LONG).show();
}
}
}
I want when this event is triggered, it will make the payment to using the value set in the amount and return status in the onActivityResult above where I can check and give value to the user
First of all make sure you are using the api keys which are for testing and if you are on staging mode(testing) then set this to true .onStagingEnv(true) and test after that.

Add query parameters to link in firebase dynamic link

I create dynamic link and I want to send some specific parameter, like:
"https://mydynamiclink/?link=" + link + "&msgid=" + id + "&apn=myapn".
link field looks like "https://play.google.com/store/apps/details/?id=com.myApp&msgid=myId&apn=myapn"
When I open my app after taping on this link - I receive PendingDynamicLinkData and can get link from it, but not some custom data. (pendingDynamicLinkData.getLink() returns my link without "&msgid=..." - I'm getting string "https://play.google.com/store/apps/details/?id=com.myApp")
How can I add my msgid field and get it after all?
I've found solution
String query = "";
try {
query = URLEncoder.encode(String.format("&%1s=%2s", "msgid", id), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
final String link = "https://play.google.com/store/apps/details/?id=com.myApp" + query;
After such encoding pendingDynamicLinkData.getLink() returns me https://play.google.com/store/apps/details/?id=com.myApp&msgid=myId
Accepted answer didn't work out fine for me, all i needed to do was check if the link was for a user's profile and not a blog post, so i can redirect to my ProfileActivity instead.
private void generateDynamicLink() {
//build link normally and add queries like a normal href link would
String permLink = getLink() + "?route=profile&name=" + getProfileName()
+ "&category=" + getUserPracticeCategory()
+ "&picture=" + getProfilePicture();
FirebaseDynamicLinks.getInstance().createDynamicLink()
.setLink(Uri.parse(permLink))
.setDynamicLinkDomain(Constants.DYNAMIC_LINK_DOMAIN)
.setAndroidParameters(new
DynamicLink.AndroidParameters.Builder().build())
.setSocialMetaTagParameters(
new DynamicLink.SocialMetaTagParameters.Builder()
.setTitle("Enter Title")
.setDescription("Enter Desc here")
.setImageUrl(Uri.parse(getProfilePicture()))
.build())
.buildShortDynamicLink()
.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT,task.getResult().getShortLink());
intent.setType("text/plain");
startActivity(intent);
} else {
Utils.snackBar(tvAddress, "Failed to Generate Profile Link, Try
Again");
}
});
}
and when a user navigates into my app using the generated link, it goes to a post detail activity, because i made that activity the only browsable activity in my manifest. i then have to use the route query to determine if the incoming link is a blog post or a shared user profile.
private void retrieveDynamicLink() {
FirebaseDynamicLinks.getInstance().getDynamicLink(getIntent())
.addOnSuccessListener(this, pendingDynamicLinkData -> {
if (pendingDynamicLinkData == null) {
retrieveLocalIntent();
} else {
Toast.makeText(context, "Resolving Link, Please Wait...", Toast.LENGTH_LONG).show();
if (pendingDynamicLinkData.getLink().getQueryParameter("route") != null) {
if (Objects.requireNonNull(pendingDynamicLinkData.getLink().getQueryParameter("route")).equalsIgnoreCase("profile")) {
try {
Uri uri = pendingDynamicLinkData.getLink();
String permLink = uri.toString().split("\\?")[0];
Intent intent = new Intent(this, ProfileActivity.class);
intent.putExtra(ProfileActivity.PROFILE_NAME, uri.getQueryParameter("name"));
intent.putExtra(ProfileActivity.PROFILE_CATEGORY, uri.getQueryParameter("category"));
intent.putExtra(ProfileActivity.PROFILE_PICTURE, uri.getQueryParameter("picture"));
intent.putExtra(Utils.POST_PERMLINK, permLink);
startActivity(intent);
this.finish();
} catch (NullPointerException e) {
Toast.makeText(context, "Unable to View User Profile", Toast.LENGTH_SHORT).show();
}
}
} else {
postHrefLink = pendingDynamicLinkData.getLink().toString();
getPostDetail.getData(postHrefLink);
}
}
})
.addOnFailureListener(this, e ->
retrieveLocalIntent()
);
}
Hope this helps.
1 First Change your Dynamic Link in firebase console from http://exampleandroid/test to http://exampleandroid/test?data
2. You send the query paramter data with this
DynamicLink dynamicLink = FirebaseDynamicLinks.getInstance().createDynamicLink()
// .setLink(dynamicLinkUri)
.setLink(Uri.parse("http://exampleandroid/test?data=dsads"))
.setDomainUriPrefix("https://App_Name.page.link")
// Open links with this app on Android
.setAndroidParameters(new DynamicLink.AndroidParameters.Builder().build())
// Open links with com.example.ios on iOS
.setIosParameters(new DynamicLink.IosParameters.Builder("com.appinventiv.ios").build())
.buildDynamicLink();
dynamicLinkUri = dynamicLink.getUri();
Let's say that You want to create the following URL:
https://www.myawesomesite.com/turtles/types?type=1&sort=relevance#section-name
For this you can do following
Uri.Builder builder = new Uri.Builder();
builder.scheme("https")
.authority("www.myawesomesite.com")
.appendPath("turtles")
.appendPath("types")
.appendQueryParameter("type", "1")
.appendQueryParameter("sort", "relevance")
.fragment("section-name");
String myUrl = builder.build().toString();

A user is somehow accessing Pro features in the Free version

I have constants set up for my Flavor names:
public static final String FLAVOR_NAME_PRO = "pro";
public static final String FLAVOR_NAME_FREE = "free";
Inside my Activity's onCreate() I assign the boolean mUsingProFlavor a value:
mUsingProFlavor = BuildConfig.FLAVOR.equals(FLAVOR_NAME_PRO);
In a clickListener created later on I have this:
if (mUsingProFlavor) {
customerId = getCustomerId();
Intent intent = new Intent(MainActivity.this, CustomerProfileActivity.class);
intent.putExtra("customerId", customerId);
startActivity(intent);
} else {
showProOnlyFeatureAlertDialog(MainActivity.this, mAlertDialog);
}
This is the only way for the user to access CustomerProfileActivity, and yet somehow I'm getting crash reports indicating that one of my Free users is crashing inside of CustomerProfileActivity.
Any idea how this could happen?
if (mUsingProFlavor) {
customerId = getCustomerId();
Intent intent = new Intent(MainActivity.this, CustomerProfileActivity.class);
intent.putExtra("customerId", customerId);
startActivity(intent);
} else {
showProOnlyFeatureAlertDialog(MainActivity.this, mAlertDialog);
}
Your -> if(mUsingProFlavor) is the issue here.
Since mUsingProFlavor is a String, you have to modify your if-check. Currently it is acting as boolean.
if (mUsingProFlavor.equals("pro")) {
customerId = getCustomerId();
Intent intent = new Intent(MainActivity.this, CustomerProfileActivity.class);
intent.putExtra("customerId", customerId);
startActivity(intent);
} else {
showProOnlyFeatureAlertDialog(MainActivity.this, mAlertDialog);
}

Make call using a specified SIM in DualSim Mobile

I've been searching a lot for this but got no good result .
I am trying to make a call from inside the app using a specified sim
String x is something like this : "OK>message>*111>1> > >"
public void test_call(String x) {
String simSlotName[] = {
"extra_asus_dial_use_dualsim",
"com.android.phone.extra.slot",
"slot",
"simslot",
"sim_slot",
"subscription",
"Subscription",
"phone",
"com.android.phone.DialingMode",
"simSlot",
"slot_id",
"simId",
"simnum",
"phone_type",
"slotId",
"slotIdx"
};
String encodedHash = Uri.encode("#");
String[] data = x.split(">");
if (!data[4].equals("1") && !data[4].equals("0")) {
Log.d("data :", "E:" + data[4]);
G.is_busy = 0;
return;
}
String ussd = data[3] + encodedHash;
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + ussd));
Log.d("Sim",data[4]);
intent.putExtra("com.android.phone.force.slot", true);
for (String s : simSlotName) {
Log.d("S","s :"+s+"="+data[4]);
intent.putExtra(s, data[4]); // 0 for sim1 , 1 for sim2
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,
"Call failed, please try again later.",
Toast.LENGTH_SHORT).show();
return;
}
//this.startActivityForResult(intent,1);
startActivity(intent);
G.needscall = "";
}
this is working fine EXCEPT that it always uses sim 0 even if the default SIM in mobile is SIM 1 ! (Android 5.1.1)
this is just use the default SIM in earlier versions
removing this line
intent.putExtra(s, data[4]);
makes the app use the default sim to dial (5.1.1)
..
.
HELP :(
public void call(String simtoiuse, String code) {
String encodedHash = Uri.encode("#");
String ussd = code + encodedHash; // assuming the USSD code to dail is always sent without the # at the end
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + ussd));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
return; // can put an error message or any thing you want to handle the missing permission
String[] strArr = new String[]{
"extra_asus_dial_use_dualsim",
"com.android.phone.extra.slot",
"slot",
"simslot",
"sim_slot",
"subscription",
"Subscription",
"phone",
"com.android.phone.DialingMode",
"simSlot",
"slot_id",
"simId",
"simnum",
"phone_type",
"slotId",
"slotIdx"
};
intent.putExtra("com.android.phone.force.slot", true);
intent.putExtra("Cdma_Supp", true); // this was missing
for (String putExtra : strArr) intent.putExtra(putExtra, sim);
if (Build.VERSION.SDK_INT >= 23) {
// also this must be added for api 23
Object obj;
List callCapablePhoneAccounts = ((TelecomManager) this.getSystemService(TELECOM_SERVICE)).getCallCapablePhoneAccounts();
String str3 = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
if (callCapablePhoneAccounts != null && callCapablePhoneAccounts.size() > 0) {
try {
obj = callCapablePhoneAccounts.get(sim);
intent.putExtra(str3, (Parcelable) obj);
} catch (Exception e){} // if the device is 1 sim only this may generate an exception
}
}
startActivity(intent);
// these next lines were missing in my code too.
intent.replaceExtras(new Bundle());
intent.setAction(null);
intent.setData(null);
intent.setFlags(0);
}
so :
call("0","*100"); // will use the first sim to dial *100#
call("1","*100") ; // will use the second sim to dial *100#
AND IT WORKS NOW.

Categories

Resources