I'm doing a handle on android phone numbers, you can know if a call is made, ie confirm that the call was answered. Use the following code to make the call:
Intent callIntent = new Intent (Intent.ACTION_CALL, Uri.parse (number));
startActivity (callIntent);
When you end the call back to my application and that's when I want to know if the call was answered and if it could be the duration of the call.
Yes you can, for this you need create BroadCastReceiver with intent
for example
<receiver android:name=".broadcast.DontMissReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
and then on Receiver
#Override
public void onReceive(final Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(PHONE_ACTION)) {
this.receivePhoneCall(context, intent);
}
}
private void receivePhoneCall(Context context, Intent intent) {
String curState = intent.getExtras().getString("state");
if (curState.equalsIgnoreCase("RINGING")) {
} else
if (curState.equalsIgnoreCase("IDLE") && state.length() > 0) {
if (!state.equalsIgnoreCase("OFFHOOK")) {
}
}
}
Related
I register a receiver using Code A in AndroidManifest.xml.
The Code B will handle something after mobile phone restart.
I think I can move the code if (intent != null && intent.getAction() != null && ACTION.compareToIgnoreCase(intent.getAction()) == 0) just like Code C.
I think that public void onReceive(Context context, Intent intent) will be launched only after mobile phone restart because I have set <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" />
Right?
Code A
<receiver android:name="bll.CleanupBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Code B
public class CleanupBootReceiver extends BroadcastReceiver{
private static final String ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent != null && intent.getAction() != null && ACTION.compareToIgnoreCase(intent.getAction()) == 0) {
//To Do...
}
}
}
Code C
public class CleanupBootReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//To Do...
}
}
I think I can move the code if (intent != null && intent.getAction()
!= null && ACTION.compareToIgnoreCase(intent.getAction()) == 0) just
like Code C.
Yes you can, because you are using your receiver for only one intent-filter action.
But your broadcast receiver can still be triggered using explicit events like
sendBroadcast(new Intent(context, CleanupBootReceiver.class)
so it is good idea to keep with conditional match though I recommend you to use equalsIgnoreCase instead of compareToIgnoreCase
I think that public void onReceive(Context context, Intent intent)
will be launched only after mobile phone restart because I have set
<intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" />
Yes though a must read : Background Execution Limits
I am trying to create an application that could respond when the power button is pressed. To be more specific, which would respond to it when pressed 2 or 3 times.
For now, I tried the following:
public class SMSKey extends BroadcastReceiver{
static int countPowerOff = 0;
private Activity activity = null;
public SMSKey(Activity activity){
this.activity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
countPowerOff++;
}else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
if(countPowerOff == 2){
Intent i = new Intent(activity, SMSOptions.class);
activity.startActivity(i);
}
}
}
}
and in my manifest:
<receiver android:name=".SMSKey">
<intent-filter >
<action android:name="android.intent.action.SCREEN_OFF"/>
<action android:name="android.intent.action.SCREEN_ON"/>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
<action android:name="android.intent.action.ACTION_SHUTDOWN"/>
</intent-filter>
</receiver>
finally in my MainActivty.java:
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
SMSKey mReceiver = new SMSKey(this);
registerReceiver(mReceiver, filter);
Even though this works, it only works for the 1st time, it won't work on the 2nd or 3rd attempt when the power button is pressed. Why is that so ??
And another question: as you can see, I am using this KeyPress event in my MainActivity, which means the application is to be open all the time. Is there any other way that I can implement this without getting into the MainActivity.
This is not even an Android problem. You never reset your countPowerOff variable after you have received the 3 key presses. Even after having done that you must consider adding an alarm that will reset your countPowerOff variable to zero after some small timeout. It will allow you to avoid situations where the user does not intend to interact with your application and just presses the button, but it still gets counted.
As to your second question, try implementing an IntentService.
Here is the solution
public class MyReceiver extends BroadcastReceiver {
private static int countPowerOff = 0;
public MyReceiver (){
}
#Override
public void onReceive(Context context, Intent intent){
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
Log.e("In on receive", "In Method: ACTION_SCREEN_OFF");
countPowerOff++;
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
Log.e("In on receive", "In Method: ACTION_SCREEN_ON");
}
else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
Log.e("In on receive", "In Method: ACTION_USER_PRESENT");
if (countPowerOff >= 2)
{
countPowerOff=0;
Toast.makeText(context, "MAIN ACTIVITY IS BEING CALLED ", Toast.LENGTH_LONG).show();
Intent i = new Intent(context, About.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
}
}
}
}
I am new to android, I have created intent's like this -
<receiver android:name=".IncommigCallListener" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<receiver android:name=".OutgoingCallReciever" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
Now i created a service like this -
<service
android:name=".CallLogger"
android:exported="false"/>
Class CallLogger
public class CallLogger extends IntentService {
public CallLogger(String name) {
super(name);
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent arg0) {
// TODO Auto-generated method stub
System.out.println("service started");
}
}
I don't want to have any activity in my application, i just want to start the service so that it can work in background and receive PHONE_STATE and NEW_OUTGOING_CALL intent.
When i start this application, it doesn't log anything on PHONE_STATE or NEW_OUTGOING_CALL intent.
How can start service in background without using any activity ?
Edit :
public class OutgoingCallReciever extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}
}
and
public class IncommigCallListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
String incommingCallNumber = incomingNumber;
System.out.println("incomming call : " + incomingNumber);
break;
}
}
}
Just start service in your BroadcastReceiver's onReceive method. As you are registering BroadcastReceiver in AndroidManifist, It will always listen for Broadcasts even if application is not running (OS will run it for you).
Example
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, MyService.class);
context.startService(service);
}
}
EDIT
To start a service on Boot completed you can do something like this.
1) Add permission to your Manifist :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2) Register your Broadcast Receiver with BOOT COMPLETE action.
<receiver android:name="com.example.BootBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
3) In BootBroadcastReceiver.java:
public class BootBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent );
}
}
You should be able to do something like this in your receiver.
public class OutgoingCallReciever extends BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Intent service = new Intent(context, CallLogger.class);
context.startService(service);
}
}
You need to create an intent and call startService() on it to "launch" the service.
Also for what it's worth you should get out of the habbit of System.out.println use Log.d(tag,msg) to print debugging information to the logcat. You can switch the d to other letters if you want to print in different channels.
Why nothing gets printed is only due to the problem that System.out.println does not work in Android! Where do you think the background process will "print" this thing?
You need to change that to Log.d(tag, msg) and then check your logcat to see the output! Otherwise I guess your code might be running properly.
I wanted to know how can i launch my android app with some code from Dialpad. Like if you
##3214789650##
from your galaxy it launches angryGps application.
How to implement that?
Thanks.
try this.use Broadcast Receivers to listen outgoing call number:
Manifest.xml
uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<receiver android:name=".OutgoingCallReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
OutgoingCallReceiver.java
public class OutgoingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Bundle bundle = intent.getExtras();
if (null == bundle)
return;
// outgoingNumber=intent.getStringExtra(Intent.ACTION_NEW_OUTGOING_CALL);
String phoneNubmer = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
//START APPLICATION HERE
}
}
What you are looking for is part of contacts application and Although its very likely that the implementation is same for every manufacturer but i am not sure about this.
The intent for starting a new activity is passed by the function handleSecretCode in the file SpecialCharSequenceMgr. The code snippet is
static boolean handleSecretCode(Context context, String input) {
// Secret codes are in the form *#*#<code>#*#*
int len = input.length();
if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
Intent intent = new Intent(Intents.SECRET_CODE_ACTION,
Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
context.sendBroadcast(intent);
What you need to do is to register broadcast receiver for the intent action Intents.SECRET_CODE_ACTION and the uri android_secret_code://"code" and in the broadcast receiver you can launch your application.
Also you can see how some applications are already implementing, One of the code that works on emulator is * #* #4636 #* #*.
I am trying to register a receiver for the removal of the sdcard, but my receiver is not getting called on removal of the sd card pasting my code here. I am registering the receiver in the oncreate() and unregistering in the ondestroy function. Please let me know if i am doing any mistake.
void registerSDCardStateChangeListener() {
final String MEDIA_REMOVED = "android.intent.action.MEDIA_REMOVED";
final String MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
final String MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
// final String MEDIA_EJECT = "android.intent.action.MEDIA_EJECT";
final String MEDIA_EJECT = "android.intent.action.MEDIA_SCANNER_FINISHED";
mSDCardStateChangeListener = new BroadcastReceiver() {
#
Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(MEDIA_REMOVED) || action.equalsIgnoreCase(MEDIA_UNMOUNTED) || action.equalsIgnoreCase(MEDIA_BAD_REMOVAL) || action.equalsIgnoreCase(MEDIA_EJECT)) {
if (mMediaPlayer != null) {
stopPlayBack();
}
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(MEDIA_REMOVED);
filter.addAction(MEDIA_UNMOUNTED);
filter.addAction(MEDIA_BAD_REMOVAL);
filter.addAction(MEDIA_EJECT);
registerReceiver(mSDCardStateChangeListener, filter);
}
Please let me know if anything is wrong in my code.
Try adding this to your intent-filter
filter.addDataScheme("file");
It appears the actions you are trying to catch send the path as the data field of the intent. If that is the case, then your intent filter must have the matching scheme.
Finally, and this is just a suggestion, but I would recommend you use the constants in the Intent class instead of typing out your actions manually. IE, use Intent.ACTION_MEDIA_REMOVED instead of you using the string directly.
Justin Breitfeller's answer worked for me, but as an alternate technique, you can also do this entirely in the AndroidManifest.xml:
<receiver android:enabled="true" android:exported="false"
android:name="SDCardStateChangeListener">
<intent-filter>
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_EJECT" />
<action android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
<data android:scheme="file" />
</intent-filter>
</receiver>
Then make the receiver a proper class:
public class OnMediaMountedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equalsIgnoreCase(Intent.ACTION_MEDIA_REMOVED)
|| action.equalsIgnoreCase(Intent.ACTION_MEDIA_UNMOUNTED)
|| action.equalsIgnoreCase(Intent.ACTION_MEDIA_BAD_REMOVAL)
|| action.equalsIgnoreCase(Intent.ACTION_MEDIA_EJECT)) {
if(mMediaPlayer != null) {
stopPlayBack();
}
}
}
};
I have found solutions while app is running and user unmount/removed sdcard.
#Override
protected void onResume() {
super.onStart();
IntentFilter ejectFilter = new ntentFilter(Intent.ACTION_MEDIA_MOUNTED);
ejectFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
ejectFilter.addAction(Intent.ACTION_MEDIA_EJECT);
ejectFilter.addDataScheme("file");
registerReceiver(ejectReceiver, ejectFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(ejectReceiver);
}
In class, define method like below,
BroadcastReceiver ejectReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_EJECT) || action.equals(Intent.ACTION_MEDIA_UNMOUNTED))
{
Log.e("msg","Media Unmounted");
//do something on unmounted sdcard from device
}
}
};
Hope it will be helpful.