I have this famous error Can't instantiate class ...; no empty constructor even after i added an empty constructor it's doesn't solve the problem. here's the code:
public class BackService extends Service {
private BackService() { }
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
SmsListener SmsListener = new SmsListener();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
registerReceiver(SmsListener, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
return START_STICKY;
}
}
and in manifest :
<service android:name="MainActivity$BackService" />
How i can solve it? thank you
Make the constructor public or eliminate that zero-argument constructor. Having a private zero-argument constructor will not work, as the framework cannot use it.
Also, this needs to be a static class, since from your <service> element, it appears to be inside MainActivity (which is very strange).
The empty constructor needs to be accessible. You could define it as public:
public BackService() { }
Or just remove it altogether and use the default constructor (since the class has no other constructors).
You should not construct Service (or Activity, BroadcastReceiver) explicitly. The Android system does that for you internally. The proper way to start a service is via startService() with an Intent, not by calling something like new YourService().
In your case, just delete this line:
private BackService() { }
..and make sure you're starting the Service correctly.
If you want to be notified about new SMS only when your activity is visible to user do these:
remove service entirely
move this line to Activity's onCreate
SmsListener SmsListener = new SmsListener();
move this line to Activity's onResume
registerReceiver(SmsListener, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
add this line to Activity's onPause
unregisterReceiver(SmsListener);
Otherwise if you want to always be notified about new SMS just add a broadcast receiver to your project:
<receiver android:name=".SmsListener" >
<intent-filter android:priority="500">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Related
I have an activity which I start a service in the OnCreate method. StartService method is executed without any error, but none of the events in Service class are not fired!
I test both of the explicit and implicit modes to start the service as you can see in my code, but both results were same!
My codes:
Activity:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
try
{
serviceToStart = new Intent(ApplicationContext, typeof(TrackService));
StartService(serviceToStart);
}
catch(Exception e)
{
var ee = e;
}
}
Track Service:
[Service(IsolatedProcess = true, enabled = true)]
public class TrackService : Service
{
FusedLocationProviderClient fusedLocationProviderClient;
public override void OnCreate()
{
base.OnCreate(); //Break point set here
}
public override StartCommandResult OnStartCommand(Android.Content.Intent
intent, StartCommandFlags flags, int startId)
{
fusedLocationProviderClient =
LocationServices
.GetFusedLocationProviderClient(this); //Break point set here
return StartCommandResult.Sticky;
}
public override IBinder OnBind(Intent intent)
{
return null;
}
}
Manifest:
EDIT: Manifest manuals removed removed
Can anyone say me what's the problem?
Please mention you service in the manifest file. This is very important step because without manifest service entry your service class never initiated.
Below line of code is very important, this should be in your manifest file.
<service android:name=".TrackService" android:enabled="true"></service>
Referrer to below link for more clarification about the services
- https://developer.android.com/training/run-background-service/create-service
1) Allow the ServiceAttribute (and the build process) to property set the manifest entry and no manual changes are needed:
[Service(IsolatedProcess = true, enabled = true)]
Note: If you wish/need to manually change the manifest, you will need to assign the Name in the ServiceAttribute to hard-code a fully-qualified package and Java class name that you can then use in your manifest
2) When starting the service, build an intent using the application context and the C# type of your service:
var serviceIntent = new Intent(ApplicationContext, typeof(TrackService));
StartService(serviceIntent);
Finally! I found the problem root! However, I don't know why it happens and how can I resolve it!
I always got this error in logcat:
No implementation found for void mono.android.Runtime.register
After removing part by part of the code I got that the problem is caused by IsolatedProcess attribute. Just by removing it the code works well.
Note: As you can see there's no need to put enabled attribute for service too.
[Service]
public class TrackService : Service
My app will not invoke the intentservice request from the wakefulbroadcastreceiver
Manifest:
<service
android:name=".MyWearableListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/>
<data android:scheme="wear" android:host="*"/>
</intent-filter>
</service>
<service
android:name=".CounterActivity$WearableReceiverService"
android:exported="false">
</service>
<receiver
android:name=".CounterActivity$WearableReceiver"
android:enabled="true">
</receiver>
So i register all receivers and services.
inside my main activity i have these as sub-classes within the main class so i can call the method in the main class msgReqAction()
public class WearableReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, WearableReceiverService.class);
startWakefulService(context, service);
}
}
public class WearableReceiverService extends IntentService {
public WearableReceiverService(){
super("WearableReceiverService");
}
#Override
protected void onHandleIntent(Intent intent) {
msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
WearableReceiver.completeWakefulIntent(intent);
}
}
I don't think having these as subclasses should hinder the situation but it may. if i must have these outside the main class for operation let me know.
finally i begin the whole process from a listener outside the main activity that listens for a message from the wearable
#Override
public void onMessageReceived(final MessageEvent messageEvent) {
nodeId = messageEvent.getSourceNodeId();
String incomingPath = messageEvent.getPath();
int incomingReq = Integer.parseInt(new String(messageEvent.getData()));
if(incomingPath.equalsIgnoreCase(MyConstants.MSG_COUNTER_REQ_PATH)) {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MyConstants.BROADCAST_ACTION_RESP);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra(MyConstants.BROADCAST_DATA_REQ, incomingReq);
sendBroadcast(broadcastIntent);
}else if(incomingPath.equalsIgnoreCase(MyConstants.MSG_DEFAULT_PATH)){
}
}
public static final String BROADCAST_ACTION_RESP = "com.example.johnbravado.zionwork.MESSAGE_PROCESSED";
my project is com.example.johnbravado.zionwork - also on a side note is there a way to change and refactor that in android studio easily so i can get rid of example or change it completely?
when i run the debugger the system gets all the way to
startWakefulService(context, service);
then it crashes without entering the intent service. is there somethig simple i am missing amongst all this which is preventing it from going into the service and doing work. best i can tell is it does not go into the service at all. i added some intro lines of the service
#Override
protected void onHandleIntent(Intent intent) {
int data;
data = 0;
data++;
msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
WearableReceiver.completeWakefulIntent(intent);
}
and tried to run debug points on these lines and it didnt get there.
You cannot have a Service defined as a non-static inner class.
A non-static inner class contains a reference to its outer class. This means that in order to create a new instance of the inner class, you need to have an instance of the outer class.
When Android tries to start your Service, it tries to create a new instance of the inner class. This fails, because Android does not have an instance of the outer class to use in the creation.
The same rule applies to the BroadcastReceiver.
Solution: Move all your inner classes to full-fledged classes (in their own source files).
The solution was to eliminate the WakefulfulBroadcastReceiver and secondary IntentService. Instead, I used a BroadcastReceiever and sent a broadcast directly from the Wearable listener function and used that to process data directly within the activity.
public class WearableReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Intent service = new Intent(context, WearableReceiverService.class);
//startWakefulService(context, service);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"com.example.johnbravado.zionwork");
wakeLock.acquire();
// Do Work
msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
wakeLock.release();
}
}
Even though i do not do much that would necessarily require a wakelock. if i decide later to do more work i have it ready to go. i am not sure if this is best place for the wakelock either never really used them but that is another topic.
I removed reference to the extra service and receiver in the manifest file also. works good now
Hi i am trying to understand Broadcast Receiver , i went through many sample codes , but still have some doubts. I wanted to know when we have to extend the Broadcast Receiver class and when should we use registerReceiver() method and when should we create object for BroadcastReceiver. In some programs i came across registerReceiver methods being used but without extending the Broadcast Receiver class. I also wanted to know how the onReceive method gets called.
Which approach should be used when?
here is the registerReceiver method:
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (getResultCode()) {
........
}
}
}, new IntentFilter(SENT));
Object being created for BroadcastReceiver:
private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
.................
}
};
Android has intent action for broadcast receiver. BroadCast receiver will be trigger when it listen any action which registered within it.
Now we will take one example :
That we need to listen the action of "whenever any bluetooth device connect to our device". For that android has it fix action android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED
So you can get it via manifest & registration also
BY Manifest Registration:
Put this in your manifest
<receiver android:name="MyBTReceiver">
<intent-filter>
<action android:name="android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED" />
</intent-filter>
</receiver>
Create MyBTReceiver.class
public class MyBTReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED")){
Log.d(TAG,"Bluetooth connect");
}
}
}
That was the simplest broadcast Receiver.
Now,
if you are only interested in receiving a broadcast while you are running, it is better to use registerReceiver(). You can also register it within your existing class file. you also need to unregister it onDestroy().
here, you dont need any broadcast registration in manifest except activity registration
For example
public class MainActivity extends Activity {
IntentFilter filter1;
#Override
public void onCreate() {
filter1 = new IntentFilter("android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED");
registerReceiver(myReceiver, filter1);
}
//The BroadcastReceiver that listens for bluetooth broadcasts
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equalsIgnoreCase("android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED")) {
Log.d(TAG,"Bluetooth connect");
}
}
};
#Override
public void onDestroy() {
unregisterReceiver(myReceiver);
}
}
In both cases BroadcastReceiver will be extended. In your second example you create so called anonymous class. New class has no specific name, that is why it's called so. Anyway this new class extends BroadcastReceiver and overrides onReceive() method.
Now back to your question. There are two kinds of receivers - statically and dynamically defined ones.
If you declare your receiver in AndroidManifest file, then it is statically defined. In this case you need to refer to a class implementing BroadcastReceiver by name. As you can see, you cannot use an anonymous class, because the last has no name. You have to explicitly implement a receiver. It's worth to mention, that in this case you do not use registerReceiver() method. Android does it for you automatically.
If you declare receivers dynamically (for instance in activity's onResume() method), then you can use anonymous class for that. To register a receiver you call registerReceiver() method. You can also use a named class too. Both options are valid in this case.
Hope this explains the difference.
In both case you are creating object.But in first case there is not any reference for
the receiver object so it can not be unregistered later but second one has so it can be
unregistered after registering object using below methods:
registerReceiver(intentReceiver );
unregisterReceiver(intentReceiver );
I am getting confused with all the different terminology when using Android: Activity, Service...
Right now I create a service:
startService(new Intent(this, RingerServer.class));
And this service starts a thread:
public class RingerServer extends Service {
public void onCreate() {
super.onCreate();
new Thread(new Ringer()).start();
}
public class Ringer implements Runnable { ... }
public void refuseConnection() { ... }
}
In this service, the RingerServer, I also have methods that I want to use. I would like to keep a reference to the RingerServer. I would basically like the Activity that created the service to be able to call refuseConnection(), but not make that method static.
startService returns a ComponentName, so I've been trying to cast it back to RingerServer but that doesn't seem to work. I see that it has getClass() and I've checked and getClassName() gives me the correct class. I haven't been able to use getClass() properly though.
Is there any way I can please keep a reference to the newly created RingerServer class? I am sure this is trivial, but I am stuck right now.
Thank you very much,
James
You have two options
1.Override onStartCommand of the service and start the server with intent using an action. that intent will be received in service, based on the intent action you can call refuseConnection()
//In Activity
...
//Start the service
Intent intent=new Intent("com.xx.xx.REFUSE_CONNECTION");
startService(this,intent);
...
//In Service
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
if(intent.getAction().equals("com.xx.xx.REFUSE_CONNECTION")){
//Refuse the connection
refuseConnection();
}else {
//Do something else
}
}
//In Manifest
<service android:name="RingerService">
<intent-filter>
<action android:name="com.xx.xx.REFUSE_CONNECTION"></action>
</intent-filter>
</service>
Implement AIDL interface and override onBind() of service , and use this interface to call refuseConnection(). Refer to this link http://developer.android.com/guide/developing/tools/aidl.html regarding AIDL.
You can use a ServiceConnection to get access to your service class. See sample code here:
Android service running after pressing Home key
That said, managing things via the service's onStart handler is much simpler.
I've a simple Main Activity which has to stop till an SMS is received... How can I launch a method from the MainActivity within the BroadcastReceiver's onReceive() Method?
Is there away with Signal and Wait? Can I pass something with a pending Intent, or how can I implement this communication?
Communication from BroadcastReceiver to Activity is touchy; what if the activity is already gone?
If I were you I'd set up a new BroadcastReceiver inside the Activity, which would receive a CLOSE message:
private BroadcastReceiver closeReceiver;
// ...
closeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//EDIT: receiving parameters
String value = getIntent().getStringExtra("name");
//... do something with value
finish();
}
};
registerReceiver(closeReceiver, new IntentFilter(CLOSE_ACTION));
Then from the SMS BroadcastReceiver you can send out this action:
Intent i = new Intent(CLOSE_ACTION);
i.putExtra("name", "value"); //EDIT: this passes a parameter to the receiver
context.sendBroadcast(i);
I hope this helps?
I had the exact same problem, I tried using intent but i was unsuccessful
The easiest way to use it would be using static methods and static variables
MainActivity.java
public static void stopsms()
{
/*
some code to stop the activity
*/
}
SMSReceiver.java
at the end call this function
MainActivity.stopsms();
It works amazing if your code does not affect when you use static methods and variables. Let me know if you need any help.
The problem with registering a second receiver within the activity, however, is that it will not be persistent like registering in the manifest... thus, although, this solution may work, will only work if the activity is running in background.
it's easy, use interface like that:
1) in your broadcast receiver create an interface.
public interface ChangeListener{
public void functionWhoSendData(String type);
public void etc();
}
and instantiate that interface in your broadcast receiver, use it:
public void onReceive(....
String data=functionWhereYouReceiveYouData();
ChangeListener.functionWhoSendData(data);
}
And in your activity, make it implements your interface