Problem opening BiometricPrompt android studio - android-studio

I have a code where I call biometrics for password validation, and it ends up working normally, I always have the expected results when I request, but it ends up generating an error on my console that I would like you to solve, but I don't find it in place some.
Follow the code:
Error:
java.lang.IllegalStateException: Must be called from main thread of fragment host
at androidx.fragment.app.FragmentManagerImpl.ensureExecReady(FragmentManagerImpl.java:1668)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1721)
at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:183)
at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:749)
at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:658)
at com.app.EntryPoint.showBiometricPrompt(EntryPoint.java:832)
at ifractal.ManagingRequests$1.callback(ManagingRequests.java:156)
at ifractal.ManagingRequests.itAllStartsHere(ManagingRequests.java:1598)
at ifractal.JSBridge.query(JSBridge.java:35)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:165)
at android.os.HandlerThread.run(HandlerThread.java:65)
public boolean showBiometricPrompt(String callback, String primeiro_acesso) {
BiometricPrompt.PromptInfo promptInfo =
new BiometricPrompt.PromptInfo.Builder()
.setTitle("Autenticação")
.setSubtitle("Realize o login usando sua biometria")
.setNegativeButtonText("Cancelar")
.build();
BiometricPrompt biometricPrompt = new BiometricPrompt(EntryPoint.this,
executor, new BiometricPrompt.AuthenticationCallback() {
#Override
public void onAuthenticationError(int errorCode, #NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
asset.log("onAuthenticationError", "Error: " +errString);
}
}
#Override
public void onAuthenticationSucceeded(
#NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
BiometricPrompt.CryptoObject authenticatedCryptoObject =
result.getCryptoObject();
}
#SuppressLint("WrongConstant")
#Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
asset.log("onAuthenticationError", "Failed");
}
});
biometricPrompt.authenticate(promptInfo);
return true;
}

Related

Flutter Platform Channels - Invoke channel method on android, hangs the ui

I'm trying to use Tesseract in flutter using the following package https://github.com/arrrrny/tesseract_ocr
I've download the app and run in.
The problem is that the extractText hangs the UI.
Looking at the Java code:
Thread t = new Thread(new Runnable() {
public void run() {
baseApi.setImage(tempFile);
recognizedText[0] = baseApi.getUTF8Text();
baseApi.end();
}
});
t.start();
try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); }
result.success(recognizedText[0]);
I can see that it is running on a new thread, so I expect it not to hang the app, but it still does.
I found this example:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// Call the desired channel message here.
baseApi.setImage(tempFile);
recognizedText[0] = baseApi.getHOCRText(0);
baseApi.end();
result.success(recognizedText[0]);
}
});
from https://flutter.dev/docs/development/platform-integration/platform-channels#channels-and-platform-threading
but it also hangs the UI.
The docs also say
**Channels and Platform Threading**
Invoke all channel methods on the platform’s main thread when writing code on the platform side.
Can someone clarify this sentence?
According to Richard Heap answer, I tried to call a method from native to dart, passing the result:
Dart side:
_channel.setMethodCallHandler((call) {
print(call);
switch (call.method) {
case "extractTextResult":
final String result = call.arguments;
print(result);
}
var t;
return t;
});
Java side:
channel.invokeMethod("extractTextResult","hello");
if I call this method from the main thread, this works fine, but then the thread is blocking.
If I do
Thread t = new Thread(new Runnable() {
public void run() {
channel.invokeMethod("extractTextResult","test1231231");
}
});
t.start();
result.success("tst"); // return immediately
Then the app crashes with the following message:
I also tried:
Thread t = new Thread(new Runnable() {
public void run() {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// Call the desired channel message here.
baseApi.setImage(tempFile);
recognizedText[0] = baseApi.getHOCRText(0);
baseApi.end();
result.success(recognizedText[0]);
// channel.invokeMethod("extractTextResult", "test1231231");
}
});
}
});
t.start();
result.success("tst");
which is what I understand that Richard Heap last comment meant, but It still hangs the ui.
I had the same Issue and fixed it with a MethodCallWrapper in TesseractOcrPlugin.java
This Code works for me (no Dart-code change is needed):
package io.paratoner.tesseract_ocr;
import com.googlecode.tesseract.android.TessBaseAPI;
import android.os.Handler;
import android.os.Looper;
import android.os.AsyncTask;
import java.io.File;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** TesseractOcrPlugin */
public class TesseractOcrPlugin implements MethodCallHandler {
private static final int DEFAULT_PAGE_SEG_MODE = TessBaseAPI.PageSegMode.PSM_SINGLE_BLOCK;
/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "tesseract_ocr");
channel.setMethodCallHandler(new TesseractOcrPlugin());
}
// MethodChannel.Result wrapper that responds on the platform thread.
private static class MethodResultWrapper implements Result {
private Result methodResult;
private Handler handler;
MethodResultWrapper(Result result) {
methodResult = result;
handler = new Handler(Looper.getMainLooper());
}
#Override
public void success(final Object result) {
handler.post(new Runnable() {
#Override
public void run() {
methodResult.success(result);
}
});
}
#Override
public void error(final String errorCode, final String errorMessage, final Object errorDetails) {
handler.post(new Runnable() {
#Override
public void run() {
methodResult.error(errorCode, errorMessage, errorDetails);
}
});
}
#Override
public void notImplemented() {
handler.post(new Runnable() {
#Override
public void run() {
methodResult.notImplemented();
}
});
}
}
#Override
public void onMethodCall(MethodCall call, Result rawResult) {
Result result = new MethodResultWrapper(rawResult);
if (call.method.equals("extractText")) {
final String tessDataPath = call.argument("tessData");
final String imagePath = call.argument("imagePath");
String DEFAULT_LANGUAGE = "eng";
if (call.argument("language") != null) {
DEFAULT_LANGUAGE = call.argument("language");
}
calculateResult(tessDataPath, imagePath, DEFAULT_LANGUAGE, result);
} else {
result.notImplemented();
}
}
private void calculateResult(final String tessDataPath, final String imagePath, final String language,
final Result result) {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
final String[] recognizedText = new String[1];
final TessBaseAPI baseApi = new TessBaseAPI();
baseApi.init(tessDataPath, language);
final File tempFile = new File(imagePath);
baseApi.setPageSegMode(DEFAULT_PAGE_SEG_MODE);
baseApi.setImage(tempFile);
recognizedText[0] = baseApi.getUTF8Text();
baseApi.end();
result.success(recognizedText[0]);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}.execute();
}
}
By using join you're making the main thread wait for the background thread, blocking it. You have to remove the join and return a result immediately.
So, how do you return the ocr result, which won't be available immediately. When it becomes available, you then call a method from native to dart, passing the result. At the dart end, you then handle the result as any async event.
The point of the last paragraph of your question is that your result will become available on your background thread, so you'd want to call the native to dart method there. You can't. You have to post the method call code to the main looper - you already show some code for posting to the main looper which you can use as an example.
Based on Richard Heap answer I came up with this:
Dart code:
_channel.setMethodCallHandler((call) {
switch (call.method) {
case "extractTextResult":
final String result = call.arguments;
print(result);
}
var t;
return t;
});
Java code:
Thread t = new Thread(new Runnable() {
public void run() {
baseApi.setImage(tempFile);
recognizedText[0] = baseApi.getHOCRText(0);
baseApi.end();
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
channel.invokeMethod("extractTextResult", recognizedText[0]);
}
});
}
});
t.start();
result.success("tst");
explain:
This code will run the Java extractText in a separate thread, and when the result is ready it will hopp back to the ui thread with the call to Looper.getMainLooper() which will then send the message back to the Dart side which must receive the message on the ui thread, which is what this message means:
**Channels and Platform Threading**
Invoke all channel methods on the platform’s main thread when writing code on the platform side.
NOTE on the Dart side, this is still incomplete example since you then need to report to the ui that a message received, this can be done with a Completer, which is used to create and complete a future
At the end of your method channel just return the response back to dart side
Add this line at the end of method channel result.success(true)
full example
override fun configureFlutterEngine(#NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
"method-channel"
).setMethodCallHandler { call, result ->
if (call.method == "getFirebaseAppCheckDebugToken") {
...
result.success(true) // just add this line
}
}
}```

Attempt to invoke virtual method...on a null object reference problem

I have a problem with my code, where sometimes I get a null object reference and sometimes not (on the same thing) and I cant understand whats the problem because as I said, one time its working fine but on the second time it shows me the null object reference message. What Im trying to do is to get the club of the logged trainer from my Azure table.
private MobileServiceTable<trainer> TrainerTable=null;
private MobileServiceClient mService=null;
private users cl=null;
private ProgressDialog prg;
private void Trainer_Club_String(final String username)
{
AsyncTask<Void,Void,Void> task = new AsyncTask<Void, Void, Void>()
{
#Override
protected Void doInBackground(Void... voids)
{
try
{
List<trainer> chosen_manager= TrainerTable.where().field("username").eq(username).execute().get(); \\the problem is in this line. Sometimes it tells me that the user is null and sometimes its working well
if(chosen_manager.size()>0)
{
trainer_club=chosen_manager.get(0).getClub().toString();
}
}
catch (Exception e)
{
final String message=e.getMessage().toString();
runOnUiThread(new Runnable()
{
#Override
public void run()
{
Toast.makeText(trainer_home_page.this, message, Toast.LENGTH_LONG).show();
}
});
}
return null;
}
}.execute();
}
ONCREATE:
cl=StaticObjects.GetClient();
trainer_username=cl.getUsername().toString();
Trainer_Club_String(trainer_username);

How to detect recent button in android 8.1.0

I want to detect recent button but in android 8.1.0 it's not working.Below code is working on another version of android but in 8.1.0 the Intent.ACTION_CLOSE_SYSTEM_DIALOGS broadcast is not calling.I am using below implementation.
public class HomeWatcher {
static final String TAG = "hg";
private Context mContext;
private IntentFilter mFilter;
private OnHomePressedListener mListener;
private InnerRecevier mRecevier;
public HomeWatcher(Context context) {
mContext = context;
mFilter = new IntentFilter();
mFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mFilter.addAction("");
}
public void setOnHomePressedListener(OnHomePressedListener listener) {
mListener = listener;
mRecevier = new InnerRecevier();
}
public void startWatch() {
if (mRecevier != null) {
mContext.registerReceiver(mRecevier, mFilter);
}
}
public void stopWatch() {
if (mRecevier != null) {
mContext.unregisterReceiver(mRecevier);
}
}
class InnerRecevier extends BroadcastReceiver {
final String SYSTEM_DIALOG_REASON_KEY = "reason";
final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null) {
Log.e(TAG, "action:" + action + ",reason:" + reason);
if (mListener != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
mListener.onHomePressed();
} else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
mListener.onHomeLongPressed();
}
}
}
}
}
}
}
and in class, I am calling using below code.
HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.startWatch();
Please help!.
Edited----
The above code is working properly in normal flow but when the screen pinning is set(ON) then it's not working. Even i am not getting any event like KeyUp, KeyDown
com.android.systemui package will be the foreground app when you click recent app button, so find the foreground running apps and launch your page if foreground running app is 'com.android.systemui'.
HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
#Override
public void onHomePressed() {
// do something here...
}
#Override
public void onHomeLongPressed() {
}
});
mHomeWatcher.startWatch();
For a detailed Answer Check
Detect Home And Recent App Button
Please use below code
`#Override
public boolean dispatchKeyEvent(KeyEvent event) {
Log.i("key pressed", String.valueOf(event.getKeyCode()));
return super.dispatchKeyEvent(event);
}`

Alaways goin in onFailure in retrofit2.0

I am trying to hit the api : www.xyz.com/abc_cc/cc/userregister/newuser
This is my Code :
public class MainActivity extends AppCompatActivity {
public static final String BASE_URL = "abc.com/abc_cc/cc/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getUnsafeOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
Endpoints endpoints= retrofit.create(Endpoints.class);
endpoints.newuser("{\"full_name\":\"sss\",\"states_id\":\"20\",\"mobile\":\"9876543210\",\"password\":\"******\",\"accept_terms\":true,\"Userid\":\"0\",\"refer\":\"\",\"ip-address\":\"1.2.3.4\",\"device_type\":\"samsung J5\",\"os-version\":\"5.0.1\",\"client\":\"app\",\"secret_key\":\"44\"}")
.enqueue(new retrofit2.Callback<Items>() {
#Override
public void onResponse(retrofit2.Call<Items> call, retrofit2.Response<Items> response) {
System.out.println("onResponse : "+response.message());
System.out.println("onResponse : "+response.body());
System.out.println("onResponse : "+response.code());
System.out.println("onResponse : "+response.errorBody());
System.out.println("onResponse : "+response.isSuccessful());
System.out.println("onResponse : "+response.raw());
System.out.println("onResponse : "+response);
}
#Override
public void onFailure(retrofit2.Call<Items> call, Throwable t) {
System.out.println("onFailure"+call);
}
});
}
public static OkHttpClient getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
} };
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts,
new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext
.getSocketFactory();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient = okHttpClient.newBuilder()
.sslSocketFactory(sslSocketFactory)
.hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Interface :
public interface Endpoints {
#POST("/userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}
POJO class :
public class Items {
#SerializedName("Response-Status")
#Expose
private Boolean responseStatus;
#SerializedName("Response-Validate")
#Expose
private Boolean responseValidate;
#SerializedName("Response-Message")
#Expose
private String responseMessage;
#SerializedName("Response-Data")
#Expose
private ResponseData responseData;
public Boolean getResponseStatus() {
return responseStatus;
}
public void setResponseStatus(Boolean responseStatus) {
this.responseStatus = responseStatus;
}
public Boolean getResponseValidate() {
return responseValidate;
}
public void setResponseValidate(Boolean responseValidate) {
this.responseValidate = responseValidate;
}
public String getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
public ResponseData getResponseData() {
return responseData;
}
public void setResponseData(ResponseData responseData) {
this.responseData = responseData;
}
}
I am getting this response :
{protocol=http/1.1, code=404, message=Not Found, url=www.xyz.com/userregister/newuser}
I have given the proper url then why is it taking only half of it?
I have tried the example from https://code.tutsplus.com/tutorials/sending-data-with-retrofit-2-http-client-for-android--cms-27845. This example and the link given in the example are working fine, but if I do the same with my url then I get the above error
I Hope kindly check your parsing issues may occurred.
#Override
public void onFailure(retrofit2.Call<Items> call, Throwable t) {
System.out.println("onFailure"+call);
//add this lije you got exceptions.
t.printStackTrace();
}
Change your Endpoints interface for this:
public interface Endpoints {
#POST("userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}
Note that I removed the trailing slash /. This way Retrofit appends the path you defined to the BASE_URL.
refer to the docs for Retrofit.Builder for a more detailed explanation, but pay particular attention to these bits:
Base URLs should always end in /.
A trailing / ensures that endpoints values which are relative paths
will correctly append themselves to a base which has path components.
...
Endpoint values which contain a leading / are absolute.
Absolute values retain only the host from baseUrl and ignore any
specified path components.
as presently written, the path referenced in your call to Endpoints.newuser() is absolute, and therefore the path segments after the host in your base URL are dropped (as this is the documented behavior).
therefore, you should change your Endpoints interface to use relative paths instead, like so:
public interface Endpoints {
#POST("userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}

Finalize method causing a memory leak?

I cannot resolve a problem and need your help. When I click on menu I call customer account and then afterwards I close it. Every time I call customer account the memory increases. It should diminish when I close the account, but it does not happen.
Class Menu
mnItemCL_Cust.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
try {
panCenterPrev = (Pane) root.getCenter();
panCenterAct = Customer.listCustomer();
root.setCenter(null);
root.setCenter(panCenterAct);
Customer.btCanc.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
try {
Customer.Fim();
panCenterAct.getChildren().clear();
panCenterAct = null;
root.setCenter(null);
root.setCenter(panCenterPrev);
} catch (Throwable ex) {
Logger.getLogger(Customer.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Class Customer
public class Customer
{
public static Pane listCustomer() throws SQLException, ClassNotFoundException
{
...
final ObservableList<MyCustomer> data = FXCollections.observableArrayList();
...
}
public static class MyCustomer {
private final SimpleIntegerProperty idcl;
private MyCustomer(Integer pIdcl ) {
this.idcl = new SimpleIntegerProperty(pIdcl);
}
public Integer getIdcl() {
return idcl.get();
}
public void setIdcl(Integer pIdcl) {
idcl.set(pIdcl);
}
}
public static void Fim() throws Throwable {
...
rs = null;
tbViewCL.getItems().clear();
tbViewCL = null;
colIDCL.getColumns().clear();
colIDCL = null;
}
...
protected void finalize() throws Throwable {
try{
...
rs.close();
...// Never happens... why??
} catch(Throwable t) {
throw t;
} finally {
JOptionPane.showMessageDialog(null,"End?");
super.finalize();
}
}
Regards
Java usually reclaims the memory you used when it see it fits, so even if you finalize the object, the memory may still be there. However, if rs.Close() never executes, probably is because something before it is throwing and exception, i recommend you to check the code before just to be sure that nothing is doing so, also, if you catch an exception is a good practice to log it so you can know what is happening.

Resources