Passing data between 2 classes returns null

2020-03-31 07:33发布

问题:

Sorry I am new in Android Developing and now I have this simple problem for my final project and I tried everything I've learnt from stackoverflow but didn't work. My project is a simple Client/Server Encrypted message application. I found sample codes and made the classes, the classes are working properly but can't work together :( Class 1 (EncryptActivity) Encrypts data from its own input using RSA. Class 2 (MyActivity) makes a TCP connection with a server to send a plain text.

BUT when I want to send plain text from MyActivity to EncryptActivity and get encrypted text, I always get "null".

The ways I tried to pass data are in code with comment "//"

Please help me :((

EncryptActivity:

public class EncryptActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    try {
        generateKey();
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    super.onCreate(savedInstanceState);
    setContentView(R.layout.encryptinput);

    final Button enButton = (Button) findViewById(R.id.bEncrypt);
    final Button deButton = (Button) findViewById(R.id.bDecrypt);
    final EditText input = (EditText) findViewById(R.id.etPlainText);
    final EditText Raw = (EditText) findViewById(R.id.etEncryptedText);
    final EditText output = (EditText) findViewById(R.id.etDecryptedText);

    enButton.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            try {
                // Encrypted text
                Raw.setText(encrypt(input.getText().toString()));

                // Receive plain text from MyActivity
                //
                // Bundle gotContainer = getIntent().getExtras();
                // String gotPlainText = gotContainer.getString("key");
                // input.setText(gotPlainText);

                // Send encrypted to MyActivty
                //
                // Bundle container2 = new Bundle();
                // container2.putString(encrypt(input.getText().toString()),
                // "key2");
                // Intent myIntent2 = new Intent(EncryptActivity.this,
                // MyActivity.class);
                // myIntent2.putExtras(container2);
                // startActivity(myIntent2);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        };
    });

    deButton.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            try {
                output.setText(String.valueOf(decrypt(Raw.getText()
                        .toString())));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });

}

private final static String RSA = "RSA";
public static PublicKey uk;
public static PrivateKey rk;

public static void generateKey() throws Exception {
    KeyPairGenerator gen = KeyPairGenerator.getInstance(RSA);
    gen.initialize(512, new SecureRandom());
    KeyPair keyPair = gen.generateKeyPair();
    uk = keyPair.getPublic();
    rk = keyPair.getPrivate();
}

private static byte[] encrypt(String text, PublicKey pubRSA)
        throws Exception {
    Cipher cipher = Cipher.getInstance(RSA);
    cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
    return cipher.doFinal(text.getBytes());
}

public final static String encrypt(String text) {
    try {
        return byte2hex(encrypt(text, uk));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public final static String decrypt(String data) {
    try {
        return new String(decrypt(hex2byte(data.getBytes())));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

private static byte[] decrypt(byte[] src) throws Exception {
    Cipher cipher = Cipher.getInstance(RSA);
    cipher.init(Cipher.DECRYPT_MODE, rk);
    return cipher.doFinal(src);
}

public static String byte2hex(byte[] b) {
    String hs = "";
    String stmp = "";
    for (int n = 0; n < b.length; n++) {
        stmp = Integer.toHexString(b[n] & 0xFF);
        if (stmp.length() == 1)
            hs += ("0" + stmp);
        else
            hs += stmp;
    }
    return hs.toUpperCase();
}

public static byte[] hex2byte(byte[] b) {
    if ((b.length % 2) != 0)
        throw new IllegalArgumentException("hello");

    byte[] b2 = new byte[b.length / 2];

    for (int n = 0; n < b.length; n += 2) {
        String item = new String(b, n, 2);
        b2[n / 2] = (byte) Integer.parseInt(item, 16);
    }
    return b2;
}

}

MyActivity:

public class MyActivity extends Activity {

private ListView mList;
private ArrayList<String> arrayList;
private MyCustomAdapter mAdapter;
private TCPClient mTcpClient;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);

    arrayList = new ArrayList<String>();

    final EditText editText = (EditText) findViewById(R.id.editText);
    Button send = (Button) findViewById(R.id.send_button);

    // relate the listView from java to the one created in xml
    mList = (ListView) findViewById(R.id.list);
    mAdapter = new MyCustomAdapter(this, arrayList);
    mList.setAdapter(mAdapter);

    // connect to the server
    new connectTask().execute("");

    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            String message = editText.getText().toString();

            // String encMessage =
            // EncryptActivity.encrypt(editText.getText().toString());

            // Send plain text to EncryptActivity
            //
            // Bundle container = new Bundle();
            // container.putString(message, "key");
            // Intent myIntent = new Intent(MyActivity.this,
            // EncryptActivity.class);
            // myIntent.putExtras(container);
            // startActivity(myIntent);

            // Receive encrypted data from EncryptActivity
            //
            // Bundle gotContainer2 = getIntent().getExtras();
            // String gotEncrypted = gotContainer2.getString("key2");

            // add the text in the arrayList
            arrayList.add("Me: " + message);

            // sends the message to the server
            // Change message to gotEncrypted but doesn't work :(
            if (mTcpClient != null) {
                mTcpClient.sendMessage(message);
            }

            // refresh the list
            mAdapter.notifyDataSetChanged();
            editText.setText("");
        }
    });

}

public class connectTask extends AsyncTask<String, String, TCPClient> {

    @Override
    protected TCPClient doInBackground(String... message) {

        // we create a TCPClient object and
        mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
            @Override
            // here the messageReceived method is implemented
            public void messageReceived(String message) {
                // this method calls the onProgressUpdate
                publishProgress(message);
            }
        });
        mTcpClient.run();

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);

        // in the arrayList we add the messaged received from server
        arrayList.add(values[0]);
        // notify the adapter that the data set has changed. This means that
        // new message received
        // from server was added to the list
        mAdapter.notifyDataSetChanged();
    }
}

}

回答1:

It looks like you have your key,value pair backwards here

container.putString(message, "key");

The key, which you use to retrieve the extra in getString() should be first. Change those around

container.putString("key", message);

Intent Docs



回答2:

Thank you guys @codeMagic & @Joffrey, I fixed those problems you mentioned. And I found the reason that EncryptActivity was returning "null": Intent was inside the setOnClickListener, and as we didn't have any click in EncryptActivity, return was "null".

Now MyActivity class can send plain text to EncryptActivity and receive encrypted text back

I changed this part in EncryptActivity:

public void onCreate(Bundle savedInstanceState) {
    try {
        generateKey();
    } catch (Exception e1) {
        e1.printStackTrace();
    }
    super.onCreate(savedInstanceState);

    // Receive plain text from MyActivity
    String plainText = getIntent().getStringExtra("plainKey");
    String cipherText = encrypt(plainText);

    // Send encrypted to MyActivty
    Intent cryptIntent = new Intent(EncryptActivity.this, MyActivity.class);
    cryptIntent.putExtra("cipherKey", cipherText);
    startActivity(cryptIntent);
}

And some changes in MyActivity class:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    initialize();
}

private void initialize() {

    arrayList = new ArrayList<String>();
    editText = (EditText) findViewById(R.id.editText);
    Button send = (Button) findViewById(R.id.send_button);
    mList = (ListView) findViewById(R.id.list);
    mAdapter = new MyCustomAdapter(this, arrayList);
    mList.setAdapter(mAdapter);
    // connect to the server
    new connectTask().execute("");
    send.setOnClickListener(this);
}

@Override
public void onClick(View arg0) {

    String plainText = editText.getText().toString();

    // Send plain text to EncryptActivity
    Intent plainIntent = new Intent(MyActivity.this, EncryptActivity.class);
    plainIntent.putExtra("plainKey", plainText);
    startActivity(plainIntent);

    // Receive encrypted data from EncryptActivity
    String message = getIntent().getStringExtra("cipherKey");

    // add the text in the arrayList
    arrayList.add("Me: " + plainText);

    // sends the message to the server
    if (mTcpClient != null) {
        mTcpClient.sendMessage(message);
    }

    // refresh the list
    mAdapter.notifyDataSetChanged();
    editText.setText("");
}