4

我在 SD 卡上打开了一个文件。当有人安装 SD 卡时,它最终会导致我的应用程序崩溃。我正在尝试注册 ACTION_MEDIA_EJECT 广播事件,我收到了,但似乎我来得太晚了。当我得到那个时,它已经让我的应用程序崩溃了。有没有办法在我的应用程序崩溃之前得到通知?

添加了一些非常简单的示例代码。当我这样做时,当我打开 USB(MSC 模式)时,它会导致服务崩溃。

测试.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;
    }

};

测试服务.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

2 回答 2

7

它正在杀死您的应用程序,因为当需要从设备上卸载 sdcard(例如,将 USB 安装到连接的 PC)时,杀死任何持有 sdcard 的打开句柄的进程是 android 中记录的设计决定。

仍具有打开文件句柄的文件系统无法完全卸载。在操作系统级别,没有办法撤销文件句柄,除非杀死被授予它的进程,所以这就是 android 最终所做的。

于 2012-01-27T07:16:58.387 回答
2
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
    //access external file
}

在不知道更多关于抛出什么异常的情况下,这就是我能推荐的全部内容。

此外,Environment 类文档中的以下代码可能会有所帮助:

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);
}
于 2011-02-17T19:15:06.430 回答