Intent extra on WallpaperManager's broadcast receiver - java

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?

Related

Run function when app is closed - Android

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

Equalizing the audio of another app - how to?

i need to make a Equalizer for Android.
El audio session ID 0 is deprecated.
Is there a way to get the current audio session ID?
I want to equalize from my app the sound of other apps.
In Google play there are other apps that use the "compatibility mode". but i do not know how they do it. For example, the app detects that spotify is playing, the session is selected and it can equalized.
Does anyone know how do this?
Thanks.
Example applications:
https://play.google.com/store/apps/details?id=com.devdnua.equalizer.free
https://play.google.com/store/apps/details?id=devdnua.equalizerp.free
According to Android, you can use ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION to receive the id of a playing audio session:
Intent to signal to the effect control application or service that a new audio session is opened and requires audio effects to be applied.
I tried adding the constant (and many others) in the manifest, but it only worked for music apps such as Spotify and Youtube Music:
<receiver android:name=".receivers.AudioSessionReceiver">
<intent-filter>
<action android:name="android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION"/>
</intent-filter>
</receiver>
Then, you can use the id to create an equalizer attached to the session id.
public class AudioSessionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int id = intent.getIntExtra(Equalizer.EXTRA_AUDIO_SESSION, -1);
String packageName = intent.getStringExtra(Equalizer.EXTRA_PACKAGE_NAME);
}
}
When I play my own media file (with my own test app), there are equalizer apps that still work on it even though I didn't broadcast the session id of my media player. So there must be a solution involving a Service that doesn't rely on Broadcast Receivers.

Launching an Activity with no UI which starts a service and finishes, but don't want to interrupt the currently running app

this is more of a style question. Right now, due to Android limitations, in order to get the functionality I am going after, I have to receive an intent with an activity which launches with no UI and doesn't render, starts a service with the intent, and then immediately finishes. However, apps vary in how they react to this launching of another activity. For example, YouTube videos pause. Is there any way I can launch this wrapper activity with as little impact on the app that is currently running as possible?
You must use BroadcastReciever. Here you can find a good tutorial about it.
Put it in you Manifest
<receiver android:name=".AutoStart ">
<intent-filter>
<action android:name="com.tutorialspoint.CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
Extend BroadcastReceiver
public class AutoStart extends BroadcastReceiver
{
#Override
public void onReceive(Context arg0, Intent arg1)
{
Log.d("AutoStart","Broadcast received");
Intent intent = new Intent(arg0,YourService.class);
arg0.startService(intent);
}
}
and Finally you can send a broadcast like this:
Intent intent = new Intent();
intent.setAction("com.tutorialspoint.CUSTOM_INTENT");
sendBroadcast(intent);

How to pause onCreate until boot completed?

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/

Having trouble receiving ACTION_PASSWORD_SUCCEEDED and ACTION_PASSWORD_FAILED intents

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.

Categories