问题描述
我创建了一个启动浮动气泡的服务,在浮动气泡上,我添加了几个按钮。为了让这些按钮起作用,我在服务活动中创建了一个界面,并使用服务回调将其与我的主要活动绑定。
所以浮动气泡一切正常,但是一旦用户移出应用程序,浮动气泡仍然有效,但它的按钮不起作用,当用户按下浮动气泡应用程序上的任何按钮时,它会在后台崩溃,我尝试调试,发现用户一住app,界面变量就变成null了。
这是我的服务
public class FloatingViewService extends Service {
private WindowManager mWindowManager;
private View mFloatingView;
// Binder given to clients
private final IBinder binder = new LocalBinder();
// Registered callbacks
private ServiceCallbacks serviceCallbacks;
// Class used for the client Binder.
public class LocalBinder extends Binder {
FloatingViewService getService() {
// Return this instance of MyService so clients can call public methods
return FloatingViewService.this;
}
}
public void setCallbacks(ServiceCallbacks callbacks) {
serviceCallbacks = callbacks;
}
public FloatingViewService() {
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
//Inflate the floating view layout we created
mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget,null);
//Add the view to the window.
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,// WindowManager.LayoutParams.TYPE_PHONE,WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);
//Specify the view position
params.gravity = Gravity.TOP | Gravity.LEFT; //Initially view will be added to top-left corner
params.x = 0;
params.y = 100;
//Add the view to the window
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mWindowManager.addView(mFloatingView,params);
//….
//….
//The root element of the collapsed view layout
final View collapsedView = mFloatingView.findViewById(R.id.collapse_view);
//The root element of the expanded view layout
final View expandedView = mFloatingView.findViewById(R.id.expanded_container);
//Set the close button
ImageView closeButtonCollapsed = (ImageView) mFloatingView.findViewById(R.id.close_btn);
closeButtonCollapsed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//close the service and remove the from from the window
stopSelf();
}
});
//Set the view while floating view is expanded.
//Set the start recording button.
ImageView playButton = (ImageView) mFloatingView.findViewById(R.id.startRecording);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Toast.makeText(FloatingViewService.this,"Recording started",Toast.LENGTH_LONG).show();
//serviceCallbacks.onClick(1);
}
});
//stop recording.
ImageView nextButton = (ImageView) mFloatingView.findViewById(R.id.stopRecording);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Toast.makeText(FloatingViewService.this,"recording stoped.",Toast.LENGTH_LONG).show();
serviceCallbacks.onClick(2);
}
});
//Set the close button
ImageView closeButton = (ImageView) mFloatingView.findViewById(R.id.close_button);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
collapsedView.setVisibility(View.VISIBLE);
expandedView.setVisibility(View.GONE);
}
});
//Drag and move floating view using user's touch action.
mFloatingView.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
@Override
public boolean onTouch(View v,MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//remember the initial position.
initialX = params.x;
initialY = params.y;
//get the touch location
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
int Xdiff = (int) (event.getRawX() - initialTouchX);
int Ydiff = (int) (event.getRawY() - initialTouchY);
//The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.
//So that is click event.
if (Xdiff < 10 && Ydiff < 10) {
if (isViewCollapsed()) {
//When user clicks on the image view of the collapsed layout,//visibility of the collapsed layout will be changed to "View.GONE"
//and expanded view will become visible.
collapsedView.setVisibility(View.GONE);
expandedView.setVisibility(View.VISIBLE);
}
}
return true;
case MotionEvent.ACTION_MOVE:
//Calculate the X and Y coordinates of the view.
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
//Update the layout with new X & Y coordinate
mWindowManager.updateViewLayout(mFloatingView,params);
return true;
}
return false;
}
});
}
private boolean isViewCollapsed() {
return mFloatingView == null || mFloatingView.findViewById(R.id.collapse_view).getVisibility() == View.VISIBLE;
}
@Override
public void onDestroy() {
super.onDestroy();
if (mFloatingView != null) mWindowManager.removeView(mFloatingView);
}
public interface ServiceCallbacks {
void onClick(int type);
}
}
这是我的主要活动
public class MainActivity extends AppCompatActivity implements View.OnClickListener,HBRecorderListener,FloatingViewService.ServiceCallbacks {
private HBRecorder recorder;
private static final int PERMISSION_REQ_ID_RECORD_AUDIO = 22;
private static final int PERMISSION_REQ_ID_WRITE_EXTERNAL_STORAGE = PERMISSION_REQ_ID_RECORD_AUDIO + 1;
private static final int CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084;
private boolean hasPermissions = false;
private FloatingViewService myService;
private boolean bound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkFloatingPermission();
recorder = new HBRecorder(this,this);
findViewById(R.id.startR).setOnClickListener(this);
findViewById(R.id.stopR).setOnClickListener(this);
}
private void checkFloatingPermission() {
//Check if the application has draw over other apps permission or not?
//This permission is by default available for API<23. But for API > 23
//you have to ask for the permission in runtime.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
//If the draw over permission is not available open the settings screen
//to grant the permission.
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));
startActivityForResult(intent,CODE_DRAW_OVER_OTHER_APP_PERMISSION);
} else {
Toast.makeText(this,"floting permission already given",Toast.LENGTH_SHORT).show();
initializeView();
}
}
@Override
protected void onStart() {
super.onStart();
// bind to Service
Intent intent = new Intent(this,FloatingViewService.class);
bindService(intent,serviceConnection,Context.BIND_AUTO_CREATE);
}
/**
* Callbacks for service binding,passed to bindService()
*/
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,IBinder service) {
// cast the IBinder and get MyService instance
FloatingViewService.LocalBinder binder = (FloatingViewService.LocalBinder) service;
myService = binder.getService();
bound = true;
myService.setCallbacks(MainActivity.this); // register
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
bound = false;
}
};
@Override
protected void onStop() {
super.onStop();
// Unbind from service
if (bound) {
myService.setCallbacks(null); // unregister
unbindService(serviceConnection);
bound = false;
}
}
private void initializeView() {
startService(new Intent(MainActivity.this,FloatingViewService.class));
}
@Override
public void onClick(View view) {
if (checkSelfPermission(Manifest.permission.RECORD_AUDIO,PERMISSION_REQ_ID_RECORD_AUDIO) && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,PERMISSION_REQ_ID_WRITE_EXTERNAL_STORAGE)) {
hasPermissions = true;
}
if (view.getId() == R.id.startR && hasPermissions) {
startRecordingScreen();
} else if (view.getId() == R.id.stopR && hasPermissions) {
recorder.stopScreenRecording();
}
}
private boolean checkSelfPermission(String permission,int requestCode) {
if (ContextCompat.checkSelfPermission(this,permission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,new String[]{permission},requestCode);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQ_ID_RECORD_AUDIO:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,PERMISSION_REQ_ID_WRITE_EXTERNAL_STORAGE);
} else {
hasPermissions = false;
}
break;
case PERMISSION_REQ_ID_WRITE_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
hasPermissions = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
startRecordingScreen();
}
} else {
hasPermissions = false;
}
break;
default:
break;
}
}
public void startRecordingScreen() {
if (recorder.isBusyRecording()) {
recorder.stopScreenRecording();
}
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
Intent permissionIntent = mediaProjectionManager != null ? mediaProjectionManager.createScreenCaptureIntent() : null;
startActivityForResult(permissionIntent,101);
}
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
//Check if the permission is granted or not.
if (resultCode == RESULT_OK) {
initializeView();
} else { //Permission is not available
Toast.makeText(this,"Draw over other app permission not available. Closing the application",Toast.LENGTH_SHORT).show();
finish();
}
}
if (requestCode == 101) {
if (resultCode == RESULT_OK) {
recorder.startScreenRecording(data,this);
}
}
}
@Override
public void HBRecorderOnStart() {
Toast.makeText(this,"recording start",Toast.LENGTH_SHORT).show();
}
@Override
public void HBRecorderOnComplete() {
Toast.makeText(this,"file saved at: " + recorder.getFilePath(),Toast.LENGTH_LONG).show();
}
@Override
public void HBRecorderOnError(int errorCode,String reason) {
Toast.makeText(this,"recording error",Toast.LENGTH_SHORT).show();
}
@Override
public void onClick(int type) {
Toast.makeText(myService,"workinggggggg",Toast.LENGTH_SHORT).show();
if (type == 1) {
if (checkSelfPermission(Manifest.permission.RECORD_AUDIO,PERMISSION_REQ_ID_WRITE_EXTERNAL_STORAGE)) {
hasPermissions = true;
}
if (hasPermissions) {
startRecordingScreen();
}
} else
recorder.stopScreenRecording();
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)