Crash prevention when someone mounts an Android SD card

I have a file open on an SD card. When someone mounts an SD card, this causes my app to crash. I'm trying to register to broadcast ACTION_MEDIA_EJECT events, and I get this, but it looks like I'm too late. By the time I realized this, he had already crashed my application. Is there a way to get notified before my application crashes?

A very simple code example has been added. When I do this, it crashes the service when I turn on USB (MSC mode).

Test.java

/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { startService(new Intent(this, TestService.class)); bindService(new Intent(this, TestService.class), serviceConnection, Context.BIND_AUTO_CREATE); } catch (Exception e) { } } protected TestService testService; private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { TestService.LocalBinder binder = (TestService.LocalBinder) service; testService = binder.getService(); } @Override public void onServiceDisconnected(ComponentName name) { testService = null; } }; 

TestService.java

 @Override public void onCreate() { super.onCreate(); try { mFileOutputStream = new FileOutputStream("/sdcard/test2", true); } catch (Exception e) { } } @Override public IBinder onBind(Intent intent) { return binder; } public static class LocalBinder extends Binder { public static TestService getService() { return _this; } } 
+4
source share
2 answers

It kills your application because it is a documented design solution in android to kill any process containing an open SD card descriptor when the SD card must be disconnected from the device (for example, to connect USB to a connected PC)

A file system that still has open files cannot be completely disabled. At the operating system level, there is no way to cancel a file descriptor without waiting for the destruction of the process to which it was provided, so ultimately the android does it.

+7
source
 if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { //access external file } 

Without knowing more about what exceptions are thrown, that’s all I can recommend.

In addition, the following code from the environment class documentation may help:

 BroadcastReceiver mExternalStorageReceiver; boolean mExternalStorageAvailable = false; boolean mExternalStorageWriteable = false; void updateExternalStorageState() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { mExternalStorageAvailable = mExternalStorageWriteable = true; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { mExternalStorageAvailable = true; mExternalStorageWriteable = false; } else { mExternalStorageAvailable = mExternalStorageWriteable = false; } handleExternalStorageState(mExternalStorageAvailable, mExternalStorageWriteable); } void startWatchingExternalStorage() { mExternalStorageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i("test", "Storage: " + intent.getData()); updateExternalStorageState(); } }; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MEDIA_MOUNTED); filter.addAction(Intent.ACTION_MEDIA_REMOVED); registerReceiver(mExternalStorageReceiver, filter); updateExternalStorageState(); } void stopWatchingExternalStorage() { unregisterReceiver(mExternalStorageReceiver); } 
+2
source

Source: https://habr.com/ru/post/1340220/


All Articles