I'm working on AndroidService, where every 5 minutes a network call is made to search new data from database. I have implemented BroadcastListener to listen for constant connection inside service, but the app is crashing everytime.
Error:
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } in com.test.service.MyService$1#d3df904
Globally declared:
BroadcastReceiver receiver;
Code:
#Override
public void onCreate() {
super.onCreate();
registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(ConnectionStatus.isConnected(MyService.this)){
//some work
}
else {
//some task
}
}
};
registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
return START_STICKY;
}
onCreate happens before onStartCommand so you are trying to register a broadcast receiver with a null receiver. Remove the register from onCreate and it should work.
Related
i want to receive a broad cast when the screen is turned off in android. I have written the following code. This is the Receiver's code.
#Override
public void onReceive(Context context, Intent intent) {
helper = new FeedReaderDBHelper(context);
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
System.out.println("Screen Off Receiver just received something");
if(helper.getValue(FeedReaderContract.FeedEntry.onlock).equals("YES"))
{
helper.lockAll();
wasScreenOn = false;
}
else if(helper.getValue(FeedReaderContract.FeedEntry.onLock3).equals("YES"))
{
System.out.println("Running 3 minutes thread");
Runner runner = new Runner(context);
Thread t = new Thread(runner);
t.setName("LockThreeThread");
t.start();
}
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// and do whatever you need to do here
wasScreenOn = true;
}
}
I am registering and unregistering the Receiver in a Service. The code is as follows.
Registring Receiver in onStartCommand method
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
isScreenOn = pm.isScreenOn();
RegisterReceiver();
//Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_SHORT).show();
//System.out.println("StartRemove");
helper = new FeedReaderDBHelper(this);
names = helper.getNames();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
startChecker();
}
});
t.start();
return START_STICKY;
}
And this is how i unregister in onDestroy of the Service method.
private void RegisterReceiver()
{
receiver = Factory.getScreeReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(receiver, filter);
}
Please let me know what could be the problem. I have been digging into it for long time. Last two days were wasted on this. Nothing seems to work.
I think you're overly complicating this.
This is the activity you would need
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent startServiceIntent = new Intent(this, MyService.class);
startService(startServiceIntent);
}
This is the service
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("APP", "Service started");
ScreenOffReceiver receiver = new ScreenOffReceiver();
registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
return START_STICKY;
}
}
And this is the Broadcast Receiver
public class ScreenOffReceiver extends BroadcastReceiver {
public ScreenOffReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Log.i("APP", "EVENT occured");
}
}
I just tried out this code and the logging worked fine.
When you start this via a service, and start a new thread to do the job in the onStartCommand() method, be noted that the thread will start every time you invoke the onCreate() of the activity.
Hope this helps
I have an activity. It will be receive two variable from an service. In the service, I will send two variable to the activity by
// Send first variable
sendBroadcast(new Intent("first_one"));
// Send second variable
sendBroadcast(new Intent("second_one"));
Now, In the activity, I used bellow code to receive the data. There are
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(firstRec, new IntentFilter("first_one"));
registerReceiver(secondRec, new IntentFilter("second_one"));
}
#Override
protected void onPause() {
super.onPause();
if (firstRec != null) {
unregisterReceiver(firstRec);
firstRec = null;
}
if (secondRec != null) {
unregisterReceiver(secondRec);
secondRec = null;
}
}
private BroadcastReceiver firstRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG","OK first");
}
};
private BroadcastReceiver secondRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG","OK second");
}
};
However, I cannot print the log "OK second" when I called sendBroadcast(new Intent("second_one")); in the service. What is happen? How can I fix it? Thank you
UPDATE: my activity is an accept calling activity get from #notz
How can incoming calls be answered programmatically in Android 5.0 (Lollipop)?. Then I create an service as following
public class myService extends Service{
#Override
public void onCreate() {
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent answerCalintent = new Intent(getApplicationContext(), AcceptCallActivity.class);
answerCalintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
answerCalintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(answerCalintent);
//Send the second command after 10 second and make the calling in background
new CountDownTimer(10000, 100) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
sendBroadcast(new Intent("second_one"));
}
}.start();
return START_STICKY;
}
}
You should unregister your reŃeiver in a method opposite to that in which you register it:
If you registered receiver in onCreate() - then you should unregister it in onDestroy().
But as i know, for most cases, the best practice is to register receiver in onResume() and unregister it in onPause().
I have service in which I want to have a localbroadcast receiver. I want to recieve a value from the activity to my services onCreate.
Note: I can get a value from an activity to my service in onStartCommand() using intent. But here I want a value from activity in onCreate of the service.
The following is my service file:
public class MediaServiceSimha extends Service {
private MediaPlayer player;
String musicpath;
private ResponseReceiver receiver;
public MediaServiceSimha() {}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.unregisterReceiver(receiver);
super.onDestroy();
}
#Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
#
Override
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate() {
super.onCreate();
IntentFilter broadcastFilter = new IntentFilter("com.example.myintentserviceapp.intent_service.ALL_DONE");
receiver = new ResponseReceiver();
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.registerReceiver(receiver, broadcastFilter);
}
public class ResponseReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
musicpath = intent.getStringExtra("musicpath");
}
}
}
The following is my activity file where I want to pass a value called musicpath
public class ServiceTest extends AppCompatActivity {
Intent intent;
public static final String TEXT_INPUT = "inText";
//MediaServiceSimha mediaServiceSimha;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
L.m("activity_oncreate_starting");
setContentView(R.layout.activity_service_test);
intent= new Intent(this,MediaServiceSimha.class);
startService(intent);
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.example.myintentserviceapp.intent_service.ALL_DONE");
broadcastIntent.putExtra("musicpath", "/storage/emulated/0/Download/1.mp3");
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.sendBroadcast(broadcastIntent)
}
}
After running, it says musicpath value is null.
How to do it?
My goal was to pass a variable value directly to oncreate in the service class.
I tried LocalBroadcast's reciver and also onbindservices - onServiceConnected
Both of them i found that they will only get executed untill oncreate -> onbind/onstartcommand get executed in the services.
So only option left is onstartcommand()
So when we pass values using intent then they can be used immediately inside onstartcommand.
when you are calling start service it doesn't mean it will call immediately,so wait for oncreate of service,whenever your service getstarted you can send a callback to your activity then you can broadcast values to your service
public service callback() // callback from service started
{
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.example.myintentserviceapp.intent_service.ALL_DONE");
broadcastIntent.putExtra("musicpath", "/storage/emulated/0/Download/1.mp3");
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.sendBroadcast(broadcastIntent)
}
public class MediaServiceSimha extends Service {
#Override
public void onCreate() {
super.onCreate();
IntentFilter broadcastFilter = new IntentFilter("com.example.myintentserviceapp.intent_service.ALL_DONE");
receiver = new ResponseReceiver();
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.registerReceiver(receiver, broadcastFilter);
sendCallback(); // using interface or broadcast receiver to send callback to activity
}
}
I have an Activity, this Activity will call a Service and that Service will call a broadcast to listen for SMS coming. I register a broadcast in the Service dynamically.
But it's not working. My code is below. Please help me resolve.
This is the onCreate method in the Service.
#Override
public void onCreate() {
super.onCreate();
final IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
this.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
showSuccessfulBroadcast();
}
}, filter);
}
The code is correct. Don't forget to declare used permission in AndroidManifest.xml, and to unregister receiver in onDestroy(). Both points are important.
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
Inside your Service
private BroadcastReceiver mSmsBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
showSuccessfulBroadcast();
}
};
#Override
public void onCreate() {
super.onCreate();
final IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
this.registerReceiver(mSmsBroadcastReceiver, filter);
}
#Override
public void onDestroy() {
this.unregisterReceiver(mSmsBroadcastReceiver);
}
I have broadcast receiver that activates on phone boot
public class autostart extends BroadcastReceiver {
public void onReceive(Context arg0, Intent arg1) {
Intent intent = new Intent(arg0, MyService.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
}
The service is very simple it just keeps registered an broadcast receiver that can be only registered by code and not from manifest
public class MyService extends Service
{
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
ScreenOffReceiver actionScreenOffReceiver;
#Override
public void onStart(Intent intent, int startid)
{
try {
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(Intent.MY_ACTION);
registerReceiver(actionScreenOffReceiver = new ScreenOffReceiver(),
intentfilter);
} catch (Exception e) {
}
}
}
The problem is that if the app get closed, for example with call of finish() on some activity, then the service just dies.
How can I keep the service running till the phone is turned on
what is the right way to do this ?
You don't need an BroadcastReceiver just add this code in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Source: Service | Android Developers