The below code used to work fine:
Uri skypeUri = Uri.parse("skype:<username injected>?call&video=true");
Intent myIntent = new Intent(Intent.ACTION_VIEW, skypeUri);
this.startActivity(myIntent);
A user would click a button on my app and get re-directed to Skype to place a call with a user:
Recently, this code stopped working. Instead the user still gets redirected to Skype, but when they start the call there's no ringing on their end and the receiver of the 'call' sees this:
Based on Skype docs my code is still correct, but something must have changed. I have ran my app in multiple Android devices and observe the same issue.
Related
I'm making an app in which you can chat and call with other contacts. But in case of calling, I've designed the app in such a way that after typing the number and clicking on the call icon, it takes you to native calls app for calling and updates the call log in my current app.
For this process, this is the code I've written:
if (nativeCall(mobileNumber)) {
Intent intent = new Intent(Intent.ACTION_CALL).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("tel:" + mobileNumber));
if (((BaseActivity) context).isNetworkOk()) {
addToUserCallLogs(context, DateUtils.convertTimestampToDate(), contactUri, "Out", System.currentTimeMillis());
}
context.startActivity(intent);
return true;
}
You can see that I'm putting mobile number into the intent and starting it. And I'm using addToUserCallLogs() function to show it in my app's call logs.
This works fine usually, but in the issue is in the following case.
When the user has multiple calling applications(For eg, the user has installed application named SMARTalk. Now he has native caller app and SMARTalk app to call from), in that case the Android system gives options to chose from like this:
Now, if he choses from one of them, even in that case there is no issue. Say he didn't chose any of those and clicked on the other part of the screen. Then this options bar will be closed. Since all this is happening after starting the intent, this call will be added in the call logs of the app from the function addToUserCallLogs(). But I don't want the call to be shown in the call Logs because I haven't done any call.
But according to the code I've written, before starting the intent, I'm adding into my app's call logs database. Is there a way the information of whether the call has happened or not can be sent back from the system to the app?
Or a way to get these options to be shown manually from the app?
Please comment if you need any more explanation.
I guess no way to receive the callback information because ACTION_CALL does not return a result. You can see the output is nothing from docs even you use startActivityForResult
There 2 apps: First app can open the second one using:
Intent intent = getPackageManager().getLaunchIntentForPackage("com.my.path");
startActivity(intent);
this works fine.
Second app can call again the first app by using intents with actions. for example:
public void call(String number)
{
Intent myIntent = new Intent(Intent.ACTION_CALL);
myIntent.setData(Uri.parse("tel:" + number);
startActivity(myIntent);
}
And there lies a problem which I'll get to shortly.
I'm handling the received intent in the first app in the onCreate method. The first app is simply a single activity with many fragments which are switched with a fragment transaction. When receiving the intent from the second app, I'm making a transaction to a specific fragment according to the intent.
The problem is that when the first app is not in the background (meaning its close), my handling of the intent works fine. However, if the user opened the second app from the first one and the first one is still in the background, then when a user calls the intent in the second app, the first app is getting back to the foreground but to the same fragment the user was when he launched the second app, while I was expecting to show the new fragment which is based on the user's request in the intent sent from the second app.
Why is this happening and how can I fix it?
You could handle this by overriding the OnNewIntent method handling the intent and bringing to top the required fragment.
I have a problem regarding Android task and intent management.
Scenario
User gets a push with a deep-link into the app.
We show a notification putting the URI into the Intent Data.
User clicks the notification and is taken into the app and redirected to some Feature1Activity described by the deep-link.
User looks around, and backs out of the app.
Later, user opens the app from history (long-press home or multitasking button).
Now the same intent that were used from the notification (with the deep-link in the Intent Data) is used to start the app.
Hence, user is taken into the Feature1Activity again.
Problem:
Starting the app from history (long-press home or multitasking button) does not reset the Task (which it does when launching from app icon).
I understand that starting an app from history is not supposed to reset the task since it is intended to be used as "get-right-back-where-you-were". However, in my case this is an issue since the launch of the app from a notification is a one time thing.
Anyone else encountered this problem? Anyone know any solution?
More in-depth
The intent inside the PendingIntent is built like this:
Intent intent = new Intent (Intent.ActionView);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.setData (Uri.Parse (DEEP_LINK_URL));
I found out about the FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET just this day and really thought that it would git rid of my problem but it made no difference.
There are three activities of interest:
SplashActivity (main launcher & listener of the deep-linking schema -- this activity just redirects either to login or OverviewActivity)
OverviewActivity (authorized user's main activity)
Feature1Activity (any feature that the deep-link is pointing to)
What happens when the user clicks the notification is that the SplashActivity acts as a listener for the schema and converts the deep-link url to two intents to start up OverviewActivity and Feature1Activity using Activity.startActivities (Intent[]).
When I look at the intent from the notification inside SplashActivity it always contain the deep-link in the Data.
One work around
There is a work around, setting some booleanExtra field to the notification intent (for instance "ignoreWhenLaunchedFromHistory" = true) and then check in SplashActivity before redirecting
boolean fromHistory = (getIntent().getFlags() & FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY;
if (fromHistory && getIntent().getBooleanExtra ("ignoreWhenLaunchedFromHistory", false))
// Don't follow deep-link even if it exists
else
// Follow deep-link
Except that it hackish and ugly, can you see any problems with this work around?
EDIT: The work around only works when I am responsible for sending the Intent with the deep-link. Since no external source can know about the "ignoreWhenLaunchedFromHistory" extra.
From what I get, maybe using android:excludeFromRecents="true"on your manifest (as a property for the Activity declaration) might ameliorate the issue?
On many Android devices you can get into a secret settings menu from Phone app by typing in
*#*#4636#*#*
http://technology-headlines.com/2010/09/17/4636-android-secret-codes/
There are also some other codes.
Is it also possible to open this stuff programmatically?
I've tried this:
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:*#*#4636#*#*"));
startActivity(intent);
But it just tries to initiate a phone call and of course fails, hangs up and closes the Phone app.
EDIT: The phone *#*#4636#*#* gets saved to my Contact list as "Unknown" but the call just fails. In fact, the secret code only works when you type manually on buttons in Phone app without pressing Call in the end. Is it probably just a hidden feature of Phone app which has nothing to do with calling?
If so, one could open the Phone app programmatically and simulate typing on the buttons.
According to this post
Programmatically press a button in another appplication's activity
this should NOT be possible because if any app on non-rooted phone could just start other apps and press something there, it could take over control of the whole device and do bad things.
Here are some more details but I guess the post is a bit old and even if it worked it may have been changed in current Android versions:
http://mylifewithandroid.blogspot.de/2009/01/generating-keypresses-programmatically.html
So, no easier way to enter secret code?
Is it also possible to open this stuff programmatically?
Yes:
Intent in = new Intent(Intent.ACTION_MAIN);
in.setClassName("com.android.settings", "com.android.settings.TestingSettings");
startActivity(in);
You just need to watch logcat output to learn what this magic combination actually opens:
I/ActivityManager(31362): START {act=android.intent.action.MAIN
flg=0x10000000 cmp=com.android.settings/.TestingSettings} from pid
4257
Secret codes exist and work independent of the dialer application. The dialer application just provides a handy interface for these codes. It recognizes the special string and then calls a special intent to invoke the action. You shouldn't use the dialer to call these dialogs. Instead you can call the secret codes directly yourself like the dialer does internally:
Invoking built in secret codes:
What the dialer really does when you enter the code is extracting the number between *#*# and #*#* and then broadcasting the following intent:
sendBroadcast(new Intent("android.provider.Telephony.SECRET_CODE", Uri.parse("android_secret_code://4636")));
Register your own secret codes (if you like):
You can even register your own secret code actions using:
<action android:name="android.provider.Telephony.SECRET_CODE" />
<data android:scheme="android_secret_code" android:host="4636" />
Source: http://android.amberfog.com/?p=422
Edit: Fixed a bug in the original code (see comment)
try this
String ussdCode = "*" +Uri.encode ("#")+"*"+Uri.encode ("#")+ "4636" + Uri.encode ("#")+"*"+Uri.encode ("#")+"*";
startActivity (new Intent ("android.intent.action.CALL", Uri.parse ("tel:" + ussdCode)));
finally you must encode '#' using Uri.encode()
ACTION_DIAL sends the user to the dialer with the given code (it does not call). So that would be :
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:*#*#4636#*#*"));
startActivity(intent);
It would appear that codes are to be dialed, rather than to be called
looking for this
Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("com.android.settings", "com.android.settings.Settings$TestingSettingsActivity");
startActivity(intent);
There are different activities for different phone, we can jump to the activity through typing in ##4636##.
And use
adb shell dumsys activity activities
to find the realActivity package and name.
e.g: Xiaomi 8
Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("com.android.settings", "com.android.settings.Settings$TestingSettingsActivity");
startActivity(intent);
I'm working on an app and I want to integrate the Last.fm app into it. Basically, when someone is looking at an artist in my app, I would like to have a button that they can tap to open up Last.fm application with the artist's information.
This intent works, but it loads a menu asking which app I would like to use (Browser or Last.fm):
Intent i = new Intent();
i.setData(Uri.parse("http://last.fm/music/" + headliner));
i.setAction("android.intent.action.VIEW");
startActivity(i);
However, I just want to start the Last.fm app and skip the dialog asking which app to use, I thought maybe using the setPackage() method would work like this:
i.setPackage("fm.last.android");
But it causes the app to crash:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=http://last.fm/music/Rihanna pkg=fm.last.android }
Is it possible to just start the Last.fm app? Here's a copy of Last.fm's AndroidManifest.xml for reference.
Thanks for reading,
Tony
Yes, it's possible but you need to know the correct component name. Launch the last.fm app regularly and check the logfile for the cmp=... information that's been used when the app is started. Use this as well in your app then.
I start the Z-DeviceTest app from the market from within my app without a problem like this:
final Intent intentDeviceTest = new Intent("android.intent.action.MAIN");
intentDeviceTest.setComponent(new ComponentName("zausan.zdevicetest","zausan.zdevicetest.zdevicetest"));
startActivity(intentDeviceTest);
in my case the info I took from the logcat was:
// dat=content://applications/applications/zausan.zdevicetest/zausan.zdevicetest.zdevicetest
// cmp=zausan.zdevicetest/.zdevicetest
in order to know how to start the app with the right component/class... do the same for the last.fm app
Edit:
I've tested to launch Last.fm from my own app, and this works fine without any errors:
final Intent intentDeviceTest = new Intent("android.intent.action.MAIN");
intentDeviceTest.setComponent(new ComponentName("fm.last.android","fm.last.android.LastFm"));
startActivity(intentDeviceTest);