I'm trying to implement my own phone call handling UI.
What I want to do is, if a call comes in, the incoming telephone number and a picture are displayed, and, if I press a button, the incoming call will be accepted/answered.
The related code is:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
answerButton = (Button) findViewById(R.id.pickup);
answerButton.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
Intent intent = new Intent("android.intent.action.ANSWER");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
Sadly, the code does not work. At first, an exception is thrown if I press my answer button:
ActivityNotFoundException: No Activity found to handle Intent {
act=android.intent.action.ANSWER
Then I added an entry in the AndroidManifest.xml:
<uses-permission android:name="android.permission.CALL_PHONE" />
I run the app again, there is no exception anymore. However, I doubt the incoming call is not really accepted. Because if the press the Android's screen answer button (green button), the incoming call is accepted and a green in call icon is also displayed on the upper left corner of the emulator screen, while my app doesn't.
I also read the Phone app's source code in android source. There is method such as acceptCall() in the Phone class. But these codes seem difficult for me to use, because there are many imports declaration in the code, such as :
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CallerInfo;
import com.android.internal.telephony.CallerInfoAsyncQuery;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.Phone;
And, if I add these imports in my code, there will be too many errors, such as :
The import com.android.internal.telephony cannot be resolved.
What is the right and simple way for my problem?
Add the category "android.intent.category.DEFAULT" (Intent.CATEGORY_DEFAULT)
The intent android.intent.action.ANSWER is somehow not working as expected. There is a workaround by emulating the bluetooth button to answer the incoming call. You can see an example from auto-answer project.
You need to create a broadcast receiver in which you will get the event when your phone is ringing and after that you can launch your desired activity.You can not replace the default incoming call screen until using CUSTOM ROM.
And do not forget to set the priority in broadcast receiver in manifest file.
Once you get the event you can use the object of ITelephony by using reflection.And that can provide you methods to answering or rejecting the call.
This is possible using the com.android.internal.telephony package, but you have to find someway for using this methods in eclipse and your app has to be compiled as a system app using the android source code.
Change your accept call method by this:
public static void acceptCall(Context context)
{
Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
buttonUp.putExtra(Intent.EXTRA_KEY_EVENT,
new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
}
Related
I have put in place the following:
I added <receiver android:name="BootReceiver"></receiver> to application in the manifest XML file.
I added <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> to the manifest also.
I created a new class in the droid project called BootReceiver:
using Android.App;
using Android.Content;
using uarapp.droid;
[BroadcastReceiver(Enabled = true, DirectBootAware = true, Exported = true)]
[IntentFilter(new[] { Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.HighPriority)]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Intent i = new Intent(context, typeof(MainActivity));
i.AddFlags(ActivityFlags.NewTask);
context.StartActivity(i);
}
}
The app does not start when the device boots. From Googling it looks like this process has changed for latest version of Android. Anybody know what needs to change? I can't find it online anywhere.
In case it matters the specific device I'm targetting is a RealWear HMT-1.
A lot has changed with Android 10 there are a lot of restrictions on starting something in the background more information here.
The possible solution is in the following answer on SO: https://stackoverflow.com/a/59421118/7462031
Possible Solutions:
1- You can choose just show a service notification, and start pending intent with a click
2- You can use full-screen intents to show your intent immediately as shown in the other answer and suggested by Google.
For full-screen intent solution, as described in the official document
The system UI may choose to display a heads-up notification, instead of launching this intent, while the user is using the device.
3- To start the activity automatically in the background, The most possible solution in my view is adding "SYSTEM_ALERT_WINDOW" to the manifest file. And ask for user permission once when the app opened the first time. (The user can give this permission manually - (Settings-Apps-Your App-Advanced- Draw over other apps))
I have also read about some brands restricting the above solutions so you might wanna investigate that too.
Good luck feel free to get back if you have queries.
I am new to android app development, but I have good knowledge of programming in JAVA and in general. I am trying to write an app for android which can enqueue music files to default music player in android (like Google Play Music). My app decides which song to play when, but I don't want to write a full-blown music player app. I just want to feed the existing player app with new music.
I am looking for something like "inter-app" communication (perhaps using Intent?) through which I can feed content to the music player and probably control the player itself.
I am not sure if such facility exist in android, so other alternative suggestions are also welcome. Also, please let me know if I didn't explain the problem properly.
Intents are a very powerful feature of Android to which there isn't any direct analog in Java. What you want to use is a mechanism known as an implicit Intent. Normally, when you launch one activity from another, you create an Intent and specify which activity to start. With an implicit Intent, you provide an action (Intent.ACTION_VIEW) and data (a URI pointing to a music file). Using an implicit Intent, you have a piece of data handled without knowing in advance which Activity will do the handling.
When you pass your Intent to startActivity(), the OS will attempt to resolve the data in the best way possible, typically popping up a list of apps that can possibly handle your data. The user selects the appropriate app and that app handles the Intent, playing your music file. Any app that registers as a service capable of potentially handling your data will show up in the list. After passing the Intent, your activity will go into the background, and the app handling the intent will come to the foreground.
Once the user has selected an app to handle the Intent from your Activity, that app will always be used to handle that kind of Intent by your Activity until you delete your own app's data.
Take a look at the official doc to get yourself started and then ask a new question when you have a more specific problem you're trying to address.
Here's a code sample that demonstrates a very simple implicit Intent example, by which a URL is opened without knowing which browser will open it:
package com.marsatomic.intentimplicitdemo;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity
{
public final static Uri URI = Uri.parse("http://www.marsatomic.com");
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonConnect = (Button)findViewById(R.id.button_connect);
buttonConnect.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(Intent.ACTION_VIEW, URI);
startActivity(i);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I'm making a SIP application, and I've got pretty much everything working that i want to except one thing. I cant get the activity to launch when a SIP call occurs.
I'm working with a SIP library that starts a 'phone' service which deals with the handling of incoming calls etc, and when i create an instance of the 'phone' I then register listeners which detail what i want to happen. So to handle incoming calls i register an 'OnIncommingCall' listener.
If the app isn't currently open at the time i want it to launch the app. so my listener is:
thisPhone.setIncomingCallListener(new OnIncomingCallListener()
{
public void OnIncomingCall(String remoteContact, int accountId)
{
if(MainActivity.this.getIsOpen())
{
MainActivity.this.setIsCallIncomming(true);
MainActivity.this.setCurrentCaller(remoteContact);
MainActivity.this.setMainUIEles();
}
else
{
Intent i = new Intent(getApplicationContext(), MainActivity.class);
i.putExtra("isCallIncomming", true);
i.putExtra("currentCaller", remoteContact);
i.putExtra("isRegistered", true);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
}); //incoming call listener
However when the call comes, it rings but the app wont open, but if i open the app from the launcher whilst the call is still ringing then it will open and know the call is there.
Is the problem because I'm trying to start the Activity which defined the listener?
I've tried all sorts of flags and combinations (SINGLE_TOP etc) can i can't get it to work.
Any help would be appreciated!
DJOodlen
Well this was a silly mistake on my part.
After putting in some toasts so I could see where in the code each bit was going I realised that getIsOpen() never returned false. That's because it wasn't being called on the onPause() method as wells as the onDestroy() method...
Ooops!
Iam new to android. I could understand the concept of Broadcast Receivers, but i couldn't understand the concept of sendBroadcast(Intent i).. My main doubt is who will listen to this sendBroadcast.
public class OOVOOActivity extends Activity {
/** Called when the activity is first created. */
public static int count = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
addShortcut();
}
private void addShortcut(){
Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
// Shortcut name
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name));
shortcut.putExtra("duplicate", false); // Just create once
// Setup current activity shoud be shortcut object
ComponentName comp = new ComponentName(this.getPackageName(), "."+this.getLocalClassName());
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_MAIN).setComponent(comp));
// Set shortcut icon
ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(this, R.drawable.search);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
sendBroadcast(shortcut);
}
I have few questions to ask,
In the above code there is no toast message is used, But if i
run the app i could see the toast msg.. Plz explain how it is coming
and also tell me how to hide those toast msg.
U could see sendBroadcast(shortcut); , basically who will listen to this broadcast.
Plz clear my doubt. Thank U
U could see sendBroadcast(shortcut); , basically who will listen to this broadcast.
Some other app or apps. No app might receive this broadcast. 999 apps might receive this broadcast. That is up to the user and the developers of those other apps.
In this case, you are assuming that there are one or more apps on the device that will respond to a com.android.launcher.action.INSTALL_SHORTCUT broadcast. Please note the com.android. This means that this Intent action is not part of the Android SDK. com.android is used for pieces of the Android environment. As it turns out, this Intent action is not documented, meaning that it may or may not work on all devices and Android OS versions.
Plz explain how it is coming
Other developers, besides you, can write code that displays Toast messages. They can even write code that displays Toast messages in response to a broadcast Intent. It turns out that your test environment contains such code, possibly in the com.android.launcher application.
also tell me how to hide those toast msg
You don't.
We have a live video streaming app with a lot going on. A user presses the home button. I want the app to be removed from memory. When the app is selected again we have a brand new load. There are a lot of processes going on and we don't want to have to manually manage all the connections, streams, etc. This is how our iPhone version of the app works.
I've read this: Is quitting an application frowned upon?
I don't really care about Androids design patterns here either way. However if someone has an elegant, simple way that all my activities will be removed from the stack when the home button is pressed, and then when the app is reloaded it starts with a fresh main activity, that would be great. Also, I can't seem to ever debug when the home key is pressed in onKeyDown. Its simply not registering. (keyCode == KeyEvent.KEYCODE_HOME) is my check. It picks up back buttons, etc.
Any thoughts?
You can call system.exit(0); but I would still suggest to follow the Android guidelines, and clean everything (as should be) on onPause() or similar method.
Could you just override the onPause method and use the finish() function?
int p = android.os.Process.myPid();
android.os.Process.killProcess(p);
you can do than on button click. Define any static method like exit() and define
android.os.Process.killProcess(android.os.Process.myPid()); in exit method
in the main or first activity.
Then call this method on button click.
If you want to clear all of your activities from the stack, you can broadcast an intent from the activity which initiates the quit like this:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("CLEAR_STACK");
sendBroadcast(broadcastIntent);
And in every one of your activities that you want to be cleared off the stack you can create a BroadcastReceiver with an inner class:
class ActivitiesBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
}
And register your BroadcastReceiver in the onCreate() method:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("CLEAR_STACK");
BroadcastReceiver r;
r = new ActivitiesBroadcastReceiver();
registerReceiver(r, intentFilter);