How to Record Android Screen Video programmatically in KitKat 4.4

Good Question But the answer depends on what type of platform you want to use to record the screen in android.

Here are some tricks…..

1) Using this class you can record the screen fort that you required rooted device you can test this in genymotion 4.4 also.

public static class MainFragment extends Fragment {
    private Context mContext;

    private EditText mWidthEditText;
    private EditText mHeightEditText;
    private EditText mBitrateEditText;
    private EditText mTimeEditText;
    private Button mRecordButton;

    public MainFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);

        mContext = getActivity();

        mRecordButton = (Button) rootView.findViewById(R.id.btn_record);
        mRecordButton.setOnClickListener(RecordOnClickListener);

        mWidthEditText = (EditText) rootView.findViewById(R.id.et_width);
        mHeightEditText = (EditText) rootView.findViewById(R.id.et_height);
        mBitrateEditText = (EditText) rootView
                .findViewById(R.id.et_bitrate);
        mBitrateEditText.addTextChangedListener(BitrateTextWatcher);
        mTimeEditText = (EditText) rootView.findViewById(R.id.et_time);
        mTimeEditText.addTextChangedListener(TimeTextWatcher);

        return rootView;
    }

    private TextWatcher BitrateTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i,
                int i2, int i3) {
            // Not used.
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2,
                int i3) {
            if (TextUtils.isEmpty(charSequence)) {
                return;
            }

            int value = Integer.valueOf(charSequence.toString());
            if (value > 50 || value == 0) {
                mBitrateEditText.setError(mContext
                        .getString(R.string.error_bitrate_edittext));
                return;
            }

            mTimeEditText.setError(null);
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // Not used.
        }
    };

    private TextWatcher TimeTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i,
                int i2, int i3) {
            // Not used.
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2,
                int i3) {
            if (TextUtils.isEmpty(charSequence)) {
                return;
            }

            int value = Integer.valueOf(charSequence.toString());
            if (value > 180 || value == 0) {
                mTimeEditText.setError(mContext
                        .getString(R.string.error_time_editext));
                return;
            }
            mTimeEditText.setError(null);
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // Not used.
        }
    };

    private View.OnClickListener RecordOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (!TextUtils.isEmpty(mTimeEditText.getError())
                    || !TextUtils.isEmpty(mBitrateEditText.getError())) {
                Toast.makeText(mContext,
                        mContext.getString(R.string.toast_invalid_values),
                        Toast.LENGTH_LONG).show();
                return;
            }

            boolean widthSet = !TextUtils.isEmpty(mWidthEditText.getText());
            boolean heightSet = !TextUtils.isEmpty(mHeightEditText
                    .getText());
            if ((!widthSet && heightSet) || (widthSet && !heightSet)) {
                Toast.makeText(mContext,
                        mContext.getString(R.string.error_invalid_wxh),
                        Toast.LENGTH_LONG).show();
                return;
            }

            boolean bitrateSet = !TextUtils.isEmpty(mBitrateEditText
                    .getText());
            boolean timeSet = !TextUtils.isEmpty(mTimeEditText.getText());

            StringBuilder stringBuilder = new StringBuilder(
                    "/system/bin/screenrecord");
            if (widthSet) {
                stringBuilder.append(" --size ")
                        .append(mWidthEditText.getText()).append("x")
                        .append(mHeightEditText.getText());
            }
            if (bitrateSet) {
                stringBuilder.append(" --bit-rate ").append(
                        mBitrateEditText.getText());
            }
            if (timeSet) {
                stringBuilder.append(" --time-limit ").append(
                        mTimeEditText.getText());
            }

            // TODO User definable location.
            stringBuilder
                    .append(" ")
                    .append(Environment.getExternalStorageDirectory()
                            .toString()).append("/recording.mp4");
            Log.d("TAG", "comamnd: " + stringBuilder.toString());

            try {
                new SuTask(stringBuilder.toString().getBytes("ASCII"))
                        .execute();

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    };

    private class SuTask extends AsyncTask<Boolean, Void, Boolean> {
        private final byte[] mCommand;

        public SuTask(byte[] command) {
            super();
            this.mCommand = command;
        }

        @Override
        protected Boolean doInBackground(Boolean... booleans) {
            try {
                Process sh = Runtime.getRuntime().exec("su", null, null);
                OutputStream outputStream = sh.getOutputStream();
                outputStream.write(mCommand);
                outputStream.flush();
                outputStream.close();

                final NotificationManager notificationManager = (NotificationManager) mContext
                        .getSystemService(NOTIFICATION_SERVICE);
                notificationManager.notify(RUNNING_NOTIFICATION_ID,
                        createRunningNotification(mContext));

                sh.waitFor();
                return true;

            } catch (InterruptedException e) {
                e.printStackTrace();
                Toast.makeText(mContext,
                        mContext.getString(R.string.error_start_recording),
                        Toast.LENGTH_LONG).show();

            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(mContext,
                        mContext.getString(R.string.error_start_recording),
                        Toast.LENGTH_LONG).show();
            }

            return false;
        }

        @Override
        protected void onPostExecute(Boolean bool) {
            super.onPostExecute(bool);
            if (bool) {
                final NotificationManager notificationManager = (NotificationManager) mContext
                        .getSystemService(NOTIFICATION_SERVICE);
                notificationManager.cancel(RUNNING_NOTIFICATION_ID);

                File file = new File(Environment
                        .getExternalStorageDirectory().toString()
                        + "/recording.mp4");
                notificationManager.notify(FINISHED_NOTIFICATION_ID,
                        createFinishedNotification(mContext, file));
            }
        }

        private Notification createRunningNotification(Context context) {
            Notification.Builder mBuilder = new Notification.Builder(
                    context)
                    .setSmallIcon(android.R.drawable.stat_notify_sdcard)
                    .setContentTitle(
                            context.getResources().getString(
                                    R.string.app_name))
                    .setContentText("Recording Running")
                    .setTicker("Recording Running")
                    .setPriority(Integer.MAX_VALUE).setOngoing(true);

            return mBuilder.build();
        }

        private Notification createFinishedNotification(Context context,
                File file) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(file), "video/mp4");

            PendingIntent pendingIntent = PendingIntent.getActivity(
                    context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            Notification.Builder mBuilder = new Notification.Builder(
                    context)
                    .setSmallIcon(android.R.drawable.stat_notify_sdcard)
                    .setContentTitle(
                            context.getResources().getString(
                                    R.string.app_name))
                    .setContentText("Recording Finished")
                    .setTicker("Recording Finished")
                    .setContentIntent(pendingIntent).setOngoing(false)
                    .setAutoCancel(true);

            return mBuilder.build();
        }
    }
}

2) You can capture the screen shots and make the video from it and it will work for the 3.0+ devices And for converting the images to video you can use FFMPEG or JavaCV.

For Rooted devices(in that you can capture the keyboard screen also)

if (Environment.MEDIA_MOUNTED.equals(Environment
            .getExternalStorageState())) {

        // we check if external storage is\ available, otherwise
        // display an error message to the user using Toast Message
        File sdCard = Environment.getExternalStorageDirectory();
        File directory = new File(sdCard.getAbsolutePath() + "/ScreenShots");
        directory.mkdirs();

        String filename = "screenshot_jpeg_" + i + ".png";
        File yourFile = new File(directory, filename);



        try {
            Process sh = Runtime.getRuntime().exec("su", null, null);
            OutputStream os = sh.getOutputStream();
            os.write(("/system/bin/screencap -p " + "/sdcard/ScreenShots/" + filename).getBytes("ASCII"));


            os.flush();
            os.close();
            sh.waitFor();
            i++;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

For without Rooted devices(in that you can not capture the keyboard screen)

if (Environment.MEDIA_MOUNTED.equals(Environment
            .getExternalStorageState())) {

        // we check if external storage is\ available, otherwise
        // display an error message to the user using Toast Message
        File sdCard = Environment.getExternalStorageDirectory();
        File directory = new File(sdCard.getAbsolutePath() + "/ScreenShots");
        directory.mkdirs();

        String filename = "screenshot_jpeg_" + i + ".png";
        File yourFile = new File(directory, filename);



        try {
            Process sh = Runtime.getRuntime().exec("su", null, null);
            OutputStream os = sh.getOutputStream();
            os.write(("/system/bin/screencap -p " + "/sdcard/ScreenShots/" + filename).getBytes("ASCII"));


            os.flush();
            os.close();
            sh.waitFor();
            i++;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Leave a Comment