I've followed instructions on this page until "Preparing your code for Android 2.2 without restricting it to Android 2.2". Even if I'm building against 2.3 version, I guess it should be working at this point but it's not. I've registered a receiver in manifest:
<receiver android:name="RemoteControlReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
created a class for RemoteControlReceiver declaration:
public class RemoteControlReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "onReceive", Toast.LENGTH_SHORT).show();
}
}
and finally boostrapped it in the starting activity.
private AudioManager _audioManager;
private ComponentName _componentName;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
_componentName = new ComponentName(getPackageName(), RemoteControlReceiver.class.getName());
}
#Override
protected void onResume() {
super.onResume();
_audioManager.registerMediaButtonEventReceiver(_componentName);
_audioManager.requestAudioFocus(new OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
Toast.makeText(getApplicationContext(), "onFocusChanged", Toast.LENGTH_SHORT).show();
}
}, AudioManager.STREAM_MUSIC, 0);
}
Could you point out what am I missing here ? I have an assumption that in order to receive thodse messages I my activity has to play any media stuff. I gonna test it right away.
P.S. As you see I've even added some uneccessary code - don't pay attention to requestAudioFocus.
Thanks for any suggestions.
Related
I am making some animation in android and I want to pause it whenever notification pops up in screen. For example sms, message from messenger, whatsApp, viber etc.
I don't need to know what is the type of notification or handle it somehow. I just need to know when it pops up so I can call my pause() method. How I can achieve this?
What you need is a notification listener service.
public class NotificationService extends NotificationListenerService {
Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
// Send a braoadcast with some data
Intent notificationMessage = new Intent("SomeData");
notificationMessage.putExtra("Hello", "World");
LocalBroadcastManager.getInstance(context).sendBroadcast(notificationMessage);
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Log.i("Msg","Notification Removed");
}
}
You can recieve the Local broadcast in you activity as follows
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("Hello");
// Do something with the data
}
}, new IntentFilter("SomeData"));
}
}
Also register the service in manifest
<service
android:name=".NotificationService"
android:label="#string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
you can find the official documentation here https://developer.android.com/reference/android/service/notification/NotificationListenerService
You can also find detailed demo here http://www.androiddevelopersolutions.com/2015/05/android-read-status-bar-notification.html
I'm trying to implement a feature which would read the notification and it seems that I've a bug in it because the onNotificationPosted() of the NotificationListenerService is never called. I configured the manifest, modified the security settings properly and even started the service manually but it did nothing. Can it be that testing it in an emulator is not the best way to proceed.
Here is the Notification getter class:
/**
* Created by laurentmeyer on 28/02/15.
*/
public class NotificationListener extends NotificationListenerService {
public NotificationListener(){
Log.d("Notification", "Created");
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Notification mNotification = sbn.getNotification();
Intent intent = new Intent("Msg");
Log.d("Notification", "Received");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
#Override
public void onCreate() {
super.onCreate();
Log.d("Notification", "created");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Notification", "destroyed");
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
}
}
(Sorry for the incorrect indentation)
This is my Fragment which should respond to the broadcasts:
public class VerificationFragment extends BaseFragment implements SMSReceivedCallbacks {
public void onNotificationReceived(int code) {
ed.setText("OK");
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(new Receiver(), new IntentFilter("Msg"));
}
// A bunch of other useless stuff
private class Receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
onNotificationReceived(0);
}
}
}
The Manifest:
<service
android:name=".NotificationListener"
android:label="#string/service_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
To summarise, I've:
02-28 11:40:53.236 6585-6585/com.******.laurentmeyer.****** D/Notificationīš Created
02-28 11:40:53.236 6585-6585/com.******.laurentmeyer.****** D/Notificationīš created
and then nothing. I already looked at all the threads on SO but maybe missing something really simple.
Enable Notification Access in your settings:
if (Settings.Secure.getString(this.getContentResolver(), "enabled_notification_listeners").contains(getApplicationContext().getPackageName())) {
//Add the code to launch the NotificationService Listener here.
} else {
//Launch notification access in the settings...
getApplicationContext().startActivity(new Intent(
"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
}
I am building a simple android application and it has two Activities and a IntentService. My IntentService plays music over every activity(thats what I want) but if I leave the app the music still plays (example: if I press the home button it will take me to the desktop, putting my activity in the onpause state but the music from that app is still playing). Any help would be appreciated....
code below
Main Activity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent serviceIntent= new Intent(this, BackgroundMusic.class);
startService(serviceIntent);
}
public void ShipPick(View view){
Intent activityIntent= new Intent(this, ShipChoiceActivity.class);
startActivity(activityIntent);
}
}
Background Music Service
public class BackgroundMusic extends IntentService {
MediaPlayer mp;
public BackgroundMusic() {
super("BackgroundMusic");
}
Handler HN = new Handler();
private class PlayMusic implements Runnable {
public void PLayMusic(){
}
public void run(){
mp = MediaPlayer.create(getApplicationContext(), R.raw.musicfile);
mp.start();
}
}
#Override
protected void onHandleIntent(Intent intent) {
HN.post(new PlayMusic());
}
public void onPause() {
mp.pause();
}
public void onResume() {
mp.start();
}
protected void onStop() {
mp.stop();
mp = null;
}
}
second activity
public class ShipChoiceActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ship_choice);
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.starwars"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:debuggable="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:name=".BackgroundMusic" />
<activity
android:name="com.example.ship.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>
<activity android:label="#string/app_name" android:name="ShipChoiceActivity"/>
</application>
</manifest>
For controlling BackgroundMusic Service from Activity you will need to use custom BroadcastReceiver to communicate with service when application is going in onpause state.
Register BroadcastReceiver In BackgroundMusic :
public class MusicServiceBroadCast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
if(<Match for action>){
if Action is for pause then call pause for MediaPlayer
}else{
if Action for Play ...
}
}
}
#Override
protected void onHandleIntent(Intent intent) {
//... Register BroadcastReceiver
registerReceiver(new MusicServiceBroadCast(), new IntentFilter(
"com.xx.PAUSE_MUSIC_ACTION"));
HN.post(new PlayMusic());
}
Send BroadcastReceiver from Activity onPause :
Intent intent = new Intent();
intent.setAction("com.xx.PAUSE_MUSIC_ACTION");
sendBroadcast(intent);
I'm trying to start a service on android in order to performe some network-related tasks in background. I have written a basic network-manager for my app, which is a service. I basically used the tutorial from the android documentation. The basic structure goes as following:
public class MyNetworkManager extends Service {
// some code
private final IBinder mBinder = (IBinder) new MyBinder();
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
MyNetworkManager getService() {
return MyNetworkManager.this;
}
}
public void onCreate() {
// some network related stuff like setting up sockets etc.
}
public void onStart(Intent intent, int startid) {
while(true) {
// receive new connections etc
}
}
The calling app/activity is then:
public class AndroidNetworkManagerClient extends Activity {
private Button buttonSend;
private EditText inputText;
private TextView outputText;
private MyNetworkManager networkManager;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
networkManager = ((MyNetworkManager.MyBinder) binder).getService();
}
public void onServiceDisconnected(ComponentName className) {
networkManager = null;
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
inputText = (EditText) findViewById(R.id.textInput);
outputText = (TextView) findViewById(R.id.textOutput);
buttonSend = (Button)this.findViewById(R.id.buttonSend);
buttonSend.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (inputText.getText().length() != 0) {
outputText.append("Out: " + inputText.getText() + "\n");
networkManager.sendData("localhost", inputText.getText().toString());
}
}
});
bindService(new Intent(this, MyNetworkManager.class), mConnection, Context.BIND_AUTO_CREATE);
doSomeAppRelatedStuff();
}
bindService() seems to be called without any problems, but the variable "networkManager" is always null! I already tried to debug into the onCreate() method or onServiceConnected() but it seems, that these parts are not reached at all (at least no breakpoint was triggered).
The service is already registered in the AndroidManifest.xml:
package="some.random.name"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".AndroidNetworkManagerClient"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyNetworkManager"></service>
</application>
Anyone an idea?
Chances are, your Activity is getting into doSomeAppRelatedStuff() and trying to use networkManager before the binding is complete.
If doSomeAppRelatedStuff() absolutely must have the network manager to function, move your call to doSomeAppRelatedStuff() into onServiceConnected() so it won't actually start until the binding is complete. Note that if you do that, your onStart() and onResume() calls will probably (but not guaranteed!) happen before the binding is complete, so program accordingly.
I've been studying from the book "Pro Android 2." I'm working through a Service example that consists of two classes: BackgroundService.java and MainActivity.java. The MainActivity claims (erroneously?) it starts the Service as indicated by output to logcat from the Log.d call below:
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "starting service");
Button bindBtn = (Button)findViewById(R.id.bindBtn);
bindBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent backgroundService = new Intent(MainActivity.this, com.marie.mainactivity.BackgroundService.class);
startService(backgroundService);
}
});
Button unbindBtn = (Button)findViewById(R.id.unbindBtn);
unbindBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
stopService(new Intent(MainActivity.this, BackgroundService.class));
}
});
}
}
What puzzles me is the UI provides two buttons: Bind and UnBind as shown above. But according to the documentation if onBind() as shown below returns null that indicates you don't want to allow binding. But as shown above the onClick() method of (the Bind button) bindBtn.setOnClickListener(new OnClickListener() calls startService(backgroundService) which gives this error:"Unable to start service Intent { cmp=com.marie.mainactivity/.BackgroundService }: not found"
public class BackgroundService extends Service {
private NotificationManager notificationMgr;
#Override
public void onCreate() {
super.onCreate();
notificationMgr = NotificationManager)getSystemService(NOTIFICATION_SERVICE);
displayNotificationMessage("starting Background Service");
Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService");
thr.start();
}
class ServiceWorker implements Runnable
{
public void run() {
// do background processing here...
//stop the service when done...
//BackgroundService.this.stopSelf();
}
}
#Override
public void onDestroy()
{
displayNotificationMessage("stopping Background Service");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void displayNotificationMessage(String message)
{
Notification notification = new Notification(R.drawable.note, message, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
notification.setLatestEventInfo(this, "Background Service", message, contentIntent);
notificationMgr.notify(R.id.app_notification_id, notification);
}
}
I don't understand the point of this example. If onBind() returns null what's the point of having a Bind button (bindBtn)? I thought the point was to show how to start a BackgroundService. But it doesn't seem to work unless I'm missing something.
I should add I have added to my AndroidManifest.xml:
<service android:name=".BackgroundService"></service>
as follows:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<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>
<service android:name=".BackgroundService"></service>
</activity>
</application>
Remove the service from inside the activity. It is at the same level as the activity within the application. Eg:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<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>
<service android:name=".BackgroundService"></service>
</application>