Search code examples
androidandroid-softkeyboard

How to fix 'Android Soft Keyboard not returning KeyCode'


i'm fairly new to Android and i am trying to create an app that outputs the key code of a soft keyboard input (the android keyboard on screen, NOT a physical keyboard) to a text file from an edit text field.

So the user will type in text into an edit text such as "hello World" and i want to output the key code for each of those to a text file.

I will eventually get the Keyup system time and the keydown system time but that's a later me problem!

I've tried various different methods such as writing my own soft keyboard and using that, as well as using a switch statement for each character. The following code is my main activity:

package com.example.useridentificationapp;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Parcelable;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class MainActivity extends AppCompatActivity{

    EditText et_name, et_content;
    Button b_save;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
        }
        et_name = (EditText) findViewById(R.id.et_name);
        et_content = (EditText) findViewById(R.id.et_content);
        final TextView view = (TextView) findViewById(R.id.view);
        final EditText log  = (EditText) findViewById(R.id.log);
        b_save = (Button) findViewById(R.id.b_save);


        et_content.setOnKeyListener(new View.OnKeyListener(){
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                String keyCodeStr = KeyEvent.keyCodeToString(keyCode);
                view.setText(String.valueOf(keyCodeStr));
                log.setText(keyCodeStr + " " + log.getText());
                return true;
            }
        });


        b_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              String filename = et_name.getText().toString();
              String content = et_content.getText().toString();

              saveTextAsFile(filename, content);
            }
        });
    }

    private void saveTextAsFile (String filename, String content){
        String fileName = filename + ".txt";

        //create file
        File file = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), fileName);

        //write to file
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(content.getBytes());
            fos.close();
            Toast.makeText(this, "Saved", Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e){
            e.printStackTrace();
            Toast.makeText(this, "File not found", Toast.LENGTH_SHORT).show();
        } catch (IOException e){
            e.printStackTrace();
            Toast.makeText(this, "Error saving", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1000:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
                } else{
                    Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_SHORT).show();
                    finish();
                }
        }
    }

}

The code above only returns "KEYCODE_ENTER", "KEYCODE_BACK", "KEYCODE_SHIFT" and "KEYCODE_DELETE". This is fine but i want it to return that for each key press so for example if the user pressed A on the keyboard, i would like it to output "KEYCODE_A". I do not get anything in the "log" (a field i created to display the Keycode for debugging), for any other key, it just stays empty, however the key does type into the field.

I would then like to save this in a text file.

Any help would be greatly appreciated! I've read loads of android documentation on KeyEvent and associated methods but i can't seem to get anything working!

Thank you very much in advance for your help! I have spent a good few days (and many hours scouring the internet for help but to no avail!)


Solution

  • Just to answer this, it cannot actually be done due to the way that Android handles soft keyboard inputs.

    To resolve the issue i had to recreate a keyboard layout of buttons on the screen which then worked.