我正在尝试创建一个类似按钮的聊天头,当有人拨打我的手机时会显示该按钮 我遇到了两个问题:
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
答案 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)如果手动启动,类似聊天头的叠加层是否有效?有异常吗?