diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a31fb82..c2f1274 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + + diff --git a/app/src/main/java/net/yrom/screenrecorder/MainActivity.java b/app/src/main/java/net/yrom/screenrecorder/MainActivity.java index 3b24e82..b068ab9 100644 --- a/app/src/main/java/net/yrom/screenrecorder/MainActivity.java +++ b/app/src/main/java/net/yrom/screenrecorder/MainActivity.java @@ -46,6 +46,7 @@ import android.widget.Toast; import android.widget.ToggleButton; +import net.yrom.screenrecorder.floatball.FloatHelper; import net.yrom.screenrecorder.view.NamedSpinner; import java.io.File; @@ -96,6 +97,10 @@ public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + FloatHelper.init(this); + IntentFilter filter = new IntentFilter(ACTION_STOP); + filter.addAction(ACTION_START); + registerReceiver(mStopActionReceiver, filter); mMediaProjectionManager = (MediaProjectionManager) getApplicationContext().getSystemService(MEDIA_PROJECTION_SERVICE); mNotifications = new Notifications(getApplicationContext()); bindViews(); @@ -267,8 +272,14 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in @Override protected void onDestroy() { super.onDestroy(); + try { + unregisterReceiver(mStopActionReceiver); + } catch (Exception e) { + //ignored + } saveSelections(); stopRecorder(); + FloatHelper.clear(this); } private void startCaptureIntent() { @@ -307,19 +318,15 @@ private void bindViews() { mVideoCodec.setOnItemSelectedListener((view, position) -> onVideoCodecSelected(view.getSelectedItem())); mAudioCodec.setOnItemSelectedListener((view, position) -> onAudioCodecSelected(view.getSelectedItem())); mVieoResolution.setOnItemSelectedListener((view, position) -> { - if (position == 0) return; onResolutionChanged(position, view.getSelectedItem()); }); mVideoFramerate.setOnItemSelectedListener((view, position) -> { - if (position == 0) return; onFramerateChanged(position, view.getSelectedItem()); }); mVideoBitrate.setOnItemSelectedListener((view, position) -> { - if (position == 0) return; onBitrateChanged(position, view.getSelectedItem()); }); mOrientation.setOnItemSelectedListener((view, position) -> { - if (position == 0) return; onOrientationChanged(position, view.getSelectedItem()); }); } @@ -340,7 +347,6 @@ private void startRecorder() { if (mRecorder == null) return; mRecorder.start(); mButton.setText("Stop Recorder"); - registerReceiver(mStopActionReceiver, new IntentFilter(ACTION_STOP)); moveTaskToBack(true); } @@ -351,11 +357,6 @@ private void stopRecorder() { } mRecorder = null; mButton.setText("Restart recorder"); - try { - unregisterReceiver(mStopActionReceiver); - } catch (Exception e) { - //ignored - } } private void cancelRecorder() { @@ -461,7 +462,7 @@ private void onOrientationChanged(int selectedPosition, String orientation) { int current = getResources().getConfiguration().orientation; if (isLandscape && current == Configuration.ORIENTATION_PORTRAIT) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } else if (!isLandscape && current == Configuration.ORIENTATION_PORTRAIT) { + } else if (!isLandscape && current == Configuration.ORIENTATION_LANDSCAPE) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } @@ -830,23 +831,28 @@ private void restoreSelectionFromPreferences(SharedPreferences preferences, Name } } - static final String ACTION_STOP = "net.yrom.screenrecorder.action.STOP"; + public static final String ACTION_STOP = "net.yrom.screenrecorder.action.STOP"; + public static final String ACTION_START = "net.yrom.screenrecorder.action.START"; private BroadcastReceiver mStopActionReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - File file = new File(mRecorder.getSavedPath()); - if (ACTION_STOP.equals(intent.getAction())) { - stopRecorder(); - } - Toast.makeText(context, "Recorder stopped!\n Saved file " + file, Toast.LENGTH_LONG).show(); - StrictMode.VmPolicy vmPolicy = StrictMode.getVmPolicy(); - try { - // disable detecting FileUriExposure on public file - StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().build()); - viewResult(file); - } finally { - StrictMode.setVmPolicy(vmPolicy); + if (ACTION_START.equals(intent.getAction())) { + onButtonClick(null); + }else { + File file = new File(mRecorder.getSavedPath()); + if (ACTION_STOP.equals(intent.getAction())) { + stopRecorder(); + } + Toast.makeText(context, "Recorder stopped!\n Saved file " + file, Toast.LENGTH_LONG).show(); + StrictMode.VmPolicy vmPolicy = StrictMode.getVmPolicy(); + try { + // disable detecting FileUriExposure on public file + StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().build()); + viewResult(file); + } finally { + StrictMode.setVmPolicy(vmPolicy); + } } } diff --git a/app/src/main/java/net/yrom/screenrecorder/Utils.java b/app/src/main/java/net/yrom/screenrecorder/Utils.java index dcac5a0..3887eed 100644 --- a/app/src/main/java/net/yrom/screenrecorder/Utils.java +++ b/app/src/main/java/net/yrom/screenrecorder/Utils.java @@ -16,6 +16,7 @@ package net.yrom.screenrecorder; +import android.content.Context; import android.media.MediaCodecInfo; import android.media.MediaCodecList; import android.os.AsyncTask; @@ -26,7 +27,7 @@ import java.util.ArrayList; import java.util.List; -class Utils { +public class Utils { interface Callback { @@ -243,4 +244,14 @@ private static void initColorFormatFields() { } } + + public static int getStatusBarHeight(Context context) { + int result = 0; + int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = context.getResources().getDimensionPixelSize(resourceId); + } + return result; + } + } diff --git a/app/src/main/java/net/yrom/screenrecorder/floatball/FloatBall.java b/app/src/main/java/net/yrom/screenrecorder/floatball/FloatBall.java new file mode 100644 index 0000000..87b629c --- /dev/null +++ b/app/src/main/java/net/yrom/screenrecorder/floatball/FloatBall.java @@ -0,0 +1,77 @@ +package net.yrom.screenrecorder.floatball; + +import android.content.Context; +import android.content.Intent; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; +import android.widget.FrameLayout; + +import net.yrom.screenrecorder.MainActivity; +import net.yrom.screenrecorder.R; +import net.yrom.screenrecorder.Utils; + +/** + * Created by chao on 18-2-2. + */ + +public class FloatBall extends FrameLayout{ + + private int mStatusHeight; + + private boolean mIsBig = true; + + public FloatBall(Context context) { + super(context); + mStatusHeight = Utils.getStatusBarHeight(context); + inflate(context, R.layout.layout_float_ball, this); + final View ivBig = findViewById(R.id.iv_big); + final View ivSmall = findViewById(R.id.iv_small); + setOnClickListener(view -> { + mIsBig = !mIsBig; + ivBig.setVisibility(mIsBig ? VISIBLE : GONE); + ivSmall.setVisibility(!mIsBig ? VISIBLE : GONE); + if(mIsBig){ + context.sendBroadcast(new Intent(MainActivity.ACTION_STOP)); + }else{ + context.sendBroadcast(new Intent(MainActivity.ACTION_START)); + } + }); + } + + float mInnerY, mRawY; + + long time; + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mInnerY = event.getY(); + mRawY = event.getRawY(); + time = System.currentTimeMillis(); + break; + case MotionEvent.ACTION_MOVE: + float y = event.getRawY(); + moveTo(y - mInnerY - mStatusHeight); + break; + case MotionEvent.ACTION_UP: + long delay = System.currentTimeMillis() - time; + int move = (int) Math.abs(event.getRawY() - mRawY); + if(move < 10) { + if (delay < 300){ + performClick(); + } + } + break; + } + return true; + } + + private void moveTo(float y){ + WindowManager.LayoutParams params = (WindowManager.LayoutParams) getLayoutParams(); + params.y = (int) y; + ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).updateViewLayout(this, params); + } + +} diff --git a/app/src/main/java/net/yrom/screenrecorder/floatball/FloatHelper.java b/app/src/main/java/net/yrom/screenrecorder/floatball/FloatHelper.java new file mode 100644 index 0000000..d480433 --- /dev/null +++ b/app/src/main/java/net/yrom/screenrecorder/floatball/FloatHelper.java @@ -0,0 +1,53 @@ +package net.yrom.screenrecorder.floatball; + +import android.content.Context; +import android.content.Intent; +import android.graphics.PixelFormat; +import android.os.Build; +import android.provider.Settings; +import android.view.Gravity; +import android.view.WindowManager; + +/** + * Created by chao on 18-2-2. + */ + +public class FloatHelper { + + private static FloatBall floatBall; + + public static void init(Context context){ + if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)) { + Intent intent = new Intent(context, RequestOverlayActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } else { + addToWindow(context); + } + } + + public static void addToWindow(Context context){ + floatBall = new FloatBall(context); + WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + WindowManager.LayoutParams params = new WindowManager.LayoutParams(); + params.type = WindowManager.LayoutParams.TYPE_PHONE; + params.format = PixelFormat.RGBA_8888; + params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + params.width = WindowManager.LayoutParams.WRAP_CONTENT; + params.height = WindowManager.LayoutParams.WRAP_CONTENT; + params.gravity = Gravity.END | Gravity.TOP; + params.x = 0; + params.y = context.getResources().getDisplayMetrics().heightPixels / 2; + if (windowManager != null) { + windowManager.addView(floatBall, params); + } + } + + public static void clear(Context context){ + WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + if (windowManager != null && floatBall != null) { + windowManager.removeView(floatBall); + floatBall = null; + } + } +} diff --git a/app/src/main/java/net/yrom/screenrecorder/floatball/RequestOverlayActivity.java b/app/src/main/java/net/yrom/screenrecorder/floatball/RequestOverlayActivity.java new file mode 100644 index 0000000..f93844d --- /dev/null +++ b/app/src/main/java/net/yrom/screenrecorder/floatball/RequestOverlayActivity.java @@ -0,0 +1,34 @@ +package net.yrom.screenrecorder.floatball; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.provider.Settings; +import android.widget.Toast; + +/** + * request overlay window permission + */ +public class RequestOverlayActivity extends Activity { + + @SuppressLint("NewApi") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); + startActivityForResult(intent, 0); + } + + @SuppressLint("NewApi") + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == 0 && Settings.canDrawOverlays(this)) { + FloatHelper.addToWindow(this); + }else{ + Toast.makeText(getApplicationContext(), "window permission denied, cannot show activity task", Toast.LENGTH_SHORT).show(); + } + finish(); + } +} diff --git a/app/src/main/res/drawable/bg_float_ball.xml b/app/src/main/res/drawable/bg_float_ball.xml new file mode 100644 index 0000000..26b698f --- /dev/null +++ b/app/src/main/res/drawable/bg_float_ball.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_float_ball.xml b/app/src/main/res/layout/layout_float_ball.xml new file mode 100644 index 0000000..e6e46a9 --- /dev/null +++ b/app/src/main/res/layout/layout_float_ball.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file