I am using Android's Administration API and have a DeviceAdminReceiver, and override the following functions:
#Override
public void onEnabled(Context context, Intent intent)
{
System.out.println("Admin On======================");
}
#Override
public void onDisabled(Context context, Intent intent)
{
System.out.println("Admin Off======================");
}
#Override
public void onPasswordFailed(Context context, Intent intent)
{
System.out.println("PW Bad============================");
}
#Override
public void onPasswordSucceeded(Context context, Intent intent)
{
System.out.println("PW Good===========================");
}
#Override
public void onPasswordChanged(Context context, Intent intent)
{
System.out.println("Changed PW=======================");
}
On enabled, Disabled, and PW changed work, however password failed and succeeded do not. Strangely, they randomly work once in a while and then stop working. Is there anything wrong with my code, or could this be an API problem?
The receiver in AndroidMaifest
<receiver android:name="AdminReciever"
android:label="Administration"
android:permission="android.permission.BIND_DEVICE_ADMIN" android:enabled="true">
<meta-data android:name="android.app.device_admin"
android:resource="#xml/adminpolicies" />
<intent-filter>
<action android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED"/>
<action android:name="android.app.action.ACTION_PASSWORD_FAILED"></action>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"></action>
<action android:name="android.app.action.ACTION_PASSWORD_CHANGED"></action>
</intent-filter>
</receiver>
FIXED
Found out the problem, it seems this wasn't documented. I had set a minimum password length with dpm.setPasswordMinimumLength(). The password entry activity does not fire a PASSWORD_FAILED intent if the password entered is less then the minimum length. Also PASSWORD_SUCCEEDED only fires if a bad password (PASSWORD_FAILED fired) was entered before the successful one. So two successful passwords in a row will not fire the second intent.
Very late answer here but I was having the same issue and your 'Fixed' edit helped me work out why.
As you say, this isn't very well documented at all so can be quite misleading. The documentation suggests that any password failure will result in onPasswordFailed being called.
ACTION_PASSWORD_FAILED
Action sent to a device administrator when the user has entered an incorrect device or profile challenge password. You can at this point check the number of failed password attempts there have been with DevicePolicyManager.getCurrentFailedPasswordAttempts(). You will generally handle this in onPasswordFailed(Context, Intent, UserHandle).
However, that's not true. onPasswordFailed only appears to be called when the password/PIN/Pattern satisfies the Default Policy. This is different from your minimum password length.
Although I can't find any documentation stating the default policies, it appears to be 4 numbers (PIN), 4 characters (Password) or 4 points (Pattern). Anything less than these will not trigger the call.
For an example, set minimum length to 6 and set your password to 123ABC. Now try to login using the following :-
123 - onPasswordFailed is not called
123A - onPasswordFailed is called
Nice little tester project here you can try this with.
Even though you've probably well and truly moved on from this issue, someone else may gain some clarity.
Cheers.
You can make use of the android.intent.action.USER_PRESENT. This intent will be fired whenever the user unlocks the device. You can register a broadcast receiver which will capture the android.intent.action.USER_PRESENT to detect the device unlock events.
Related
I want to show the user constantly an ongoing notification that doesn't disappear when the user kills the app in the "task manager". The problem is that when this happens (the user kills the app in the "task manager") the ongoing notification disappears. As a solution, I want to resend the notification when the app gets killed by the user or from android itself. I tried to handle this with a BroadcastReciever connected with the PACKAGE_RESTARTED action (like suggested in this post), but it doesn't work (the sysout doesn't get called). Any solutions?
My BroadcastReciever:
package com.appstiq.flutter_app;
public class AutoConnection extends android.content.BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
/*This function should be called when the app is killed
so that I can resend the notification */
System.out.println("It works!");
}
}
Part of my AndroidManifest.xml:
<receiver android:name="com.appstiq.flutter_app.AutoConnection">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_RESTARTED"/>
<data android:scheme="package" android:path="com.appstiq.flutter_app"/>
</intent-filter>
</receiver>
I look forward to helpful answers :D
I'm building a wallpaper application.
I have a button which sets the wallpaper.
What I would like to do is to check if the wallpaper is downloaded, if yes set the wallpaper - if not, download and set the wallpaper.
I check if a file with an ID (e.g. 26748.jpg) exists, if yes I successfully set the wallpaper, if it doesn't exist, I download it - but I'm unable to set it.
I'm have a BroadcastReceiver set up:
<receiver android:name=".SinglePhotoActivity$CheckDownloadComplete">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
</intent-filter>
</receiver>
which displays a simple saved message:
public static class CheckDownloadComplete extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Saved!", Toast.LENGTH_SHORT).show();
}
}
The problem is that I have two types of setting the wallpaper: one if the wallpaper is already downloaded, and one if it isn't. I've done a little research and found out that broadcast receivers of this type cannot really contain any intent extras. The only thing I could do is set a description on my DownloadManager's request and then check the description in onReceive.
So, if the image is already downloaded, I'd like to display a simple Toast. If not, then download it and after, in OnReceive after the download has completed run my setWallpaper code.
Is there any more proficient way of doing this?
I host widgets in my app and it seems, that if i start my app before booting of the device is completed, widgets cannot be created properly. Widgets then seem to be not loaded completely or not initialized/updated correctly. For instance: BatteryBotIndicator-Widget, which shows the battery status in percentage, shows a value of "XX" instead of some number like "70%". If i then restart my app and try to recreate the widget with:
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
it gives me null for appWidgetInfo (i fetch appWidgetId from SQLite database). And widget cannot be recreated.
It is kind of difficult to debug the real cause in this situation to find out what is exactly causing this (Starting Debugger at the right time). I assume the AppWidgetManager is not ready yet or something.
What i can say for sure: If i wait until i receive the broadcast-event BOOT_COMPLETED all widgets are created properly.
So how can i pause the execution of onCreate until booting is completed?
I can think of putting the thread to sleep in a while loop until the BroadcastReceiver (BOOT_COMPLETED) is setting a bool-variable in application-data to true. But i dont want to wait for this event always at starting of my app, as you can imagine ;)
if i start my app before booting of the device is completed, widgets cannot be created properly.
please explain more what exactly do you mean when you say - "not properly" . this might be relevant to understand if you're widget really depends on something related to the boot.
I can think of putting the thread to sleep in a while loop until the BroadcastReceiver (BOOT_COMPLETED) is setting a bool-variable in application-data to true
very bad idea.. also from performances and design reasons
instead, why not simply register to boot complete broadcast from the manifest, and when you recevice it - simply send the relevant broadcast to update your widget? AppWidgetProvider is already extends BroadcastReceiver, so you can simply add it intent filter for boot complete broadcast.
this is how to add intent filter to boot complete:
<receiver android:name="MyWidgetProvider" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<meta-data
...
</receiver>
and this is how to react to it from the widget provider implementation:
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")){
doTheUpdateHereExactlyLikeHowYouUpdateItFromAnywhereElse();
} else {
super.onReceive(context,intent);
}
}
for more information - follow this tutorial :https://laaptu.wordpress.com/2013/08/12/android-update-app-widget-with-listview-after-phone-reboot/
I hope this is not to generic but I am developing an app for the Sony SmartWatch. When ever I make a mistake like allowing a null pointer exception. I can not get my app to restart. It's like it stays in the crashed state forever. To make the problem worse I also stop receiving messages via Logcat pertaining the app. When I uninstall and reinstall the app It's not listed in the SmartWatch app on the phone. Like it won't register. This is difficult to trouble shoot since I don't get any Log messages at this point. The only thing I can do is uninstall the app. Restart my phone. Then reinstall the app. At that point it's back to normal and I can start writing code again. So that brings me to my questions.
Is there a better way to re-register a control?
Will this happen to end users? If the app crashes will they need to uninstall, reboot and install to recover?
Some Detail (names have been changed to protect the inocent):
I have created a Broadcast Reciever and in my mainfest set it to listen for these broadcasts.
<receiver android:name=".MyExtensionReceiver" >
<intent-filter>
<!-- Receiver intents -->
<action android:name="com.sonyericsson.extras.liveware.aef.registration.EXTENSION_REGISTER_REQUEST" />
<action android:name="com.sonyericsson.extras.liveware.aef.registration.ACCESSORY_CONNECTION" />
<!-- Control intents -->
<action android:name="com.sonyericsson.extras.aef.control.START" />
<action android:name="com.sonyericsson.extras.aef.control.STOP" />
<action android:name="com.sonyericsson.extras.aef.control.PAUSE" />
<action android:name="com.sonyericsson.extras.aef.control.RESUME" />
<action android:name="com.sonyericsson.extras.aef.control.ERROR" />
<action android:name="com.sonyericsson.extras.aef.control.TOUCH_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.SWIPE_EVENT" />
</intent-filter>
Code for MyExtensionReceiver:
public class MyExtensionReceiver extends BroadcastReceiver {
public MyExtensionReceiver() {
super();
Log.d("mytag", "MyExtensionReceiver Loaded");
Dbg.setLogTag("mytag");
}
#Override
public void onReceive(Context context, Intent intent) {
Log.d("mytag", "onReceive: " + intent.getAction());
intent.setClass(context, MyExtensionReceiver.class);
context.startService(intent);
}
}
Even if my app is crashing I should still get a log message when onReceive is called. It's like the EXTENSION_REGISTER_REQUEST broadcast never gets sent. I just keep uninstalling rebooting and reinstalling over and over. Eventually the app gets found by the SmartConnect App.
It doesn't seem to have anything to do with the BroadcastReceiver. Without using one, I'm having the same annoying problem. I need to restart the phone in order to get things running normal again, as neither disabling/enabling the app helps a bit, nor killing the SmartWatch phone app (as I see no other way to restart it).
I would also appreciate some help from Sony on this matter.
Just came across this issue, giving some grey!! To work around this issue, just create a new intent using string and launch that with context.
Intent intent = new Intent("MY.PACKAGE.NAME.MyExtensionReceiver");
context.startService(intent);
I don't know why, but my battery broadcast receiver doesn't work.
AndroidManifest.xml
<receiver android:name=".BatteryReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
<action android:name="android.intent.action.BATTERY_LOW" />
</intent-filter>
</receiver>
BatteryReceiver.java
public class BatteryReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
int level = intent.getIntExtra( "level", 0 );
Log.d("Battery", "level: "+level);
Toast.makeText(context, "Battery low!", Toast.LENGTH_LONG).show();
}
}
What is wrong with my code?
I'm using console (telnet) to change battery level (power capacity X).
There are several issues; I've ordered them roughly by decreasing severity:
You can't register for ACTION_BATTERY_CHANGED from your Manifest; you must register for it programmatically.
Don't use the BATTERY_STATS permission; it's completely unrelated.
If you're receiving more than one Broadcast in the same BroadcastReceiver (and it's generally a good idea even if you're not) you should check to see which Broadcast you've just received. ACTION_BATTERY_LOW should not be treated in the same way as ACTION_BATTERY_CHANGED. (For one thing, it doesn't have the BatteryManager.EXTRA_LEVEL Extra attached to it, so trying to read it will give you your default value, 0.)
You should use -1 as your default value, not a valid value like 0.
You should check to see if you've received the default value and handle it appropriately.
You should use BatteryManager.EXTRA_LEVEL rather than hard-coding "level".