Unable to start foreground operation from broadcast receiver
I am trying to create a chat head like a button that will appear when someone calls my phone I am facing two problems:
1) the call receiver will only start when the user starts my application, I understand that the new rule and receivers will not start until the application is started, is there a way to start it when the phone starts up?
2) the service that is supposed to start when called does not start (it shows in the log that the method is being called, but the service isnt) I would like to understand why and how to fix it
manifesto:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="********"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:name="MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_app_logo"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="*******.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- handle incoming calls -->
<receiver
android:name="*********.CallReciever">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<service android:name="*****.FloatingButtonService" />
</application>
</manifest>
recipient:
public void onReceive(Context context, Intent intent)
{
Log.i("GABI", "CallReciever onRecieve()");
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
Log.v("GABI", "state is:"+state);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING))
{
String num = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.v("GABI", "phone ringing, num:"+num);
Log.v("GABI", "adding floating button");
addAppButtonToCallScreen(context);//add out application to the main call screen
}
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE))//call ended or hanged up
{
//remove our button from screen
removeAppButtonFromCallScreen();
}
}
/**
* add our application to the main call screen
* @param context
*/
private void addAppButtonToCallScreen(Context context)
{
Log.i("GABI","addAppButtonToCallScreen()");
Intent intent = new Intent(context, FloatingButtonService.class);
context.startService(intent);
}
service:
public class FloatingButtonService extends Service
{
private WindowManager _windowManager;
private ImageView _floatingButton;
private boolean _isMove;
@Override
public void onCreate()
{
Log.i("GABI", "FloatingButtonService.OnCreate()");
super.onCreate();
_floatingButton = new ImageView(this); //the logo bubble as imageView
_floatingButton.setImageResource(R.drawable.ic_call);
_windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//set the layout params
final LayoutParams myParams = new WindowManager.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
myParams.gravity = Gravity.TOP | Gravity.LEFT;
myParams.x=0;
myParams.y=100;
// add a floatingButton icon in window
Log.v("GABI", "adding the view");
_windowManager.addView(_floatingButton, myParams);
try{
//for moving the picture on touch and slide
_floatingButton.setOnTouchListener(new View.OnTouchListener() {
WindowManager.LayoutParams paramsT = myParams;
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
private long touchStartTime = 0;
@Override
public boolean onTouch(View v, MotionEvent event)
{
Log.i("GABI", "floating button touch event");
//remove button bubble on long press
if(System.currentTimeMillis()-touchStartTime>ViewConfiguration.getLongPressTimeout() && initialTouchX== event.getX())
{
_windowManager.removeView(_floatingButton);
stopSelf();
return false;
}
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
touchStartTime = System.currentTimeMillis();
initialX = myParams.x;
initialY = myParams.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
if (_isMove==false)
{
startApp();//start our application
}
break;
case MotionEvent.ACTION_MOVE:
myParams.x = initialX + (int) (event.getRawX() - initialTouchX);
myParams.y = initialY + (int) (event.getRawY() - initialTouchY);
_windowManager.updateViewLayout(v, myParams);
_isMove=true;
break;
}
return false;
}
});
} catch (Exception e){
e.printStackTrace();
}
}
/**
* show toast */
private void startApp()
{
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "pressed button weeeeeeeeee", Toast.LENGTH_LONG).show();
}
and of course the log:
01-08 18:03:56.745: I/GABI(10149): CallReciever onRecieve()
01-08 18:03:56.745: V/GABI(10149): state is:RINGING
01-08 18:03:56.745: V/GABI(10149): phone ringing, num:0549968089
01-08 18:03:56.745: V/GABI(10149): adding floating button
01-08 18:03:56.745: I/GABI(10149): addAppButtonToCallScreen()
01-08 18:04:04.645: I/GABI(10149): CallReciever onRecieve()
01-08 18:04:04.645: V/GABI(10149): state is:IDLE
01-08 18:11:45.765: I/GABI(10543): CallReciever onRecieve()
01-08 18:11:45.765: V/GABI(10543): state is:RINGING
01-08 18:11:45.765: V/GABI(10543): phone ringing, num:0549968089
01-08 18:11:45.765: V/GABI(10543): adding floating button
01-08 18:11:45.765: I/GABI(10543): addAppButtonToCallScreen()
01-08 18:11:57.950: I/GABI(10543): CallReciever onRecieve()
01-08 18:11:57.950: V/GABI(10543): state is:OFFHOOK
01-08 18:12:11.275: I/GABI(10543): CallReciever onRecieve()
01-08 18:12:11.275: V/GABI(10543): state is:IDLE
source to share
1) You can set a specific receiver to be notified when the phone turns on by catching the action android.intent.action.BOOT_COMPLETED
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name="com.my.CustomReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
2) Does the inscription on the voice clock work if it is started manually? Any exception?
source to share