gpt4 book ai didi

java - NoSuchMethodError 在我的 android 设备上运行时确实存在的方法

转载 作者:太空狗 更新时间:2023-10-29 15:05:59 25 4
gpt4 key购买 nike

感谢您花时间阅读本文。我在一个涉及 Android 的项目中遇到了一个非常奇怪的“NoSuchMethodError”。我想不通,因为它违背了我所有的逻辑。

package com.project.qrcode

import android.security.KeyStore;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import jim.h.common.android.lib.zxing.config.ZXingLibConfig;
import jim.h.common.android.lib.zxing.integrator.IntentIntegrator;
import jim.h.common.android.lib.zxing.integrator.IntentResult;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

private ZXingLibConfig zxingLibConfig;
private Handler handler = new Handler();
private TextView txtScanResult;
KeyStore ks = KeyStore.getInstance();
SecretKeyStore secretKeyStore = new SecretKeyStore();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );

byte[] hashedBytes;
String decoded;

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

try {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
startActivity(new Intent("android.credentials.UNLOCK"));
} else {
startActivity(new Intent("com.android.credentials.UNLOCK"));
}
} catch (ActivityNotFoundException e) {
Log.e(getPackageName(), "No UNLOCK activity: " + e.getMessage(), e);
}

zxingLibConfig = new ZXingLibConfig();
zxingLibConfig.useFrontLight = true;
txtScanResult = (TextView) findViewById(R.id.scan_result);

Button scanButton = (Button) findViewById(R.id.scan_button);

//Set a listener on the scan button
scanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!checkIfKeyStored()) {
Toast keyerror = Toast.makeText(getBaseContext(), "You need to complete setup first", Toast.LENGTH_SHORT);
keyerror.show();
return;
}
IntentIntegrator.initiateScan(MainActivity.this, zxingLibConfig);
}
});
Log.v(getPackageName(), "Listener set on scan button");

Button setupButton = (Button) findViewById(R.id.setup_button);

// Set a listener on the setup button
setupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (checkIfKeyStored()) {
Log.v(getPackageName(), "Key is already stored");
Toast keyerror = Toast.makeText(getBaseContext(), "You have already completed setup", Toast.LENGTH_SHORT);
keyerror.show();
return;
}
Log.v(getPackageName(), "Key not stored, proceeding with setup");
IntentIntegrator.initiateScan(MainActivity.this, zxingLibConfig);
}
});
Log.v(getPackageName(), "Listener set on setup button");
}

protected boolean checkIfKeyStored() {
String[] keyNames = ks.saw("");

if( keyNames.length == 0 ) {
return false;
}

return true;
}

// IF setup is done i.e. key is stored send to server
// Otherwise store on phone

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Log.v(getPackageName(), "Scanned QRCode");

if (requestCode == IntentIntegrator.REQUEST_CODE) {
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);

if (scanResult == null) {
Log.v(getPackageName(), "Scanned nothing");
return;
}

//Contents of the QRCode
Log.v(getPackageName(), "Scan complete, getting result");
final String result = scanResult.getContents();
Log.v(getPackageName(), "Scanned the following code "+ result);

//If there is already a secret key stored i.e. setup already done
if (checkIfKeyStored()) {
Log.v(getPackageName(), "Key already stored, encrypting");
try {
MessageDigest digest = MessageDigest.getInstance("SHA1PRNG");
Log.v(getPackageName(), "Got SHA1PRNG instance");

byte[] keyBytes = ks.get("twofactorkey");
byte[] resultBytes = result.getBytes("UTF-8");

Log.v(getPackageName(), "Got Bytes");

outputStream.write( resultBytes );
outputStream.write( keyBytes );
Log.v(getPackageName(), "Wrote Bytes to output stream");

byte[] bytesToEncrypt = outputStream.toByteArray( );
Log.v(getPackageName(), "Wrote to Byte array");

hashedBytes = digest.digest(bytesToEncrypt);
decoded = new String(hashedBytes, "UTF-8");
Log.v(getPackageName(), "Coverted bytes to String");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

handler.post(new Runnable() {
@Override
public void run() {
txtScanResult.setText(decoded);
Log.v(getPackageName(), "Set TextView");
}
});
}
else //This is the first time scanning a QRCode, i.e. Setup
{
Log.v(getPackageName(), "Key not stored, first time setup");

byte[] resultBytes;

try {
resultBytes = result.getBytes("UTF-8");
Log.v(getPackageName(), "Result byte array: " + resultBytes);

boolean success = ks.put("twofactorkey", resultBytes);

if (!success) {
int errorCode = ks.getLastError();
throw new RuntimeException("Keystore error: " + errorCode);
}

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

Log.v(getPackageName(), "Stored in keystore");

Toast setupComplete = Toast.makeText(getBaseContext(), "You have completed setup", Toast.LENGTH_SHORT);
setupComplete.show();
}
}
}

}

package android.security;

public class KeyStore {
private boolean put(byte[] key, byte[] value) {
execute('i', key, value);
return mError == NO_ERROR;
}

public boolean put(String key, byte[] value) {
Log.v("KEYSTORE", "Attempting put");
return put(getBytes(key), value);
}
}

我得到的错误是..02-24 15:25:55.689: E/AndroidRuntime(11016): java.lang.NoSuchMethodError: android.security.KeyStore.put 发生在 onActivityResult() 方法中。

如果您需要完整的 logcat,我也可以发布。

您可以看到我在整个代码中植入了一些日志消息。放在里面的永远不会打印出来。

编辑 24/02/14:上面的 NoMethod 异常已经通过将 KeyStore.java 移动到与 MainActivity.java 相同的包中得到解决 - 谢谢 Lars

但是我现在有一个新问题。每当我尝试使用 ks.state() 或 ks.put() 时,我都会收到 AssertError: 5 的响应 - 根据 KeyStore.java 的说法,这是一个协议(protocol)错误。

最终编辑我想通了上面的问题。事实证明,我使用的 AOSP KeyStore 版本仅适用于 4.2 以下的 Android 版本。

最佳答案

java.lang.NoSuchMethodError是什么原因

java 文档说

Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method. Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.

在您的代码中,您在这里调用了 put 方法

boolean success = ks.put("twofactorkey", resultBytes);

并且您在 KeyStore 类中有一个必需的方法

public boolean put(String key, byte[] value) {
Log.v("KEYSTORE", "Attempting put");
return put(getBytes(key), value);
}

但问题是您编译的 KeyStore(KeyStore.class 文件)没有必需的 put 方法。我假设您错误地更改了上面的 put 方法并单独 编译了两个类并运行了 MainActivity 类。这就是你得到那个错误的原因

关于java - NoSuchMethodError 在我的 android 设备上运行时确实存在的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21992496/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com