How to secure pre marshmallow application crashings - android

I am making an application that contains a part of activities that can be executed on pre marshmallow devices and some part of activities on marshmallow and above.
So what I want to do is don't let the application crash on pre marshmallow device that runs the activity that is supported on marshmallow device and just show a toast that your device does not support this module to access.
Here I am stuck on finger print module that crashes the applications on pre marshmallow device.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
//do something
}
else
showToastMessage();
Error
FATAL EXCEPTION: main
java.lang.VerifyError: com/example/android/fingerprintdialog/MainActivity
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1130)
at android.app.Instrumentation.newActivity(Instrumentation.java:1078)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2210)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
at android.app.ActivityThread.access$700(ActivityThread.java:159)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)

In my application I have a download button that requires runtime permission.
This is how I managed to do it:
public static int MY_PERMISSIONS_REQUEST_DOWNLOAD_IMAGE = 1;
btnDownLoad.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
urlFromDownload();
}
});
public void urlFromDownload() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_DOWNLOAD_IMAGE);
} else {
DowloadFileFromUrl downloadwall = new DowloadFileFromUrl();
if (downloadwall.getStatus() == AsyncTask.Status.RUNNING) {
// My AsyncTask has not started yet
Toast.makeText(getActivity(), "Please wait until download is complete", Toast.LENGTH_SHORT).show();
} else {
downloadwall.execute(imageUrl);
}
}
} else {
DowloadFileFromUrl downloadwall = new DowloadFileFromUrl();
if (downloadwall.getStatus() == AsyncTask.Status.RUNNING) {
// My AsyncTask has not started yet
Toast.makeText(getActivity(), "Please wait until download is complete", Toast.LENGTH_SHORT).show();
} else {
downloadwall.execute(imageUrl);
}
}
}
I hope you understand my code. What I've done is wrote my download code twice. First for marshmallow and second for lower versions.

Just check whether installed app is using marshmallow or above Android OS.
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M)
{
// FingerPrint is supported by Android
// Show the FingerPrint touch screen.
}
else
{
//FingerPrint is not supported by Android
//Don't show the FingerPrint touch screen.
}

Put that within the below condition
if (Build.VERSION.SDK_INT >= 23) {
// Your code for
} else {
// Code for previous versions
}

Related

Open Android credentials Setup programmatically

To display sensible data users can enable authentication in my app. I am using the android in-build authentication.
However, if the user did not secure his device using any pattern, pin, password or biometric authentication, I would like to open the android settings, where he can setup his authentication. Is there any Intent/ way to go there? I did not find it.
Some code so far:
To determine, if the user did not setup any authentication method:
androidx.biometric.BiometricPrompt biometricPrompt = new BiometricPrompt((FragmentActivity) activity, executor, new BiometricPrompt.AuthenticationCallback() {
#Override
public void onAuthenticationError(int errorCode, #NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
// Determine, if the user has no device password set.
boolean errorCodeIsBeingHandledSeparately = false;
// HERE WE DETERMINE THAT CREDENTIALS HAVE NOT BEEN SETUP
if (errorCode == BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL) {
if (authenticationInterface != null) {
errorCodeIsBeingHandledSeparately = true;
authenticationInterface.onUserHasNoDevicePassWordSet();
}
}
// Display error message, only if the error code is not being handled seperately.
if (!errorCodeIsBeingHandledSeparately) {
Toast.makeText(activity, "Authentication error\n" + errString, Toast.LENGTH_LONG).show();
}
}
#Override
public void onAuthenticationSucceeded(#NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
if (authenticationInterface == null) {
Toast.makeText(activity, "Success", Toast.LENGTH_LONG).show();
}
else {
authenticationInterface.onUserSuccessfullyAuthenticated();
}
}
#Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
Toast.makeText(activity, "Authentication failed", Toast.LENGTH_LONG).show();
}
});
The interface to receive authentication return.
/**
* Interface to receive authentication return.
*/
private AuthenticationUtils.AuthenticationInterface authenticationInterface;
public interface AuthenticationInterface {
public void onUserSuccessfullyAuthenticated();
public void onUserHasNoDevicePassWordSet();
}
The dialog where I want to lead the user to go to the device setup credentials.
public void displayNoDeviceCredentialsSetDialog() {
MaterialAlertDialogBuilder noDeviceCredentialsDialog = new MaterialAlertDialogBuilder(activity, R.style.AlertDialogTheme);
String noDeviceCredentials_goToSettings_dialogMessage = activity.getString(R.string.authentication_noDeviceCredentials_goToSettings_dialogMessage);
noDeviceCredentialsDialog.setMessage(noDeviceCredentials_goToSettings_dialogMessage);
noDeviceCredentialsDialog.setPositiveButton(
R.string.DialogConfirmationOK,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// HERE I WOULD LIKE TO OPEN THE ANDROID SETTING WHERE HE CAN SETUP HIS CREDENTIALS
}
}
);
noDeviceCredentialsDialog.setNegativeButton(
R.string.DialogConfirmationNegativeAnswerText,
null
);
noDeviceCredentialsDialog.show();
}
I would like to go here:
You can get there from settings here:
What i am looking for is something like this: Here we navigate the user to some other android settings.
Intent intent2 = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent2.setAction(android.provider.Settings.ACTION_APPLICATION_SETTINGS);
intent2.putExtra(android.provider.Settings.EXTRA_APP_PACKAGE, getPackageName());
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
intent2.setAction(android.provider.Settings.ACTION_APPLICATION_SETTINGS);
intent2.putExtra("app_package", getPackageName());
intent2.putExtra("app_uid", getApplicationInfo().uid);
} else {
intent2.setAction(android.provider.Settings.ACTION_APPLICATION_SETTINGS);
intent2.addCategory(Intent.CATEGORY_DEFAULT);
intent2.setData(Uri.parse("package:" + getPackageName()));
}
startActivity(intent2);
Just figured it out.
There are 3 viable options to use: Settings.ACTION_BIOMETRIC_ENROLL, Settings.ACTION_FINGERPRINT_ENROLL and Settings.ACTION_SECURITY_SETTINGS.
Final implementation I use is:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity.startActivity(new Intent(Settings.ACTION_BIOMETRIC_ENROLL));
}
else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
activity.startActivity(new Intent(Settings.ACTION_FINGERPRINT_ENROLL));
}
else {
activity.startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
}
}
Settings.ACTION_FINGERPRINT_ENROLL opens this: After chosing backup lock screen method and setup the chosen method, the device will ask you to register a fingerprint.
Settings.ACTION_SECURITY_SETTINGS opens this:
In lack of a device higher than Android Build "R" I could not test ACTION_BIOMETRIC_ENROLL, but I presume it will be similar to ACTION_FINGERPRINT_ENROLL.
If you want to see what options there are to open android settings. You can just use "CTRL" + "mouse click" on any Settings.XXX (ACTION_SECURITY_SETTINGS, ACTION_FINGERPRINT_ENROLL, ...) in Android Studio.
You will then see "..\android\platforms\android-31\android.jar!\android\provider\Settings.class"
In case you struggle to figure out which API version is described with "Build.VERSION_CODES.P" you can also click "CTRL" + "Mose Click" on the Build version (P, O, ...).
You will then see this:

How to Set the Background Drawable of a Button Properly Android

I am trying to change the background of a button when the user press it in the emulator everything works fine but on a real device the app crash.
here is my code:
answerOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
answerOne.setBackgroundResource(R.drawable.button_background_green);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ValidateAnswer(current5,Answers_six[0]);
}
});
and the error in the log is:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nasrf.winners10, PID: 9715
android.content.res.Resources$NotFoundException: Resource ID #0x7f080060
at android.content.res.Resources.getValue(Resources.java:1416)
at android.content.res.Resources.getDrawable(Resources.java:861)
at android.content.Context.getDrawable(Context.java:402)
at android.view.View.setBackgroundResource(View.java:16423)
at android.support.v7.widget.AppCompatButton.setBackgroundResource(AppCompatButton.java:83)
at com.example.nasrf.winners10.Game.GameActivity$16.onClick(GameActivity.java:426)
at android.view.View.performClick(View.java:4802)
at android.view.View$PerformClick.run(View.java:20101)
at android.os.Handler.handleCallback(Handler.java:810)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:189)
at android.app.ActivityThread.main(ActivityThread.java:5529)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:956)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:751)
any help please?
Its happening due to the difference in the SDK of your emulator and real device.
You can check the sdk first and then set the Background like this -
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN){
answerOne.setBackgroundDrawable(getResources().getDrawable(R.drawable.button_background_green));
}
else if(android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
answerOne.setBackground(getResources().getDrawable(R.drawable.button_background_green));
} else{
answerOne.setBackground(ContextCompat.getDrawable(this, R.drawable.button_background_green));
}

FlashLight App Fail to connect to camera service

Here Is my Code:
I have Added a github Permission code But it still Crashes
I have done every thing but it crashes Every Time
I also have added Permission for Camera in my manifest
parameter = camera.getParameters();
}
#Override public void onPermissionDenied(PermissionDeniedResponse response) {
Toast.makeText(getApplicationContext(), "Permission Denied", Toast.LENGTH_SHORT).show();
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("App needs permission to access camera")
.setPositiveButton("Granted", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(myAppSettings);
}
}).setNegativeButton("Denied", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).create().show();
}
#Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token)
{[enter image description here][1]
token.continuePermissionRequest();
}
}).check();
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
textview = (TextView) findViewById(R.id.textView);
flashLight = (ImageButton) findViewById(R.id.flash_light);
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//askPermission(CAMERA,camera1);
flashLight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isFlashLightOn) {
turnOnTheFlash();
} else {
turnOffTheFlash();
}
}
});
logCat:
09-30 18:59:31.698 11339-11339/inducesmile.com.androidflashlightapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: inducesmile.com.androidflashlightapp, PID: 11339
java.lang.RuntimeException: Unable to resume activity {inducesmile.com.androidflashlightapp/inducesmile.com.androidflashlightapp.MainActivity}: java.lang.RuntimeException: Fail to connect to camera service
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3506)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3546)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2795)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1073)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)
Caused by: java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.(Camera.java:647)
at android.hardware.Camera.open(Camera.java:510)
at inducesmile.com.androidflashlightapp.MainActivity.turnOffTheFlash(MainActivity.java:105)
at inducesmile.com.androidflashlightapp.MainActivity.onResume(MainActivity.java:165)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1269)
at android.app.Activity.performResume(Activity.java:6791)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3477)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3546) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2795) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527) 
at android.os.Handler.dispatchMessage(Handler.java:110) 
at android.os.Looper.loop(Looper.java:203) 
at android.app.ActivityThread.main(ActivityThread.java:6251) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1073) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934) 
09-30 18:59:31.804 11339-11347/inducesmile.com.androidflashlightapp I/art: Enter while loop.
I also had created a flashlight sensor based app a few months back. I have created gist for the code of the flashlight activity (both java and xml) and it seems to be working fine. Take a look at the below links and see if it helps:
https://gist.github.com/robillo/b27d37be3262164ee7f5532230c28c5a
https://gist.github.com/robillo/71afef65923138ed9d6011e3bd216249
Also, try doing your processing part of the activity in the if block in onCreate() like:
askForPermissions();
if(checkForPermission()){
//Do your processing here
}
The functions are:
void askForPermissions(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
getActivity().requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
}
boolean checkForPermission(){
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
It's tough to tell without seeing your turnOnTheFlash and turnOffTheFlash functions, but I'd guess that you are not properly releasing the camera at some point as shown by the documentation.

Opencv stopped working on Android 6.0

I am using Opencv on my application and it works fine with Android 4.3 but it doesn't even open with Android 6.0.
I looked up for a solution on SO, and found one that says to set the package name. So I did it.
Follow code:
public static boolean initOpenCV(String Version, final Context AppContext,
final LoaderCallbackInterface Callback)
{
AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback);
Intent intent = new Intent("org.opencv.engine.BIND");
intent.setPackage("org.opencv.engine");
if (AppContext.bindService(intent,
helper.mServiceConnection, Context.BIND_AUTO_CREATE))
{
return true;
}
else
{
AppContext.unbindService(helper.mServiceConnection);
InstallService(AppContext, Callback);
return false;
}
}
But now I am getting the following error:
11-18 10:14:43.447 24901-24930/br.com.ibramed.dermos E/AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
11-18 10:14:43.447 24901-24930/br.com.ibramed.dermos E/AndroidRuntime: at android.view.ViewRootImpl.setView(ViewRootImpl.java:571)
11-18 10:14:43.447 24901-24930/br.com.ibramed.dermos E/AndroidRuntime: at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:310)
11-18 10:14:43.447 24901-24930/br.com.ibramed.dermos E/AndroidRuntime: at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
11-18 10:14:43.447 24901-24930/br.com.ibramed.dermos E/AndroidRuntime: at android.app.Dialog.show(Dialog.java:319)
in the following code:
case InstallCallbackInterface.NEW_INSTALLATION:
{
Looper.prepare();
Log.d("Debug", ""+mAppContext);
AlertDialog InstallMessage = new AlertDialog.Builder(mAppContext).create();
InstallMessage.setTitle("Package not found");
InstallMessage.setMessage(callback.getPackageName() + " package was not found! Try to install it?");
InstallMessage.setCancelable(false); // This blocks the 'BACK' button
InstallMessage.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", new OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
callback.install();
}
});
InstallMessage.setButton(AlertDialog.BUTTON_NEGATIVE, "No", new OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
callback.cancel();
}
});
InstallMessage.show();
} break;
I have searched and found some people saying to keep track of the main Context, because Threads doesn't have context. But my app already does this and use the main context to create the AlertDialogs and it still doesn't work.
The error is when the app show the AlertDialog.
I really don't know what else to do. Can someone help?
As far as I know in service or Aplication class you cant get context with View for android 6.0, so when OpenCv tries to show AlertDialog it does not know to what activity bind dialog and crashes.
Try to init OpenCv in Activity onCreate method before usage.
My working init method in MainActivity (code on kotlin):
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this, object : BaseLoaderCallback(this#HistoryActivity) {
override fun onManagerConnected(status: Int) {
if (LoaderCallbackInterface.SUCCESS == status)
Log.i(TAG, "OpenCV was loaded")
else
super.onManagerConnected(status)
}
})
}

RuntimeException on Xperia-devices when using ZXing

I have an application uploaded to Google Play. The app is supposed to scan a QR-code from a pole to register a visit. It works on all devices but Sony XPERIA models. In Google Play Developer Console I get a lot of one particular crash:
java.lang.RuntimeException: autoFocus failed
at android.hardware.Camera.native_autoFocus(Native Method)
at android.hardware.Camera.autoFocus(Camera.java:975)
at me.dm7.barcodescanner.core.CameraPreview$1.run(CameraPreview.java:196)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5225)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
The only place I call the camera is is here:
public class ScannerActivity extends Activity implements ZXingScannerView.ResultHandler {
private ZXingScannerView m_ScannerView;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
m_ScannerView = new ZXingScannerView(this);
setContentView(m_ScannerView);
}
#Override
public void onResume() {
super.onResume();
m_ScannerView.setResultHandler(ScannerActivity.this);
m_ScannerView.startCamera();
}
#Override
public void onPause() {
super.onPause();
m_ScannerView.stopCamera();
}
As far as I can tell, this is a bug in ZXing. You can implement a workaround by replacing ZXingSurfaceView:AutoFocus with an implementation that catches the exception. (You'll also have to replace a few other files if you go this route, or re-compile ZXing on your own). This doesn't resolve the root cause, though.
This bug was fixed in ZXing on July 29 2015, so updating to the latest version is probably easier.
public void AutoFocus()
{
if (camera != null)
{
if (!tokenSource.IsCancellationRequested)
{
global::Android.Util.Log.Debug("ZXING", "AutoFocus Requested");
try
{
camera.AutoFocus(this);
}
catch (RuntimeException ex)
{
Console.WriteLine("ZXING: Warning: Caught RuntimeException during AutoFocus.");
}
}
}
}

Categories

Resources