I am trying to create sample application in android which could access the remote service already created in android.
Below are the code of my service, it's AIDL and sample application. Please note that I am trying to run it in android emulator.
My AIDL file
// IMyAidlInterface.aidl
package com.example.mmjoshi.binderservice;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
int findFactorialService(int x);
}
My Service file
package com.example.mmjoshi.binderservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
/**
* Created by mmjoshi on 8/12/2015.
*/
public class MyService extends Service {
private final IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent)
{
//return mBinder;
return new IMyAidlInterface.Stub(){
public int findFactorialService(int x) throws RemoteException
{
int fact =1;
for(int i=1;i<=x;i++)
{
fact = fact*i;
}
return fact;
//return 5;
}
};
}
public class LocalBinder extends Binder
{
public MyService getService()
{
return MyService.this;
}
}
/*public int findFactorial(int x)
{
int fact =1;
for(int i=1;i<=x;i++)
{
fact = fact*i;
}
return fact;
//return 5;
}*/
}
Service Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mmjoshi.binderservice" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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=".MyService" android:process=":remote"
android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.example.mmjoshi.binderservice.MyService.IMyAidlInterface"></action>
</intent-filter>
</service>
</application>
</manifest>
Another application which access this service
package secondndapp.service_client;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.mmjoshi.binderservice.IMyAidlInterface;
public class MainActivity extends Activity implements View.OnClickListener {
EditText etValue1, etValue2;
Button bAdd;
ServiceConnection AddServiceConnection;
protected IMyAidlInterface iMyAidlInterface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etValue1 = (EditText)findViewById(R.id.txtinput);
bAdd = (Button)findViewById(R.id.btnCalc);
bAdd.setOnClickListener(this);
initConnection();
}
void initConnection() {
AddServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface((IBinder) service);
Toast.makeText(getApplicationContext(),
"Service Connected", Toast.LENGTH_SHORT)
.show();
Log.d("IRemote", "Binding is done - Service connected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
iMyAidlInterface = null;
Toast.makeText(getApplicationContext(), "Service Disconnected",
Toast.LENGTH_SHORT).show();
Log.d("IRemote", "Binding - Service disconnected");
}
};
if (iMyAidlInterface == null) {
Intent it = new Intent("com.example.mmjoshi.binderservice.MyService");
it.setPackage("com.example.mmjoshi");
it.setAction("com.example.mmjoshi.binderservice.MyService.IMyAidlInterface");
it.setComponent(new ComponentName("com.example.mmjoshi", "com.example.mmjoshi.binderservice.MyService"));
// binding to remote service
startService(it);
Log.d("Service-MJ","Service is going to start");
bindService(it, AddServiceConnection, Service.BIND_AUTO_CREATE);
Log.d("Service-MJ", "Service is started");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onClick(View v)
{
int num = Integer.parseInt(etValue1.getText().toString());
Toast.makeText(getApplicationContext(), "num is " + num,
Toast.LENGTH_LONG).show();
int result = 0;
try {
result = iMyAidlInterface.findFactorialService(num);
} catch (RemoteException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Result" + result,Toast.LENGTH_SHORT).show();
}
}
Now, first I run the Binder Service in emulator and then I run this application in emulator.
But I am getting this error: "java.lang.NullPointerException: Attempt to invoke interface method 'int com.example.mmjoshi.binderservice.IMyAidlInterface.findFactorialService(int)' on a null object reference"
Please help me, I am stuck with this since last 2 days.
Thanks in Advance.
Maulik
Related
I have created two different Android applications. One contains a Service and the other one the Activity which binds the Service. This works well on all devices expected one. On the problematic device runs Android 6.0.1. On all other tested devices running Android 6 there are no problems. Same for devices with newer and older versions.
With packageManager.getPackageInfo("com.example.myexampleservice", 0) I checked that the service APK is installed.
My Activity class, which binds the Service (MainActivity.java, 1. project):
package com.example.myexampleactivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
final static int MSG_SAY_HELLO = 1;
Messenger mService = null;
boolean mBound;
TextView textView;
Button button;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
mService = new Messenger(service);
mBound = true;
button.setText("Send Message");
textView.setText("Everything is fine. You can press the button to send a message.");
}
#Override
public void onServiceDisconnected(ComponentName className) {
mService = null;
mBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
textView = findViewById(R.id.text_view);
button = findViewById(R.id.button);
textView.setText("Press the button to bind the service.");
button.setText("Bind service");
}
#Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
button.setText("Bind service");
}
}
public void onClickButton(View v) {
if (!mBound) {
Intent intent = new Intent("com.example.myexampleservice.SERVICE");
intent.setPackage("com.example.myexampleservice");
if (getApplicationContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
textView.setText("Everything is fine.");
} else {
// This happens only on one device. Why???
textView.setText("bindService(...) returns false. The following message is probably shown in the logcat:\n\n" +
"I BackgroundManagerService package not in whitelist com.example.myexampleservice\n" +
"I BackgroundManagerService not whitelist service Intent { act=com.example.myexampleservice.SERVICE pkg=com.example.myexampleservice }\n" +
"I BackgroundManagerService skipService Intent { act=com.example.myexampleservice.SERVICE pkg=com.example.myexampleservice } because of activity not started!");
}
} else {
Message msg = Message.obtain(null, MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
My Service (MyExampleService.java, 2. project):
package com.example.myexampleservice;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.widget.Toast;
public class MyExampleService extends Service {
static final int MSG_SAY_HELLO = 1;
static class IncomingHandler extends Handler {
private Context applicationContext;
IncomingHandler(Context context) {
applicationContext = context.getApplicationContext();
}
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
Messenger mMessenger;
#Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
mMessenger = new Messenger(new IncomingHandler(this));
return mMessenger.getBinder();
}
}
And the AndroidManifest of the Service application (AndroidManifest, 2. project):
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myexampleservice">
<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">
<service android:name=".MyExampleService">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.example.myexampleservice.SERVICE" />
</intent-filter>
</service>
</application>
</manifest>
Only on the one device that doesn't work the method bindService(...) returns false. For this device, the Logcat shows the followoing:
I BackgroundManagerService package not in whitelist com.example.myexampleservice
I BackgroundManagerService not whitelist service Intent { act=com.example.myexampleservice.SERVICE pkg=com.example.myexampleservice }
I BackgroundManagerService skipService Intent { act=com.example.myexampleservice.SERVICE pkg=com.example.myexampleservice } because of activity not started!
I am helpless, because the application on all other devices runs without problems. The Google search does not return any results for these log messages. Has anyone seen these log messages before and knows what to do here? Does anyone have any idea how to fix this problem?
I have created a service which lives within a library. The library is then included in another project which attempts to launch the service. I am using AIDL to interact however when I attempt to connect to the service my onConnected method is never hit.
From the log files I can see the following error:
D/ActivityManager: bindService callerProcessName:com.something.services.dummyproject, calleePkgName: com.something.services.dummyproject, action: com.something.services.dummyservice.IDummyService
W/ActivityManager: Unable to start service Intent { act=com.something.services.dummyservice.IDummyService cmp=com.something.services.dummyproject/com.something.services.dummyservice.IDummyService } U=0: not found
D/ActivityManager: bindService callerProcessName:com.something.services.dummyproject, calleePkgName: com.something.services.dummyservice.service, action: null
W/ActivityManager: Unable to start service Intent { cmp=com.something.services.dummyservice.service/.DummyService } U=0: not found
The DummyService.java file is as follows:
package com.something.services.dummyservice.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.something.services.dummyservice.IDummyService;
public class DummyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IDummyService.Stub mBinder = new IDummyService.Stub() {
#Override
public String dummyHello() throws RemoteException {
return "Hello";
}
#Override
public void exit() throws RemoteException {
stopSelf();
}
};
}
The DummyService Manifest is as follows:
<?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="com.something.services.dummyservice">
<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">
<service
android:name=".services.DummyService"
android:exported="true"
android:label="#string/app_name"
tools:ignore="ExportedService" />
</application>
</manifest>
The IDummyService.aidl file is as follows:
// IDummyService.aidl
package com.something.services.dummyservice;
// Declare any non-default types here with import statements
interface IDummyService {
String dummyHello();
void exit();
}
I'm generating a .aar file with the above.
I've then included that library into my main project file.
The manifest in my main project is as follows:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.something.services.dummyproject">
<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"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
The MainActivity.java file is as follows:
package com.something.services.dummyproject;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.something.services.dummyservice.IDummyService;
import butterknife.Bind;
import butterknife.ButterKnife;
public class MainActivity extends AppCompatActivity {
private IDummyService mDummyService;
#Bind(R.id.btnStartService)
Button btnStartService;
#Bind(R.id.btnEndService)
Button btnEndService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
btnStartService.setOnClickListener(startServiceOnClickListener);
btnEndService.setOnClickListener(endServiceOnClickListener);
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
mDummyService = IDummyService.Stub.asInterface(service);
dummyHello();
}
#Override
public void onServiceDisconnected(ComponentName className) {
mDummyService = null;
}
};
private final View.OnClickListener startServiceOnClickListener = new View.OnClickListener() {
#Override
public void onClick(final View completeButton) {
Intent intent = new Intent(MainActivity.this, com.something.services.dummyservice.IDummyService.class);
intent.setAction(IDummyService.class.getName());
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
};
private final View.OnClickListener endServiceOnClickListener = new View.OnClickListener() {
#Override
public void onClick(final View completeButton) {
exitService();
}
};
private void dummyHello() {
try {
String response = mDummyService.dummyHello();
Toast.makeText(getApplicationContext(), response, Toast.LENGTH_LONG);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void exitService() {
try {
if (mDummyService != null) {
mDummyService.exit();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
The dummyProject also contains the exact same AIDL file. In both cases the AIDL file lives in an aidl folder which lives alongside the src\JAVA folder. That contains a package folder which contains the AIDL file.
Any help with identifying why I'm unable to connect to the service is very much appreciated!
I am trying to access the notifications on my android phone using the AccessibilityService.
I tried making a service and calling it from the main activity. I've also added meta for the service. It's not working. I cannot see the triggering of the service.
I'm using Android L for testing. In accessibility settings I've added my app 'Notify' as on.
Thanks in advance.
My main Activity
package com.example.tony.notify;
import android.content.Intent;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// startActivityForResult(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0);
Intent i = new Intent(this, MyAccessibilityService.class);
startService(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
This is my service class
package com.example.tony.notify;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Toast;
/**
* Created by tony on 9/7/15.
*/
public class MyAccessibilityService extends AccessibilityService {
final String TAG = "Notification service";
private String getEventType(AccessibilityEvent event) {
switch (event.getEventType()) {
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
return "TYPE_NOTIFICATION_STATE_CHANGED";
case AccessibilityEvent.TYPE_VIEW_CLICKED:
return "TYPE_VIEW_CLICKED";
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
return "TYPE_VIEW_FOCUSED";
case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:
return "TYPE_VIEW_LONG_CLICKED";
case AccessibilityEvent.TYPE_VIEW_SELECTED:
return "TYPE_VIEW_SELECTED";
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
return "TYPE_WINDOW_STATE_CHANGED";
case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
return "TYPE_VIEW_TEXT_CHANGED";
}
return "default";
}
private String getEventText(AccessibilityEvent event) {
StringBuilder sb = new StringBuilder();
for (CharSequence s : event.getText()) {
sb.append(s);
}
return sb.toString();
}
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.v(TAG, String.format(
"onAccessibilityEvent: [type] %s [class] %s [package] %s [time] %s [text] %s",
getEventType(event), event.getClassName(), event.getPackageName(),
event.getEventTime(), getEventText(event)));
}
#Override
public void onInterrupt() {
Log.v(TAG, "onInterrupt");
}
#Override
protected void onServiceConnected() {
Toast.makeText(getApplicationContext(),"connected",Toast.LENGTH_SHORT).show();
super.onServiceConnected();
Log.v(TAG, "onServiceConnected");
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.flags = AccessibilityServiceInfo.DEFAULT;
info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
setServiceInfo(info);
}
}
My manifest for declaring service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tony.notify" >
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:name=".MyAccessibilityService"
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/accessibilityservice" />
</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>
</activity>
</application>
</manifest>
Please help. Thanks in advance. I've tried looking into some examples. I couldn't find errors.
I got it working on L though, it's not really working on api 16, I tested on one. Can anyone suggest an addition to make it work on api 14+
Manifest File
package com.example.tony.acctest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.tony.acctest.MyAccessibilityService.Constants;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MA LOG";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final IntentFilter mIntentFilter = new IntentFilter(Constants.ACTION_CATCH_NOTIFICATION);
registerReceiver(NotificationCatcherReceiver, mIntentFilter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(NotificationCatcherReceiver);
}
private final BroadcastReceiver NotificationCatcherReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_PACKAGE));
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_MESSAGE));
}
};
}
My service class
package com.example.tony.acctest;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.TargetApi;
import android.app.Notification;
import android.content.Intent;
import android.os.Build;
import android.os.Parcelable;
import android.view.accessibility.AccessibilityEvent;
import java.util.List;
public class MyAccessibilityService extends AccessibilityService {
private final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
final String sourcePackageName = (String)event.getPackageName();
Parcelable parcelable = event.getParcelableData();
if (parcelable instanceof Notification) {
List<CharSequence> messages = event.getText();
if (messages.size() > 0) {
try {
final String notificationMsg = (String) messages.get(0);
Intent mIntent = new Intent(Constants.ACTION_CATCH_NOTIFICATION);
mIntent.putExtra(Constants.EXTRA_PACKAGE, sourcePackageName);
mIntent.putExtra(Constants.EXTRA_MESSAGE, notificationMsg);
MyAccessibilityService.this.getApplicationContext().sendBroadcast(mIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
#Override
public void onInterrupt() {
}
#Override
public void onServiceConnected() {
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
} else {
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
}
info.notificationTimeout = 100;
this.setServiceInfo(info);
}
public static final class Constants {
public static final String EXTRA_MESSAGE = "extra_message";
public static final String EXTRA_PACKAGE = "extra_package";
public static final String ACTION_CATCH_NOTIFICATION = "com.example.tony.acctest.CATCH_NOTIFICATION";
}
}
This is my Main activity
package com.example.tony.acctest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.tony.acctest.MyAccessibilityService.Constants;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MA LOG";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final IntentFilter mIntentFilter = new IntentFilter(Constants.ACTION_CATCH_NOTIFICATION);
registerReceiver(NotificationCatcherReceiver, mIntentFilter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(NotificationCatcherReceiver);
}
private final BroadcastReceiver NotificationCatcherReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_PACKAGE));
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_MESSAGE));
}
};
}
I had done this when my widget got enabled:
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
String enabledListeners = Settings.Secure.getString(
context.getContentResolver(), "enabled_notification_listeners");
if (!enabledListeners.contains("Myalert")) {
Intent i = new Intent(
"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
And in my manifest:
<service
android:name="com.edgealert.NotificationMonitor"
android:label="MyAlert"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" >
</action>
</intent-filter>
</service>
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="com.samsung.android.cocktail.action.COCKTAIL_UPDATE" />
</intent-filter>
<meta-data
android:name="com.samsung.android.cocktail.provider"
android:resource="#xml/single_cocktail" />
</receiver>
I am working on a larger project but have become stuck on a very simple element that is binding to an android service. My issue is that I cannot seem to bind to the service. No errors are being thrown at all when calling bindService() and I have used the internal debugger and manual tracing of print statements and I am still failing to understand what is causing this error. Any help appreciated! (This is especially irritating as it is largely C+P from the android development website yet still won't work!)
Main Activity:
package com.example.servicetest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
public class MainActivity extends Activity {
LocalService mService;
boolean mBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// START Activity
Intent intent = new Intent(this, BindingActivity.class);
startActivity(intent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Binding Activity:
package com.example.servicetest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Toast;
import com.example.servicetest.LocalService.LocalBinder;
public class BindingActivity extends Activity {
LocalService mService;
boolean mBound = false;
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
System.out.println("End onServiceConnected");
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bind);
}
#Override
protected void onStart() {
super.onStart();
// Bind to LocalService
System.out.println("onStart called");
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
this.startService(intent);
}
#Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
public void onButtonClick(View v) {
if (mBound) {
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
System.out.println("Button click");
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
System.out.println("" + num);
} else {
System.out.println("Not bound");
}
}
}
LocalService:
package com.example.servicetest;
import java.util.Random;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
System.out.println("onBind called");
return mBinder;
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
And finally the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.servicetest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.servicetest.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:name="com.example.servicetest.BindingActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
I think you need to add your service in Mainfest.xml
<service android:name="LocalService" android:enabled="true"></service>
try it and feed me back
So after 2-3 hours of failures i finally got my remote service to work somehow but it's acting real strange.
I'm using AIDL to send mediaPath string to my service and it starts playing music just fine, but the onStartCommand never gets called and the Service entry in Apps doesn't have the label/description I set in the manifest file. [http://i50.tinypic.com/344p349.png]
Also the Service terminates if I terminate the main Activity process, although it resides in a separate process. Is this how it's supposed to be? [http://i49.tinypic.com/16hpa86.png]
And I never get the "Service disconnected" Log which should happen when Service gets unbound from Activity.
Service code:
package com.example.randomserviceshitnot;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MojPrviServis extends Service {
private final Servis.Stub binder = new Servis.Stub() {
public void execute(String mediaPath) throws RemoteException {
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(mediaPath);
mp.prepare();
} catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) {
e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace(); }
mp.start();
}
};
public void onCreate() {
super.onCreate();
Log.d("Filip", "Service onCreate called.");
}
public IBinder onBind(Intent intent) {
return binder;
}
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Filip ", "Service onStart called.");
return START_STICKY;
}
}
Activity code:
package com.example.randomserviceshitnot;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MainActivity extends Activity {
private Servis mBoundService;
private boolean mIsBound = false;
private static final String mediaPath = Environment.getExternalStorageDirectory().toString()+"/Music/Art Of The Dress(Archie Remix).mp3";
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("Filip ", "Service connected.");
mBoundService = Servis.Stub.asInterface(service);
try {
mBoundService.execute(mediaPath);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName name) {
Log.d("Filip ", "Service disconnected.");
mBoundService = null;
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
doBindService();
}
void doBindService() {
Intent s = new Intent();
s.setAction("remote.servis");
bindService(s, mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
#Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
public void onPause() {
super.onPause();
doUnbindService();
}
void doUnbindService() {
if(mIsBound) {
unbindService(mConnection);
mIsBound=false;
}
}
}
AIDL:
package com.example.randomserviceshitnot;
interface Servis {
void execute(String s);
}
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.randomserviceshitnot"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MojPrviServis"
android:label="#string/servis_koji_notifikuje"
android:description="#string/proces_desc"
android:icon="#drawable/ic_launcher"
android:process=":dep" >
<intent-filter>
<action android:name="remote.servis" />
</intent-filter>
</service>
</application>
</manifest>
http://developer.android.com/guide/components/services.html
Read the documentation of onStartCommand() and onBind()
When you call bindService() onStartCommand() is NOT called. But onBind() is called.
Also the service terminates if all the clients exited if the service was stared with bindservice().
For playing music you should use startService() instead of bind. If service is started this way then it does not stop when client exists. It has to stop itself when done.