Backgroundservice正在运行,但不起作用(FileObserver)

时间:2018-06-21 08:34:12

标签: android service broadcastreceiver android-broadcastreceiver fileobserver

我想运行一个Backgroundservice(FileObserver),它将查找系统中的任何文件更改(CREATE,DELETE,MOVE等)。 当我启动我的应用程序时,它可以工作几秒钟,并且一切正常。例如,在用相机拍摄照片时,它会记录下来。几秒钟后,该服务仍列在“设置” =>“开发人员选项” =>“运行服务”中,但不再起作用并且不再记录任何内容。

Android版本:7.0

设备:三星Galaxy S7 Edge

我在这里1:1复制了Niza Siwale的答案中的代码,并仅添加了这样的日志:

How to monitor folder for file changes in background?

   @Override
    public void onEvent(int event, final String path) {
        if (event == FileObserver.OPEN) {
            Log.v("Event: ", "Open" + path);
        } else if (event == FileObserver.CREATE && (!path.equals(".probe"))) {
            Log.v("Event: ", "Create" + path);
        } else if (event == FileObserver.DELETE_SELF || event == FileObserver.DELETE) {
            Log.v("Event: ", "Delete" + path);
        } else if (event == FileObserver.MOVE_SELF || event == FileObserver.MOVED_FROM || event == FileObserver.MOVED_TO) {
            Log.v("Event: ", "Move" + path);
        }
    } 

如果文件系统发生某些变化,为什么服务在后台运行(如我在“运行服务”中所看到的),却不放弃任何日志?

完整代码:

清单

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

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!-- Adding the permission -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <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">

        <service
            android:name=".FileSystemObserverService"
            android:enabled="true"
            android:exported="true" >
        </service>
        <!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
        <receiver android:name=".StartupReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

MainActivity

package com.spicysoftware.phonesaver;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    String TAG = "Log: ";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(isReadStoragePermissionGranted()){
            Intent myIntent = new Intent(this, FileSystemObserverService.class);
            this.startService(myIntent);
        }
    }

    public  boolean isReadStoragePermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                Log.v(TAG,"Permission is granted1");
                return true;
            } else {
                Log.v(TAG,"Permission is revoked1");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 3);
                return false;
            }
        }
        else { //permission is automatically granted on sdk<23 upon installation
            Log.v(TAG,"Permission is granted1");
            return true;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {

            case 3:
                Log.d(TAG, "External storage1");
                if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
                    Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);

                }else{
                }
                break;
        }
    }

}

FileSystemOberveService

    package com.spicysoftware.phonesaver;

    import android.app.Service;
    import android.content.Intent;
    import android.os.Environment;
    import android.os.FileObserver;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Looper;
    import android.util.Log;
    import android.widget.Toast;

    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Stack;

    public class FileSystemObserverService extends Service {

        String externalPath = "";
        String internalPath = "";

        @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) {
            observe();
            return super.onStartCommand(intent, flags, startId);
        }

        public File getInternalStoragePath() {
            File parent = Environment.getExternalStorageDirectory().getParentFile();
            File external = Environment.getExternalStorageDirectory();
            File[] files = parent.listFiles();
            File internal = null;
            if (files != null) {
                for (int i = 0; i < files.length; i++) {
                    if (files[i].getName().toLowerCase().startsWith("sdcard") && !files[i].equals(external)) {
                        internal = files[i];
                    }
                }
            }

            return internal;
        }

        public File getExtenerStoragePath() {

            return Environment.getExternalStorageDirectory();
        }

        public void observe() {
            Thread t = new Thread(new Runnable() {

                @Override
                public void run() {


                    //File[]    listOfFiles = new File(path).listFiles();
                    File str = getInternalStoragePath();
                    if (str != null) {
                        internalPath = str.getAbsolutePath();

                        new Obsever(internalPath).startWatching();
                    }
                    str = getExtenerStoragePath();
                    if (str != null) {

                        externalPath = str.getAbsolutePath();
                        new Obsever(externalPath).startWatching();
                    }


                }
            });
            t.setPriority(Thread.MIN_PRIORITY);
            t.start();


        }

        class Obsever extends FileObserver {

            List<SingleFileObserver> mObservers;
            String mPath;
            int mMask;

            public Obsever(String path) {
                // TODO Auto-generated constructor stub
                this(path, ALL_EVENTS);
            }

            public Obsever(String path, int mask) {
                super(path, mask);
                mPath = path;
                mMask = mask;
                // TODO Auto-generated constructor stub

            }

            @Override
            public void startWatching() {
                // TODO Auto-generated method stub
                if (mObservers != null)
                    return;
                mObservers = new ArrayList<SingleFileObserver>();
                Stack<String> stack = new Stack<String>();
                stack.push(mPath);
                while (!stack.empty()) {
                    String parent = stack.pop();
                    mObservers.add(new SingleFileObserver(parent, mMask));
                    File path = new File(parent);
                    File[] files = path.listFiles();
                    if (files == null) continue;
                    for (int i = 0; i < files.length; ++i) {
                        if (files[i].isDirectory() && !files[i].getName().equals(".") && !files[i].getName().equals("..")) {
                            stack.push(files[i].getPath());
                        }
                    }
                }
                for (int i = 0; i < mObservers.size(); i++) {
                    mObservers.get(i).startWatching();
                }
            }

            @Override
            public void stopWatching() {
                // TODO Auto-generated method stub
                if (mObservers == null)
                    return;
                for (int i = 0; i < mObservers.size(); ++i) {
                    mObservers.get(i).stopWatching();
                }
                mObservers.clear();
                mObservers = null;
            }

            @Override
            public void onEvent(int event, final String path) {
                if (event == FileObserver.OPEN) {
                    Log.v("Event: ", "Open" + path);
                   // makeToast("Opened: "+path);
                } else if (event == FileObserver.CREATE && (!path.equals(".probe"))) {
                    Log.v("Event: ", "Create" + path);
                  //  makeToast("Created: "+path);
                } else if (event == FileObserver.DELETE_SELF || event == FileObserver.DELETE) {
                    Log.v("Event: ", "Delete" + path);
                   // makeToast("Deleted: "+path);
                } else if (event == FileObserver.MOVE_SELF || event == FileObserver.MOVED_FROM || event == FileObserver.MOVED_TO) {
                    Log.v("Event: ", "Move" + path);
                  //  makeToast("Moved: "+path);
                }
            }

            private class SingleFileObserver extends FileObserver {
                private String mPath;

                public SingleFileObserver(String path, int mask) {
                    super(path, mask);
                    // TODO Auto-generated constructor stub
                    mPath = path;
                }

                @Override
                public void onEvent(int event, String path) {
                    // TODO Auto-generated method stub
                    String newPath = mPath + "/" + path;
                    Obsever.this.onEvent(event, newPath);
                }

            }

        }

        /*
        public void makeToast(final String strMessage){
            //Let this be the code in your n'th level thread from main UI thread
            Handler h = new Handler(Looper.getMainLooper());
            h.post(new Runnable() {
                public void run() {
                    Toast.makeText(getApplicationContext(), strMessage, Toast.LENGTH_SHORT).show();
                }
            });
        }
        */

    }

StartupReceiver

    package com.spicysoftware.phonesaver;

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;

    public class StartupReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            Intent myIntent = new Intent(context, FileSystemObserverService.class);
            context.startService(myIntent);

        }
    }

0 个答案:

没有答案