I am super beginner. Now I am try to make Android notification using NotificationListenerService.
Problem:
[A]application don't post notification but I can get to check (A)application debuglog in logcat .
I want to automatically post notification as [B]application when [A] post notification .
(I am making [B]application. )
Now:
I can get [A]application package name when it post. And then ...stop , how can I post notification(id & package name) from [B]application? use broadcastreceiver?
NotificationService.java
package com.testnotification;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
public class NotificationService extends NotificationListenerService {
private String TAG = "Notification";
private String Sample = "com.notification.sample"; ///this is [A]application
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
String packagename = sbn.getPackageName();
if(packagename.equals(Sample)){
showLog(sbn);
}
}
private void showLog( StatusBarNotification sbn ){
int id = sbn.getId();
String name = sbn.getPackageName();
Log.d(TAG,"id:" + id +
" name:" + name);
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.testnotification">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Testnotification">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".NotificationService"
android:label="#string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:exported="true">
<intent-filter>
<action android:name=
"android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java(empty yet)
Please teach me.
Have you checked if the user granted your app permission for notification listener
/**
* Is Notification Service Enabled.
* Verifies if the notification listener service is enabled.
* Got it from: https://github.com/kpbird/NotificationListenerService-Example/blob/master/NLSExample/src/main/java/com/kpbird/nlsexample/NLService.java
* #return True if enabled, false otherwise.
*/
private boolean isNotificationServiceEnabled(){
String pkgName = getPackageName();
final String flat = Settings.Secure.getString(getContentResolver(),
ENABLED_NOTIFICATION_LISTENERS);
if (!TextUtils.isEmpty(flat)) {
final String[] names = flat.split(":");
for (int i = 0; i < names.length; i++) {
final ComponentName cn = ComponentName.unflattenFromString(names[i]);
if (cn != null) {
if (TextUtils.equals(pkgName, cn.getPackageName())) {
return true;
}
}
}
}
return false;
}
if you don't have permission you can open settings app for user to enable permission
/**
* Build Notification Listener Alert Dialog.
* Builds the alert dialog that pops up if the user has not turned
* the Notification Listener Service on yet.
* #return An alert dialog which leads to the notification enabling screen
*/
private AlertDialog buildNotificationServiceAlertDialog(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(R.string.notification_listener_service);
alertDialogBuilder.setMessage(R.string.notification_listener_service_explanation);
alertDialogBuilder.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
}
});
alertDialogBuilder.setNegativeButton(R.string.no,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// If you choose to not enable the notification listener
// the app. will not work as expected
}
});
return(alertDialogBuilder.create());
}
Here is complete project for notification listener I found in GitHub
https://github.com/Chagall/notification-listener-service-example
Related
I am still new to Android development, but I’m creating an app that sendings an HTTP request when it receives a broadcast (from a barcode scan). I have tried to implement some other solutions that I read on here but haven't quite figured it out yet. It would be great if someone could help me get going in the right direction.
Essentially, the end goal is for the app to keep running in the background forever so that even if the app is not open and a barcode is scanned and sent to the app via broadcast signal, the HTTP request is still sent.
This is what I have so far:
MainActivity.java
public class MainActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
public static final String BARCODE_BROADCAST = "...";
private final BarcodeReceiver barcodeReceiver = new BarcodeReceiver();
private TextView mTextView;
private String scannedBarcode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.barcode);
}
#Override
public void onResume() {
super.onResume();
registerBarcodeScanner();
}
#Override
public void onPause() {
super.onPause();
unregisterBarcodeScanner();
// this code needs to keep the app running
Intent restartService = new Intent("RestartService");
this.startService(restartService);
sendBroadcast(restartService);
}
public void onDestroy() {
super.onDestroy();
// this code needs to keep the app running
Intent restartService = new Intent("RestartService");
this.startService(restartService);
sendBroadcast(restartService);
}
private void registerBarcodeScanner() {
registerReceiver(barcodeReceiver, new IntentFilter(BARCODE_BROADCAST));
}
private void unregisterBarcodeScanner() {
unregisterReceiver(barcodeReceiver);
}
private void displayBarcode() {
if (scannedBarcode == null) return;
String text = getString(R.string.barcode_scanned, scannedBarcode);
mTextView.setText(text);
/* SEND HTTP REQUEST */
}
private class BarcodeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BARCODE_BROADCAST)) {
String barcode = intent.getStringExtra("Barcode");
if (barcode != null) {
scannedBarcode = barcode;
displayBarcode();
}
}
}
}
}
RestartService.java
public class RestartService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MainActivity.class));
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="..."
android:versionCode="1">
<uses-sdk android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
tools:replace="android:label">
<activity
android:name="...MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="...RestartService"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="RestartService" />
</intent-filter>
</receiver>
</application>
</manifest>
I am trying to send string from app to app.
First app called "send" has only "MainActivity" class and layout:
private void sendMsg(){
final TextView msg = (TextView) findViewById(R.id.sendText);
Button snd = (Button)findViewById(R.id.sendButton);
snd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!msg.getText().toString().trim().equals("")){
Intent intent = new Intent("Updated");
intent.setAction(Intent.ACTION_SEND);
intent.putExtra("TEXT", msg.getText().toString().trim());
intent.setType("text/plain");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setComponent(new ComponentName("com.example.rec","com.example.rec.broadcastReciver"));
getApplicationContext().sendBroadcast(intent);
}else{
Toast.makeText(getApplicationContext(), "Write text that You want to broadcast!", Toast.LENGTH_LONG).show();
}
}
});
}
Second app called "rec" has two classes "broadcastReciver" and "MainActivity".
MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
zoviBroadCast();
}
private void zoviBroadCast(){
broadcastReciver brcv = new broadcastReciver();
registerReceiver(brcv,
new IntentFilter("action"));
}
}
broadcastReciver:
public class broadcastReciver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent)
{
//String data = intent.getStringExtra("TEXT").trim();
if (intent != null)
{
String sIntentAction = intent.getAction();
if (sIntentAction != null && sIntentAction.equals("action"))
{
String data = intent.getStringExtra("TEXT").trim();
Toast.makeText(context, data, Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(context,"Something went wrong",Toast.LENGTH_SHORT).show();
}
}
}
}
I also added lines between tag "receiver" in "AndroidManifest.xml":
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rec">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".broadcastReciver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="action" />
</intent-filter>
</receiver>
</application>
</manifest>
What application should do is when I type something in first application and send it another over button it should "broadcast" (show) toast at second app.
My second application is not showing any data when run.
Nowadays it is essential to specify an action in intent filter of your broadcast receiver.
<receiver android:name="MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.MY_ACTION">
</action>
</intent-filter>
</receiver>
When sending the broadcast, you need to set exactly the same action to the intent you send.
Intent i = new Intent();
i.setAction("android.intent.action.MY_ACTION");
context.sendBroadcast(i);
Notation of action name may be not very important to get your code working, but I recommend to give names related to the package of your sending app.
For example: "com.username.example.myApplication.ACTION_EXAMPLE"
I am fairly new to android. I am trying to send data from my tablet to my phone using a WearableListenerService. This part works well, I can see through logs that the data is sent. The problem is that I receive the data from the tablet in the Listener class and I have to transmit it to Mainactivity in order to update my Views. To do this I use a LocalBroadcaster and I implemented the onReceive method in my MainActivity. So when I give the order to send the data from the phone the onReceive gets called multiple time most of the time between 2 or 3 times and furthermore the activity is recreated because onCreate is triggered by this method (I don't know if this behavior is expected).
Here is the code:
DataLayerListenerService.java (Listener)
public class DataLayerListenerService extends WearableListenerService {
// Tag for Logcat
private static final String TAG = "DataLayerService";
private int notificationId = 001;
private String notif;
// Member for the Wear API handle
GoogleApiClient mGoogleApiClient;
#Override
public void onCreate() {
super.onCreate();
// Start the Wear API connection
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
}
//#Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.v(TAG, "onDataChanged: " + dataEvents);
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
Log.e(TAG, "DataItem Changed: " + event.getDataItem().toString() + "\n"
+ DataMapItem.fromDataItem(event.getDataItem()).getDataMap());
String path = event.getDataItem().getUri().getPath();
switch (path) {
case DataLayerCommons.NOTIFICATION_PATH:
Log.v(TAG, "Data Changed for NOTIF_PATH: " + event.getDataItem().toString());
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
notif = dataMapItem.getDataMap().getString(DataLayerCommons.NOTIFICATION_KEY);
Intent intent = new Intent(NOTIFICATION_RECEIVED);
intent.putExtra(NOTIFICATION_RECEIVED, notif);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
break;
case DataLayerCommons.COUNT_PATH:
Log.v(TAG, "Data Changed for COUNT_PATH: " + event.getDataItem() + "\n"
+ "Count data = " + DataMapItem.fromDataItem(event.getDataItem())
.getDataMap().getInt(DataLayerCommons.COUNT_KEY));
break;
default:
Log.v(TAG, "Data Changed for unrecognized path: " + path);
break;
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
Log.v(TAG, "DataItem Deleted: " + event.getDataItem().toString());
}
}
}
}
Main Activity
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final String NOTIFICATION_RECEIVED = "NOTIFICATION_RECEIVED";
private String notif="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG,"OnCreate");
setContentView(R.layout.main_activity);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter(NOTIFICATION_RECEIVED));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "Got message!");
notif = intent.getStringExtra(NOTIFICATION_RECEIVED);
TextView warnView = findViewById(R.id.warningView);
warnView.setText(notif);
}
};
}
AndroidManifest.xml
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat">
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="false" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service android:name=".DataLayerListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<data
android:host="*"
android:pathPrefix="/notification"
android:scheme="wear" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/start-activity"
android:scheme="wear" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.example.android.wearable.datalayer.EXAMPLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Thanks for the help
I would suggest using Application class to store your Activity instead of BroadcastReceiver registering.
What I mean:
in Application class create a variable that stores your activity:
class MyApp extends Application {
public static MyActivity activity;
}
to link save into this variable current activity at onCreate and release while onDestroy.
Somehow:
public MyActivity extends Activity {
void onCreate() {
MyApp.activity = this;
}
void onDestroy() {
MyApp.activity = null;
}
void redraw() {
//redraw
}
}
inside the service do something like this:
class MyService extends WearableListenerService {
void onDataChanged() {
if (MyApp.activity != null) {
MyApp.activity.redraw()
}
}
}
do not forget to set application in the manifest:
<application
android:name=".MyApp"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat">
I'm trying to read USSD response to get Sim balance amount etc, and I'm having issues, I have been reading many questions related to that on Stackoverflow, nothing has worked so far. Except for this that came close: Prevent USSD dialog and read USSD response?. by #HenBoy331
But i'm still having issues with it. My broadcast receiver doesn't get called too. I'm using 4.4.2
But it shows nothing. I can't seem to parse the message and get the balance.
I have a MainActivity to make the phone call, ReceiverActivity to implement broadcast receiver, USSDService class to get the USSD response.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, USSDService.class));
dailNumber("100");
}
private void dailNumber(String code) {
String ussdCode = "*" + code + Uri.encode("#");
startActivity(new Intent("android.intent.action.CALL", Uri.parse("tel:" + ussdCode)));
}
}
RecieverActivity.java
public class RecieverActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter("com.times.ussd.action.REFRESH");
this.registerReceiver(new Receiver(), filter);
}
public class Receiver extends BroadcastReceiver {
private String TAG = "XXXX";
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");
Log.i(TAG, "Got message: " + message);
}
}
}
USSDService.java
public class USSDService extends AccessibilityService {
public String TAG = "XXXX";
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, "onAccessibilityEvent");
AccessibilityNodeInfo source = event.getSource();
/* if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && !event.getClassName().equals("android.app.AlertDialog")) { // android.app.AlertDialog is the standard but not for all phones */
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && !String.valueOf(event.getClassName()).contains("AlertDialog")) {
return;
}
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED && (source == null || !source.getClassName().equals("android.widget.TextView"))) {
return;
}
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED && TextUtils.isEmpty(source.getText())) {
return;
}
List<CharSequence> eventText;
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
eventText = event.getText();
} else {
eventText = Collections.singletonList(source.getText());
}
String text = processUSSDText(eventText);
if( TextUtils.isEmpty(text) ) return;
// Close dialog
performGlobalAction(GLOBAL_ACTION_BACK); // This works on 4.1+ only
Log.d(TAG, text);
// Handle USSD response here
Intent intent = new Intent("com.times.ussd.action.REFRESH");
intent.putExtra("message", text);
sendBroadcast(intent);
}
private String processUSSDText(List<CharSequence> eventText) {
for (CharSequence s : eventText) {
String text = String.valueOf(s);
// Return text if text is the expected ussd response
if( true ) {
return text;
}
}
return null;
}
#Override
public void onInterrupt() {
}
#Override
protected void onServiceConnected() {
super.onServiceConnected();
Log.d(TAG, "onServiceConnected");
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.flags = AccessibilityServiceInfo.DEFAULT;
info.packageNames = new String[]{"com.android.phone"};
info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED | AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
setServiceInfo(info);
}
}
AndroidManifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dialussd">
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".services.USSDService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="#xml/config_service" />
</service>
<receiver android:name=".RecieverActivity$Receiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Please, is there any way i'm implementing this wrongly, Or perhaps there is a new way to get USSD responses which works?
After the launch, change the settings manually
Setting->Accessibility Setting -> You can see a option 'your app name'. Turn it on. (This has to be done from as a part of application flow(not manual))
instead of using broadcast receiver use these two lines of code in
add this code in MainActivity
public static void setTextViewToModify(String Text) {
textView.setText(Text);}
and add this in service class with in onAccessibityEvent
MainActivity.setTextViewToModify(text);
I'm trying to get the RemoteControlClient set up so my app's music can be controlled by the widget that pops up on the lock screen (like SoundCloud, Google Play Music, and other music/video apps work). I'm not sure what's wrong with my code and why it isn't correctly hooking, but here's what I have so far...
A class called MusicService that tries to handle the updates to the RemoteControlClient
public class MusicService extends Service
{
public static final String ACTION_PLAY = "com.stfi.music.action.PLAY";
private RemoteController controller = null;
#Override
public void onCreate()
{
super.onCreate();
System.out.println("Creating the service.");
if(controller == null)
{
controller = new RemoteController();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
String action = intent.getAction();
System.out.println("Got an action of " + action);
/* Logic to get my Song cur */
controller.register(this);
controller.updateMetaData(cur);
return START_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
System.out.println("Destorying MusicService");
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
This uses a class I have called RemoteController which houses my RemoteControlClient.
public class RemoteController {
private RemoteControlClient remoteControlClient;
private Bitmap dummyAlbumArt;
public void register(Context context)
{
if (remoteControlClient == null)
{
System.out.println("Trying to register it.");
dummyAlbumArt = BitmapFactory.decodeResource(context.getResources(), R.drawable.dummy_album_art);
AudioManager audioManager = (AudioManager) context.getSystemService(context.AUDIO_SERVICE);
ComponentName myEventReceiver = new ComponentName(context.getPackageName(), MediaButtonReceiver.class.getName());
audioManager.registerMediaButtonEventReceiver(myEventReceiver);
// build the PendingIntent for the remote control client
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(myEventReceiver);
// create and register the remote control client
PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(context, 0, mediaButtonIntent, 0);
remoteControlClient = new RemoteControlClient(mediaPendingIntent);
remoteControlClient.setTransportControlFlags(RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
| RemoteControlClient.FLAG_KEY_MEDIA_NEXT
| RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS
| RemoteControlClient.FLAG_KEY_MEDIA_PLAY
| RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
);
audioManager.registerRemoteControlClient(remoteControlClient);
}
}
/**
* Update the state of the remote control.
*/
public void updateState(boolean isPlaying)
{
if(remoteControlClient != null)
{
if (isPlaying)
{
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
}
else
{
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
}
}
}
/**
* Updates the state of the remote control to "stopped".
*/
public void stop()
{
if (remoteControlClient != null)
{
remoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
}
}
public void updateMetaData(Song song)
{
if (remoteControlClient != null && song != null)
{
System.out.println("Updating metadata");
MetadataEditor editor = remoteControlClient.editMetadata(true);
editor.putBitmap(MetadataEditor.BITMAP_KEY_ARTWORK, dummyAlbumArt);
editor.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, (long)1000);
editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, "Artist");
editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, "Title");
editor.apply();
updateState(true);
}
}
/**
* Release the remote control.
*/
public void release() {
remoteControlClient = null;
}
}
Every time I want to update the widget, I call startService(new Intent(MusicService.ACTION_PLAY));. It looks like it correctly creates the service, and it always gets to the point where it says "Updating metadata", but for some reason when I lock my screen and unlock it, I don't see any widget on my lock screen.
Below is the important parts of my manifest as well, seeing as that could somehow cause the issue...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stfi"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:hardwareAccelerated="true"
android:allowBackup="true"
android:icon="#drawable/stfi"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/MyActionBarTheme" >
<meta-data
android:name="android.app.default_searchable"
android:value=".activities.SearchActivity" />
<activity
android:name=".StartingToFeelIt"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
...other activities listed
<service
android:name=".helpers.MyNotificationService"
android:enabled="true"
android:label="MyNotificationServiceLabel" >
</service>
<service
android:name=".music.MusicService"
android:exported="false" >
<intent-filter>
<action android:name="com.stfi.music.action.PLAY" />
</intent-filter>
<intent-filter>
<action android:name="com.example.android.musicplayer.action.URL" />
<data android:scheme="http" />
</intent-filter>
</service>
<receiver
android:name=".music.MediaButtonReceiver"
android:exported="false" >
</receiver>
</application>
Right now my MediaButtonReceiver doesn't really do much of anything. I'm just trying to get the hooks set up. If you want, this is my MediaButtonReceiver class...
public class MediaButtonReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
System.out.println("Receiving something.");
if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON))
{
final KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event != null && event.getAction() == KeyEvent.ACTION_UP)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)
{
System.out.println("You clicked pause.");
}
else if(event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY)
{
System.out.println("You clicked play.");
}
else if (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_NEXT)
{
System.out.println("You clicked next.");
}
else if (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PREVIOUS)
{
System.out.println("You clicked previous.");
}
}
}
}
}
if you can't see remoteControlClient on lock screen you must implement audio focus. You can look here