FileObserver не вызывает события при вызове в фоновом режиме - PullRequest
0 голосов
/ 17 мая 2018

Есть ответы на вопросы, касающиеся FileObserver в Android, и я следую за ними, но мой код все еще не работает.Здесь я публикую свой код, я пытаюсь установить fileObserver через сервис, чтобы он работал, даже если само приложение закрыто.При запуске он вызывает конструктор DirectoryObserver, но добавление или удаление файла не вызывает событие

public class MainActivity extends AppCompatActivity
{
    private String sharedPreferencesKey = "IsThisFIrstTime";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);

    if (!preferences.contains(sharedPreferencesKey)) {
        SharedPreferences.Editor editor = preferences.edit();
        editor.putBoolean(sharedPreferencesKey, false);
        editor.apply();

        try {
            startTheServices();
        }
        catch (Exception ex) {
        }
    }

    setContentView(R.layout.activity_main);
}

private void startTheServices()
{
    Intent intent = new Intent(this, BackgroundServices.class);
    startService(intent);
}
}



public class BackgroundServices extends Service {

@Override
public void onCreate(){
    super.onCreate();
    Toast.makeText(this, "This is on Create", Toast.LENGTH_LONG).show();


}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "This is on onStartCommand", Toast.LENGTH_LONG).show();
     Thread thread = new Thread(new ThreadClass(startId));
    thread.start();
    return super.onStartCommand(intent, flags, startId);
    //return START_STICKY;
}

@Override
public void onDestroy(){
    super.onDestroy();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}


final class ThreadClass implements Runnable {
    int _serviceId;

    ThreadClass(int serviceId) {
        _serviceId = serviceId;
    }

    @Override
    public void run() {
        DirectoryObserver directoryObserver = new DirectoryObserver(new File(Environment.getExternalStorageDirectory(), Constants.Camera_Directory).getAbsolutePath(), getApplicationContext());
        directoryObserver.startWatching();
    }
}
}





public class DirectoryObserver extends FileObserver {
    private static final String TAG = "DIRECTORY_OBERSVER";
    private String directoryPath;
    private Context _context;

public DirectoryObserver(String path, Context context) {
    super(path);

    Log.i(TAG, "Something Happening " + path);
    _context = context;
    directoryPath = path;
}

@Override
public void onEvent(int event, @Nullable String path) {
    if (path == null) {
        return;
    }
    //a new file or subdirectory was created under the monitored directory
    if ((FileObserver.CREATE & event)!=0) {
        Log.i(TAG, "A file is added to the path " + path);

        Toast.makeText(_context, "A new file has been added", Toast.LENGTH_LONG).show();
    }

    if ((FileObserver.DELETE & event)!=0) {
        Log.i(TAG, "A file is deleted to the path " + path);
        //Context.getApplicationContext();
    }
}
}

. Далее следует менифест:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="someone.package">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".BackgroundServices" android:exported="false"></service>
    </application>

</manifest>

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

Проблема здесь в том, что FileObserver, вероятно, собирается сборщиком мусора, как вы можете видеть здесь :

Предупреждение: Если FileObserver является мусоромсобранные, он прекратит отправку событий.Чтобы гарантировать получение событий, вы должны сохранять ссылку на экземпляр FileObserver от какого-либо другого живого объекта.

Android может избавиться от вашего сервиса или даже от самого FileObserver.Попробуйте проверить, входит ли код в метод startWatching (), или даже если служба запускается.

0 голосов
/ 17 мая 2018

Решение, которое я нашел, состоит в том, чтобы переместить следующую инициализацию метода DirectoryObserver

 DirectoryObserver directoryObserver = new DirectoryObserver(new File(Environment.getExternalStorageDirectory(), Constants.Camera_Directory).getAbsolutePath(), getApplicationContext());

в

public int onStartCommand(Intent intent, int flags, int startId)

в BackgroundService Class перед следующими строками

Thread thread = new Thread(new ThreadClass(startId));
    thread.start();
0 голосов
/ 17 мая 2018

Вы добавили разрешение?У меня недостаточно поводов, иначе я бы прокомментировал.

...