Unable to receive BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED broadcast - java

Background :
Developing application to make android phone A2DP receiver.
BlueDroid stack supports A2DP sink, but it's disabled by default.
Modified source code to enable A2DP. Android phone is seen as HeadsFree Device and is connectable.
Problem :
I can't hear sound.
Tried :
A2dpSinkStateMachine class is in charge of acting android as A2dpSink. One of the state is Connected, it has method broadcastAudioState, which is called when audio starts/stops streaming. (line 579)
broadcastAudioState sends broadcast with action BluetoothA2dpSink.ACTION_PLAYING_STATE_CHANGED (line 696) and writes log A2DP Playing state....))
Registered broadcast receiver
- tried via manifest.xml file
<receiver android:name=".PlayingStateChangeBroadcastReceiver">
<intent-filter>
<action android:name="android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED" />
</intent-filter>
</receiver>
- dynamically too
Intent intent =
registerReceiver(mReceiver, new IntentFilter(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED));
- dynamically with permission
Intent intent =
registerReceiver(
mReceiver,
new IntentFilter(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED),
"android.permission.BLUETOOTH",
new Handler(Looper.getMainLooper()));
onReceive method is never called.
Additionally:
while registering dynamically registerReceiver returns null.
inside Android monitor window, i see log A2DP Playing state ..., meaning broadcast is sent.
android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED is declared as <protected-broadcast> in platform/frameworks/base/core/res/AndroidManifest.xml file
Any ideas, how to fix that ?
Thanks

Related

my app doesn't send any notifications when it's not running (killed)

I have a reminder app that sends a notification according to the time of the item in the listview, the problem is that whenever my phone is rebooted or the app is killed, the app doesn't send any notification.
Note: The app is offline and local, it doesn't use internet connection, I don't use FCM or and online services for this app.
Thank you so much for your time.
Update:
I'm using a thread that searches for data in the local database, If there are any changes in time in the database compared to the current time, the notification should show, but the notification only shows when the app is running, but when the app is killed it doesn't show.
The app needs to run on android 5+,
You can use Broadcast receiver in order to be notified when Boot Completes. And again start the required services of your app.
For reference, have a look here.
This is because when you are killing the app, the onDestroy method gets called. When it's killed, you app is not doing anything. For this you would need a broadcast receiver.
How to implement broadcast receiver?
Create a java class named TimeBradcastReceiver.java.
Paste this code in the class
public class TimeBradcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String dateString = Calendar.getInstance().get(Calendar.HOUR) + ":" + Calendar.getInstance().get(Calendar.MINUTE);
String hourString = Calendar.getInstance().get(Calendar.HOUR);
String minutesString = Calendar.getInstance().get(Calendar.MINUTE;
Log.d("MyBradcastReceiver","i have recieved - " + dateString);
}
}
Once you have implemented this code, you need to add this to you manifest inside the application tag.
<receiver android:name="com.chatverse.free.TimeBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.TIME_TICK"/>
</intent-filter>
</receiver>
Add this code to your activity which opens the first.
IntentFilter mTime = new IntentFilter(Intent.ACTION_TIME_TICK);
registerReceiver(new TimeBradcastReceiver(), mTime);
Now you can do the comparison of the dates and hours and show the notification.
Note - This receiver will update only when a minute has changed.

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.

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/

Broadcast Receiver not receiving BOOT and MEDIA_MOUNTED intent

I'm trying to create a simple BroadcastReceiver that can receive the android.intent.action.BOOT_COMPLETED intent as well as the android.intent.action.MEDIA_MOUNTED intent. The idea is to start a service on receiving either of these intents. Thus the service should be started after Android boot is complete or when an USB storage device is connected to the Android target(if the service is not already started by then).
Permissions used by the application are defined in this section
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
The following section defines the BroadcastReceiver responsible for handling the intents and starting the corresponding service.
<receiver
android:name="com.example.systemupgradeapplication.IntentReceiver"
android:label="USB Detection Receiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_REMOVED" />
<action android:name="android.intent.action.MEDIA_EJECT" />
<action android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<data android:scheme="file" />
</intent-filter>
<intent-filter android:priority="999" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
The corresponding service that should be started from the Broadcast Receiver is defined in the following section
<service android:name=".SysUpgradeService" />
Note: The receiver and service components are defined within the <application> section of the Android Manifest.
The following snippet is the Class responsible for handling the intents broadcasted
public class IntentReceiver extends BroadcastReceiver {
private final static String TAG = "IntentReceiver";
private static boolean m_UsbInserted = false;
private static boolean m_UsbRemoved = true;
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "LaunchReceiver::ACTION_MEDIA_MOUNTED :: intent received with path= ");
// TODO Auto-generated method stub
//if(intent.)
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
String path = intent.getDataString();
if(path.contains("usb")) {
m_UsbInserted = true;
Log.d(TAG, "LaunchReceiver::ACTION_MEDIA_MOUNTED :: intent received with path= "+path);
Intent myIntent = new Intent(context, SysUpgradeService.class);
myIntent.putExtra("path", path);
context.startService(myIntent);
}
}else if(action.equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.d(TAG, "BOOT Completed intent received");
context.startService(new Intent(context, SysUpgradeService.class));
}
The problem I am facing is that none of the intents are arriving at my broadcast receiver(None of the Logs in the IntentReceiver class are being printed in logcat) even though I can see in the Android Debug logs that the BOOT_COMPLETE and MEDIA_MOUNTED intents are being broadcast. Also This application is not starting after android system is booting up.
I appreciate your help in this regard, what may be wrong with my approach and some possible solutions.
Okay, so I pushed the apk to /system/priv-app which is where System Applications which are part of custom ROM are placed. Now I do not need any activity in my application since it is part of the custom ROM and is recognized as a system application. It seems that if your application is a 3rd party application it must have an activity to be able to receive broadcasted intents.
However in this case I have control over the custom ROM source code as well as root access on the device. So both the approaches work
Make your application part of the custom ROM source, build and flash on device.
Get root access on device, push your apk to /system/priv-app (4.4 onwards), reboot and voila!
Make Sure you have atleat one activity present in your Application.From Android 3.1, BroadcastReceiver will not work until the user has manually launched an activity, This is for provide security . once the user runs the app for the first time then your BroadcastReceiver will run always except it does not Force Stop it. Once activity launch at first time your broadcast receiver will run even after reboot your deice.

Android: Receive silent sms?

I am currently coding an SMS-controlled GPS Tracker.
Every time I send an SMS to the device it's handled like a normal sms (new message in inbox and notification), but these sms are just to control the app.
Is is possible to turn off notifications for these sms? I also don't want all these sms in my inbox folder...
Create your Broadcast Receiver for Receiving SMS.
Set Intent Filter with highest priority.
<intent-filter android:priority="100">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
In your receiver class, abortBroadcast() method, which will not notify for SMS.
And delete the currently received message.
yes this is possible you need to use this method into the broadcast receiver at last
abortBroadcast();
This will cancel the broadcasting to the user.

Categories