Bluetooth activation Alert dialog multiplication after screen rotation - android

I have encountered strange issue. From Activity onStart() I request Bluetooth activation and 120s discoverability via intent:
Intent activateBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(activateBTIntent, BT_ACTIVATE_INTENT);
I use it no matter if the Bluetooth is already activated or not. Android documentation says that Bluetooth will be activated if it was not, and that works fine. In both cases I get system Alert dialog
When I rotate the screen I observe flickering. Press on Yes/No removes one dialog, but there is still another one below. Performing screen rotation I can get a pile of Alert dialogs, and have to press Yes/No on each to get rid of them.
Described issue is present only if Bluetooth was not already started when intent was sent, otherwise it works correctly. Tried on different 2.2 phones, and issue is present on all. Looks to me like Android system issue.
Has anybody encountered it also, and maybe have some useful hint how to avoid this?
Thanks and regards.

This is a bug in the Settings app that causes this. The RequestPermissionActivity is duplicating its instance of RequestPermissionHelperActivity on rotations.

I was facing the same problem. After spending lots of time with it, i have found one solution.
You can avoid the duplication of the 'Bluetooth activation Alert dialog' by using
FLAG_ACTIVITY_NO_HISTORY flag for activateBTIntent. But setting this flag will make startActivityForResult unusable.
The code -
Intent activateBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
activateBTIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(activateBTIntent);
Using FLAG_ACTIVITY_NO_HISTORY with activateBTIntent will remove the 'Bluetooth activation Alert dialog' activity from the history stack. Thus in this case, when orientation is changed, the 'Bluetooth activation Alert dialog' activity will be finished and newel created(NOT DUPLICATED):
Reference
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NO_HISTORY

(Your post doesn't nearly have enough info, so I'm assuming here...)
I'm not too sure about the startActivityForResult.
You shouldn't do showDialog() in onCreate() if you use a managed AlertDialog. If the Bluetooth thingy does that, could you try not running the above code from onCreate()?

The issue has been reported (google issue tracker) but it is already open after 6 years (checked with Android 7.1.2).
Unfortunately the flag FLAG_ACTIVITY_NO_HISTORY does not work anymore. The only quick workaround I found until Android team fix this (if they ever will) is to lock activity screen orientation change, just for the time the dialog is displayed:
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
to be called just before
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
and then use
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
super.onActivityResult(requestCode, resultCode, data);
}
on intent result.
It's a temporary remedy but usually better than showing this possible issue during BT activation.

Related

Android Developer Options causing the app to work improperly

I have created an android app for the Portuguese (Brasil). This is one of my client's app. The client is getting feedback from the app users that they are not able to use the app properly or it goes back to start screen when they click on the button to import a contact from the Phonebook.
i.e. In the app, there are various places where I start the activity to get the result.
startActivityForResult(intent, requestCode);
Generally, I'm doing this from Fragments. And to pass the result from Activity to its Fragment, I'm doing like following:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (getSupportFragmentManager() != null) {
Fragment fragment = getFragment();
if (fragment != null)
fragment.onActivityResult(requestCode, resultCode, data);
}
}
So to check this problem We asked some of the users to check if they have Developer options enabled on their device. And Yes, they have it enabled on their devices. So we asked them to disable this and try the app and believe me it works.
I also have this option enabled on my device to test the app (Debugging) and I haven't faced any problem like this while using the app.
I don't understand this issue and I need to find the appropriate solution.
So I need your help to solve this problem.
Looking for the positive responses.
Thanks.
Try fragment context instead of getActivity() as you are starting activity from the fragment and result should be returnned to fragment.
Intent intent=new Intent(fragment.getContext(), Activity.class)
fragment.startActivityForResult(intent,REQUEST_CODE);
Finally, after a very long time, the issue is resolved.
When we have Don't keep Activities option enabled on the device and as soon as you leave the activity, it gets destroyed.
And in the onCreate, I was adding the initial fragment again.
But now I have added a check of
if(savedInstanceState == null)
// initial fragment here
else
// nothing to do
This check resolved the issue in my app. Hope it helps the others too.

Screen Overlay Detected | (Android 6.x) Lenovo, Redmi & Samsung Devices

I have created an app which continuously run in background and show an floating overlay TextView(By using the permission android.permission.SYSTEM_ALERT_WINDOW).
I have problem in Lenovo android devices, when other applications try to request for user permission there is an alert dialog says "Screen Overlay Detected". While I have test the same application on Redmi 3S Prime device the "Allow" button in permission dialog is not clickable, until I have turned off the Floating Overlay TextView in my application.
So is there any solution to resolve this device specific issue? One of the possible solution may be disable floating TextView while permission dialog is visible to user and show floating overlay when permission dialog is closed, but the problem is how can I detect the permission dialog open/close state for other foreground application from my app.
Please suggest...
Unfortunately it seems that this is inherent to the Android OS, and as far as I know there is no way to detect when another app is requesting permissions. The general flow for interacting with other apps is to send intents to them in a push manner, so theoretically it could be done if the other apps send an intent to your app to disable the overlay, though this is not a practical solution.
I could be completely wrong, but I am yet to see a programmatic solution to this problem. The best you can probably do is warn your users that your app may cause this problem, and provide them with a quick temporary disable button.
how can I detect the permission dialog open/close state from my app??
Implement Method Mentioned Below, to run this check at the onCreate of the first Activity
public final static int PERM_REQUEST_CODE_DRAW_OVERLAYS = 1234;
/**
* Permission to draw Overlays/On Other Apps, related to
'android.permission.SYSTEM_ALERT_WINDOW'
in Manifest
Resolves issue of popup in Android M and above "Screen overlay detected- To change this permission setting you first have to turn off the screen overlay from Settings > Apps"
If app has not been granted permission to draw on the screen, create an Intent &
set its destination to
Settings.ACTION_MANAGE_OVERLAY_PERMISSION
&
* add a URI in the form of
"package:"
to send users directly to your app's page.
Note: Alternative Ignore URI to send user to the full list of apps.
public void permissionToDrawOverlays() {
if (android.os.Build.VERSION.SDK_INT >= 23) { //Android M Or Over
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, PERM_REQUEST_CODE_DRAW_OVERLAYS);
}
}
}
Called on the activity, to check on the results returned of the user action within the settings
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PERM_REQUEST_CODE_DRAW_OVERLAYS) {
if (android.os.Build.VERSION.SDK_INT >= 23) { //Android M Or Over
if (!Settings.canDrawOverlays(this)) {
// ADD UI FOR USER TO KNOW THAT UI for SYSTEM_ALERT_WINDOW permission was not granted earlier...
}
}
}
}
NOTE:Above code and extract is taken from following gist.
Hope this Helps!!!..
Just clear data of the Es explorer from device then after restart device.
I think these two links could help you.
firstlink
secondlink
Try to use for debug build -- targetSdkVersion 22.
After signed APK (for all targetSdkVersion(s)) application will work fine.

onActivityResult() called prematurely while calling Settings activity

I'm facing the known issue onActivityResult getting called immediately.
I read the reason behind it on some link
where it is advice to change launch mode of called activity.
But in my case I'm starting(navigating to) settings activity, to let the user enable data connection.
startActivityForResult(new Intent(android.provider.Settings.ACTION_SETTINGS),
Constants.REQUEST_ENABLE_DATA_CONNECTION);
So I can't change launch mode of Settings activity.
I tried setting some flags to Intent e.g. intent.setFlags(0); but its not working.
I think there is some problem with your request code "Constants.REQUEST_ENABLE_DATA_CONNECTION".What is your request code value.
I think you should use zero "0" value like this.
startActivityForResult(new Intent(android.provider.Settings.ACTION_SETTINGS), 0);
but if you need to open wifi settings then use this code.
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
and see this Setting actions link for other setting actions.
I hope,this will help you.

finish() on an Activity closes app then briefly shows previous Application

In my App, Activity1 launches Activity2 with "startActivityForResult()".
When Activity2 is done, the following code is called:
Activity2.java
private void finishActivity(final boolean accepted)
{
Intent returnIntent = new Intent();
setResult(accepted ? RESULT_OK : RESULT_CANCELED, returnIntent);
finish();
}
Activity1 receives this callback, and if the result is not RESULT_OK, it also finishes.
Activity1.java
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Globals.REQUEST_CODE_TOS)
{
if (resultCode != RESULT_OK)
finish();
}
}
After Activity1 finishes the app closes, as expected.
THE PROBLEM --
However, after my app closes, instead of going to the home screen, a previous application on the stack briefly launches forward, then closes also! Then I get to the home screen.
In the Android bug tracker, I see a similar bug listed for the case when the back button is pressed, which I believe is the same as calling finish():
https://code.google.com/p/android/issues/detail?id=71067
I'm seeing this on a Nexus 5, running 4.4.4.
Is this just a bug? Or are there any workarounds for the behavior?
EDIT --
To clarify the behavior I desire:
In Google Maps, if you decline the TOS popup, the app closes and you go directly to the home screen. There is no awkward flash to some previously opened app.
This is decidedly the same issue as the one you linked in your question (I've been following it for months, as I own a Nexus 5 myself). It was actually fixed in the AOSP, but that particular fix doesn't seem to have found its way into the N5 yet. I've got my fingers crossed for a fix in Lollipop, but we'll see when that rolls out.
As for a workaround, I don't think any exists at the moment, although if I'm wrong on that I would love to know - I work on an app myself which does something similar (manually calls finish() the bottom-most activity in the stack when closed via the back button).
Might be the empty Intent you return via setResult(). Have you tried null here, instead?

Android system stops application when launching Media Intent

I am launching a media intent to take a photo. After the user took a picture and gets back to the previous activity the whole application has restarted.
As this doesn't happen all the time, I think my application goes to the background and android kills it when the device has low memory.
Is there any way to keep my application from going to the background?
Thanks!
This is normal behavior in Android, all activities currently not visible on screen (after onStop) can be killed without notice (i.e. onDestory) if the system has low memory.
This usually happens to our app on one of our test devices which has memory issues regardless of our app.
You can usually recreate this behavior when you open the camera via the intent, and then rotate the device (portrait to landscape), this will also kill and re-create your app.
To solve this you need to extend onSaveInstanceState and use the savedInstanceState parameter in your onCreate to pass from your killed instance to your new instance some important information (like "we're in the middle of getting a pic from the camera").
I can think of two possibilities...
It's not killing the activity, but the intent launches a new activity. You can stop this by putting a tag in your manifest.xml as an attribute in the activity tag like this:
<activity
android:name=".nameOfActivity"
android:launchMode="singleTop" />
Make sure that the media intent is under the activity to handle the photo, and not a main/launcher activity.
IMO two options:
Implement onSaveInstanceState/onRestoreInstanceState
or
Make your activity a service.
I faced this issue and got a solution after R&D for it.
Set Target Android 4.0 and then add this line in AndroidManifest.xml of activity:
android:configChanges="screenLayout|uiMode|orientation|screenSize|smallestScreenSize"
It works for me.
When you start media intent use following method instead of startActivity(intent)
startActivityForResult(intent, REQUEST_CODE); //private int REQUEST_CODE = 232
When the started activity finishes, your calling activity will be started. You need to handle this using following function
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
//Perform your task
}
}
The activity started need to override follwoing method
#Override
public void onBackPressed() {
Intent intent = new Intent();
setResult(REQUEST_CODE, intent);
super.onBackPressed();
}
startActivityForResult() is an special way for starting activity for a specific task and get the desired result. The called activity will send the data back.
You can use the method putExtra() & getExtra in intent to send and receive data between two activity.
This will solve your problem hopefully.
If you have doubts comment. And if possible share your code so it can be more clear.

Categories

Resources