无法从广播接收器启动前台服务

时间:2015-01-08 16:41:14

标签: android service broadcastreceiver

我正在尝试创建一个类似按钮的聊天头,当有人拨打我的手机时会显示该按钮 我遇到了两个问题:

1)呼叫接收器只会在用户启动我的应用程序时启动,我知道新的规则和接收器不会启动,直到应用程序运行仍然有办法让它在手机启动时启动吗?

2)它假设在通话时启动的服务不会启动(它在日志中显示方法被调用但服务不是)我想了解为什么以及如何解决它

清单:

<?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>

接收者:

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);  
    }

服务:

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();
    }

并且当然是日志:

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

1 个答案:

答案 0 :(得分:0)

1)您可以设置一个特定的接收器,以便在手机开启时收到通知 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)如果手动启动,类似聊天头的叠加层是否有效?有异常吗?