None of the many similar questions I have found have helped to solve my issue.
Here are some questions I've looked at:
ServiceConnection.onServiceConnected() never called after binding to started service
onServiceConnected never called after bindService method
ServiceConnection::onServiceConnected not called even though Context::bindService returns true?
OnServiceConnected not getting called
Here is part of my android app code:
//Local service interface
private INetworkQueryService myNetworkQueryService = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
Intent intent = new Intent(this, NetworkQueryService.class);
startService (intent);
bindService (new Intent(this, NetworkQueryService.class), myNetworkQueryServiceConnection,
Context.BIND_AUTO_CREATE);
}
//Service connection
private final ServiceConnection myNetworkQueryServiceConnection = new ServiceConnection() {
/** Handle the task of binding the local object to the service */
public void onServiceConnected(ComponentName className, IBinder service) {
myNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
// as soon as it is bound, run a query.
loadNetworksList();
}
/** Handle the task of cleaning up the local binding */
public void onServiceDisconnected(ComponentName className) {
myNetworkQueryService = null;
}
public void loadNetworksList() {
// delegate query request to the service.
try {
myNetworkQueryService.startNetworkQuery(myCallback);
} catch (RemoteException e) {
}
}
};
/**
* This implementation of INetworkQueryServiceCallback is used to receive
* callback notifications from the network query service.
*/
private final INetworkQueryServiceCallback myCallback = new INetworkQueryServiceCallback.Stub() {
#Override
public void onQueryComplete(List<NetworkInfo> networkInfoArray,
int status) throws RemoteException {
displayNetworks(networkInfoArray, status);
}
/** place the message on the looper queue upon query completion. */
};
As you can sy, myNetworkQueryServiceConnection should be called from within the bindService method (located in onCreate()). This (in theory) should also run onServiceConnected (I think), but I put a breakpoint in my code and it never stops inside that method. I did some debugging and bindService returns false, so for some reason it's not successfully binding it.
This is my first time ever having to bind services in Android, so I'm sure I've missed something. I'm hoping someone could point out a mistake.
Let me know if you're missing any information--I'm not sure what all you might need, and I really can't post my entire app code here.
EDIT: I keep reading things about registering the service in the manifest but cannot seem to figure out where or how that would be done? Here's the manifest for this project:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tek15.cellemrmonitor"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/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>
</application>
I certainly don't see anything about the service, but I guess I don't know how to add it.
You need to add a <service> element, as a peer of your <activity> element, as a child of <application>:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tek15.cellemrmonitor"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/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="NetworkQueryService" />
</application>
My example element assumes that NetworkQueryService is really com.tek15.cellemrmonitor.NetworkQueryService — otherwise, substitute in the proper fully-qualified class name.
Related
I have an application A that has to bind to a service that is in another package. I have put a custom intent filter in order to make it work. Sadly the application wont bind. The log says that it can't find the service.
Application A is in the package "com.example.app_a"
The service is in another package "com.example.app_talker_service"
So I just can't refer to the service with the xxx.class solution, so my guess was to use an intent filter in the manifest file of the service's package.
Application A, on the other hand, will need to do a bind to the service to make it start (if it hasn't already started) and that later it will communicate with it though the use of broadcast receivers. I did some experimentation and I noticed that the broadcasts work fine, but what is wrond is that for some reason, the application A can't seem to find my service during the binding....
Here is the code for application A which binds in onStart():
#Override
protected void onStart()
{
// TODO Auto-generated method stub
super.onStart();
//Bind to service
getApplicationContext().bindService(new Intent("com.example.talker_service.SERVICE"), mConnection,Context.BIND_AUTO_CREATE);
}
private boolean mIsBound = false;
private ServiceConnection mConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mIsBound = true;
Toast.makeText(getApplicationContext(), "CONNECTED TO SERVICE!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.setAction("com.example.talker_service.SERVICE");
intent.putExtra("REQUEST", "REGISTER APP");
intent.putExtra("FILTER", "com.example.app_a");
intent.putExtra("NAME", "Applicazione A");
String[] components = {"NUMBER_SENT","CHANGE_TEXT_COLOR","CHANGE_TEXTVIEW_SIZE"};
intent.putExtra("COMPONENTS", components);
MainActivityA.this.sendBroadcast(intent);
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
mIsBound = false;
}
};
Here instead is the cmanifest for the service which I called Talker_service:
en<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app_talker_service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service
android:name=".Talker_Service"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter >
<action android:name="com.example.talker_service.SERVICE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
</service>
<activity
android:name=".ConnectionManagerActivity"
android:label="#string/title_activity_connection_manager" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I don't undertsand why it doesn't bind.. I put the intent filter, am I missing something? Ah, and the logs says this:
12-03 22:45:13.786: W/ContextImpl(26076): Implicit intents with startService are
not safe: Intent {
act=com.example.talker_service.SERVICE }
android.content.ContextWrapper.bindService:517
com.example.app_a.MainActivityA.onStart:81
android.app.Instrumentation.callActivityOnStart:1171
12-03 22:45:13.786: W/ActivityManager(764): Unable to start service Intent { >act=com.example.talker_service.SERVICE } U=0: not
found
This instead is the manifest file for application A
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app_a"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" ></uses-permission>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivityA"
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>
I don't know why using intent filters is not working (it says that it can't find it) but by using the following code I was able to make my application connect to the remote service:
Intent i = new Intent();
i.setClassName("com.example.app_talker_service", "com.example.app_talker_service.Talker_Service");
bindService(i, conn, Context.BIND_AUTO_CREATE);
so using the seClassName method and providing the name of the pacake and that full path of the service, I was able to make it work. I am not sure if this falls in the realm of "best practice" for this type of problem, but for my it worked. Any solution is better than no solution. I found this solution thants to this link:
Remote Service Tutorial
I have no idea what it could be. I searched through my code for like 30 min
MainActivity:
public class MainActivity extends Activity {
public void onResume(){
ArrayList<String> voiceResults = getIntent().getExtras()
.getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
if (voiceResults.size() >= 1) {
String infoId = "That is what you said";
Card ShowDataCard = new Card(this);
ShowDataCard.setText(voiceResults.get(0));
//ShowDataCard.setText("Testing");
ShowDataCard.setInfo(infoId);
View ShowDataCardView = ShowDataCard.toView();
setContentView(ShowDataCardView);
}
else {
String mainText = "You did not say anything.";
String infoId = "Why didn't you say anything?";
Card ShowDataCard = new Card(this);
ShowDataCard.setText(mainText);
ShowDataCard.setInfo(infoId);
View ShowDataCardView = ShowDataCard.toView();
setContentView(ShowDataCardView);
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.glass.texttospeech"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="com.example.glass.texttospeach.MainActivity"
android:label="#string/app_name"
android:icon="#drawable/icon" >
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voice_trigger_start" />
</activity>
</application>
So what could it be? The intent filters are correct, the packages are correct, voice trigger is correct.
I am just trying to have it print what you said. I have done it before but it will not work now!
when you are overriding Activity methods, don't forget to call super methods.
here you are overriding onResume() but not calling super method. call super method like
#Override
public void onResume() {
super.onResume();
// do your work....
}
and use Override annotation when you are overriding any method for readability and check for NullPointException when you are getting extras from Intent. Intent.getExtras...() will return null if there is no mapping found for a given key
i am trying to develop a android application using broadcast receiver,my application means that,first i want to define and store a PARENT number to the database on my first activity ,when we install the app this activity will launch and the parent number saved to the database,then broadcast receiver want to active and its listen for call state changing,if any call is make through that phone i want to send a message to the parent number...??...here how can i use broadcast receiver...is it possible...and i mentioning my codes below......i hope you can help me for this .i try to do this many ways but i cant get the result.here first i create my first activity inside that i accessing my database values and trying to activate broadcast receiver.
public class PARENT_CALLActivity extends Activity
{
String PARENT=null;
EditText edparent;
Button submit;
String parent_number;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edparent=(EditText)findViewById(R.id.editText1);
submit=(Button)findViewById(R.id.btnsubmit);
submit.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
PARENT=edparent.getText().toString();
MyDabasehandler db=new MyDabasehandler(getApplicationContext());
if(db.getContact().equals(null))
{
db.addContact(new Contacts(PARENT));
}
else
{
db.editContact();
}
Intent reciver=new Intent(getApplicationContext(),myBroadcast.class);
startActivity(reciver);
}
});
}
}
my broadcast receiver....
public class myBroadcast extends BroadcastReceiver
{
String out_number;
String myparent;
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
out_number=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
MyDabasehandler db=new MyDabasehandler(context);
myparent=db.getContact().toString();
//Toast.makeText(context, out_number+"number", Toast.LENGTH_LONG).show();
SmsManager sm=SmsManager.getDefault();
sm.sendTextMessage(myparent, "5554", "calling..to"+out_number, null, null);//5554 is my emulator number to check its in emulator
Toast.makeText(context, "send"+out_number, Toast.LENGTH_SHORT).show();
}
}
and my Manifest is..
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sha.pcall"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".PARENT_CALLActivity"
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=".MyDabasehandler"
android:label="#string/app_name">
</activity>
<activity android:name=".Contacts"
android:label="#string/app_name">
</activity>
<receiver android:name=".myBroadcast"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
/manifest>
and i am getting force to close when i press the submit button.
You should put the LogCat output that shows the exception StackTrace.
What I can spot in the code that it seems that you are missing
<uses-permission android:name="android.permission.READ_PHONE_STATE" >
I m trying to start an IntentService from the main activity of y application and it won't start. I have the service in the manifest file. Here's the code:
MainActivity
public class Home extends Activity {
private LinearLayout kontejner;
IntentFilter intentFilter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
kontejner = (LinearLayout) findViewById(R.id.kontejner);
intentFilter = new IntentFilter();
startService(new Intent(getBaseContext(), HomeService.class));
}
}
Service:
public class HomeService extends IntentService {
public HomeService() {
super("HomeService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
Toast.makeText(getBaseContext(), "TEST", Toast.LENGTH_LONG).show();
}
}
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.salefinder"
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=".Home"
android:label="#string/title_activity_home" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".HomeService" />
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
How can I make it work?
onHandleIntent gets called from a background thread. You can't modify the UI, or in this case, make Toast from outside the UI thread. So, I wouldn't expect anything to happen with your service.
Just try writing something out with Log.d() to see if your service is getting called.
It seams that android cached a bad version of the app - I forced closed it and started it again, and it worked...
I'm doing something I thought would be simple as have done a broadcast receiver in the past on 2.3.4 droid. I'm using 4.x now in this little program.
Here is the main architecture/flow. I want/have a receiver to be listening for a custom broadcast/intent. I created this as a stand along project/apk
public class FileIntegrityMonitor extends BroadcastReceiver
{
public String CLASS_NAME = "FileIntegrityMonitor";
#Override
public void onReceive(Context context, Intent intent)
{
Log.d(CLASS_NAME, "Entered onReceive: got broadcast from startFIM");
String actionReceived = intent.getAction();
Log.d(CLASS_NAME, "Action received=" + actionReceived);
if (actionReceived.equals(StartFIMActivity.CUSTOM_INTENT))
{
//start service to perform the file integrity check
Log.d(CLASS_NAME, "start service to perform file integrity check");
}
}
Then I created a activity as a separate project/app as a driver for now to kick the broadcast receiver off. Will probably replace with something else later but wanted to get the mechanics/comms down now.
public class StartFIMActivity extends Activity
{
/** Called when the activity is first created. */
public static final String CUSTOM_INTENT = "com.kdms2.StartFIM.intent.action.start";
public String CLASS_NAME = "StartFIMActivity";
#Override
public void onCreate(Bundle savedInstanceState)
{
Log.d(CLASS_NAME, "Entered onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i = new Intent();
i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); //api 3.1+
i.setAction(CUSTOM_INTENT);
Log.d(CLASS_NAME, "send brodcast to monitor");
this.sendBroadcast(i);
}
}
Now in the trace I do get the intent in FileIntegrityMonitor but a strange message that it's trying to run some method and I don't know why. Error is:
E/AndroidRuntime(979): java.lang.RuntimeException: Unable to instantiate receiver com.kdms2.FileIntegrityMonitor.StartFIMActivity: java.lang.ClassNotFoundException: com.kdms2.FileIntegrityMonitor.StartFIMActivity
why did it add the class name of the activity that broadcast the action to the broadcast receiver?
Is it something in the manifest (receiver)?
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver android:name=".StartFIMActivity" android:enabled="true">
<intent-filter android:priority="99999999999">
<action android:name="com.kdms2.StartFIM.intent.action.start"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</manifest>
activity manifest
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".StartFIMActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</application>
</manifest>
v/r,
Frank
Your receiver's name is FileIntegrityMonitor, but in the manifest you try to register StartFIMActivity as both the <activity> and <receiver> elements. Probably oughta be:
<receiver android:name=".FileIntegrityMonitor" android:enabled="true">
<intent-filter android:priority="99999999999">
<action android:name="com.kdms2.StartFIM.intent.action.start"/>
</intent-filter>
</receiver>
Or something of the like.
HTH