OBB downloader library seems to use Context.startService(...) to download OBB in background, but on Android 8.0 this leads to crashes, if app itself is in the background.
This library registers a BroadcastReceiver:
mConnReceiver = new InnerBroadcastReceiver(this);
IntentFilter intentFilter = new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
registerReceiver(mConnReceiver, intentFilter);
Receiver istelf:
private class InnerBroadcastReceiver extends BroadcastReceiver {
final Service mService;
InnerBroadcastReceiver(Service service) {
mService = service;
}
#Override
public void onReceive(Context context, Intent intent) {
pollNetworkState();
if (mStateChanged
&& !isServiceRunning()) {
Log.d(Constants.TAG, "InnerBroadcastReceiver Called");
Intent fileIntent = new Intent(context, mService.getClass());
fileIntent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
// send a new intent to the service
context.startService(fileIntent);
}
}
};
Crash stack stace:
Downloader service crash
So, what is the preferred way to avoid such crashes? Or this user experience is normal in Android 8.0+?
Related
I'm trying to test a started service that will return its results via a local broadcast receiver/intent.
I have that working... but I want to unit/integration test it.
I can find plenty of code on how to do that in the old ApplicationTestCase/etc way, but I can't find a good example of how to do it in the new 'Rule' framework.
Here is the Integration Test I have so far...
LocalBroadcastManager instance = LocalBroadcastManager.getInstance(
InstrumentationRegistry.getTargetContext());
final boolean[] called = new boolean[1];
final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
called[0] = true;
}
};
instance.registerReceiver(receiver, new IntentFilter("com.foo"));
mServiceRule.startService(serviceIntent);
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
assertThat(called[0], is(true));
and here is the relevant part of the (this is all a sample project I made to proof of concept how to get this code working) onHandleIntent code:
Intent returnIntent = new Intent();
intent.setAction("com.foo");
LocalBroadcastManager.getInstance(getApplicationContext()).
sendBroadcast(returnIntent);
Note: I'd even accept a robolectric solution as long as it used the newest 3.2 API (Need that for API 25 support)
I'm working on a Android APP. There's a main activity and a service. The service is started by calling startService(intent) in main activity. and it would be running in background no matter the activity is running or not. After the activity is created, it will send broadcast message to service to query some status. The first time of the running is okay, both activity and service initiated correctly. But I get an issue that when I quit the activity and restart it, the service will keep receiving the query message like the activity is sending it repeatedly. But I confirmed the sending code in activity was only executed once. Anyone have idea where the messages comes from?
the codes in main activity onCreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("debug", "Main.onCreate");
Intent intent=new Intent(MainActivity.this, PingService.class);
startService(intent);
Intent intent = new Intent(PingService.ACTION_QUERY);
sendBroadcast(intent);
}
And below are codes in service
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(PingService.ACTION_QUERY)) {
Log.v("debug", "PingService.receiver.onReceive: ACTION_QUERY");
//the program keeps coming here
}
}
};
#Override
public void onCreate() {
Log.v("debug", "PingService.onCreate");
HandlerThread thread = new HandlerThread("pingd",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
//handlers
serviceHandler = new ServiceHandler();
daemonHandler = new DaemonHandler(thread.getLooper());
//register broadcast receiver
IntentFilter filter = new IntentFilter();
filter.addAction(PingService.ACTION_ADD);
filter.addAction(PingService.ACTION_QUERY);
filter.setPriority(999);
registerReceiver(receiver, filter);
instance = this;
}
I'v already read post about:
BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do whatever you want to do
}
};
registerReceiver(myReceiver, new IntentFilter("ACTION"));
unregisterReceiver(myReceiver);
Intents:
ACTION_PACKAGE_INSTALL
ACTION_PACKAGE_REPLACED
ACTION_PACKAGE_CHANGED
ACTION_PACKAGE_ADDED
How to do subject or when installation failed
I am new to Android development.
I want to get a notice when the operating system (because of lack of memory) or other application (Task killer e.g. ZDbox) restart other applicatoin (not mine).
I tried BroadcastReceiver. It did not get any Intent when an app was killed and the user started it manually. I have used PACKAGE_RESTARTED intent but BroadcastReceiver did not get any Intent.
Any suggestions?
public class MyService extends Service {
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
filter.addDataScheme("package");
BroadcastReceiver pkgRemoveReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do my stuff
}
};
registerReceiver(pkgRemoveReceiver, filter);
}
I'm trying to implement a Broadcast Receiver who should receive Intent from a Service which is running in the background, however it is not working.
In my main Activity I just bind the service and start it via onClick on a Button.
In my SpeechRecognizer Service class I create a new BroadcastReceiver (see code below).
public void onCreate() {
Log.d(TAG, "onCreate");
if (SpeechRecognizer.isRecognitionAvailable(this)){ //check if a SpeechRecognizer is available
this.sr = SpeechRecognizer.createSpeechRecognizer(this);
this.sr.setRecognitionListener(new listener());
commandsReceiver = new CommandsReceiver();
ConnectivityManager cm =(ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
testfilter = new IntentFilter();
registerReceiver(commandsReceiver,testfilter);
} else {
Toast.makeText(this,"Please install a SpeechRecognizer on your system.", Toast.LENGTH_LONG).show(); //alert if speech-recognizer is not installed on the device
Log.d(TAG, "no SpeechRecognizer available");
this.onDestroy();
}
}
In my onResult I do it like this:
Intent intent = new Intent();
intent.setAction(CommandsReceiver.TEST);
sendBroadcast(intent);
In my CommandsReceiver I just got a simple String and a Log message:
public class CommandsReceiver extends BroadcastReceiver {
public static final String TEST = "de.speech.TEST_INTENT";
#Override
public void onReceive(Context context, Intent intent) {
Log.d("BroadCastReceiver", "Intent received"+intent);
}
}
However I'm not getting the Log.d() message.
I hope you can help me out.
Seems you are creating an IntentFilter without any Action as
testfilter = new IntentFilter();
instead of,
testfilter = new IntentFilter(CommandsReceiver.TEST);
so, register your BroadCast using,
testfilter = new IntentFilter(CommandsReceiver.TEST);
registerReceiver(commandsReceiver,testfilter);