Android widget get touch position

≯℡__Kan透↙ 提交于 2019-12-03 21:30:17

Maybe this will give you an idea...

PressureDynamics.java

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.util.Log;

/**
 * Keyboard sensor
 */
public class PressureDynamics extends Thread implements FeatureExtractor{

    public static final String AVG_TOUCH_PRESSURE = "Avg_Touch_Pressure";

    public static final String AVG_TOUCH_AREA = "Avg_Touch_Area";

    private static final int EVENT_BYTE_SIZE = 16;

    private InputStream _fis = null;

    private boolean _shouldRun;

    private Map<String, TouchScreenSensor> _sensors;

    public PressureDynamics(Context context, Collection<FeatureInfo> featureInfos,
        Long timeStamp){
        super("Pressure Dynamics Feature Extractor Thread");
        _shouldRun = true;

        _sensors = new HashMap<String, TouchScreenSensor>();

        int featureCount = 0;
        for (FeatureInfo featureInfo : featureInfos){
            String name = featureInfo.name;

            try{
                if (name.equalsIgnoreCase(AVG_TOUCH_PRESSURE)){
                    TouchScreenSensor s = new AvgTouchPressureSensor(featureInfo);
                    _sensors.put(AVG_TOUCH_PRESSURE, s);
                }else if (name.equalsIgnoreCase(AVG_TOUCH_AREA)){
                    TouchScreenSensor s = new AvgTouchAreaSensor(featureInfo);
                    _sensors.put(AVG_TOUCH_AREA, s);
                }else{
                    Log.e(FE_TAG, "Unhandled feature by " + getClass().getCanonicalName()
                            + ": " + name);
                    continue;
                }
                ++featureCount;
            }catch(RuntimeException e){
                Log.e(FE_TAG, "Unable to initialize feature: " + name, e);
            }
        }

        if (featureCount == 0){
            throw new FeatureExtractorInitException("No features of "
                    + getClass().getCanonicalName() + " could be initialized");
        }

        _fis = openTouchScreenInputStream();

        start();
    }

    private static InputStream openTouchScreenInputStream(){
        final String HTC_TOUCH_SCREEN_INPUT_FILEPATH = "/dev/input/event1";

        LocalServerConn localServerConn;
        try{
            localServerConn = LocalServerConn.getInstance();
            localServerConn.runLocalServer();
        }catch(Exception e){
            throw new FeatureExtractorInitException(
                    "Unable to collect Touch Screen features", e);
        }

        try{
            FileDescriptor[] fdArr = localServerConn
                    .sendFileDescriptorReq(HTC_TOUCH_SCREEN_INPUT_FILEPATH);

            if (fdArr == null || fdArr.length == 0){
                throw new FeatureExtractorInitException("Can't open keyboard device");
            }
            return new FileInputStream(fdArr[0]);
        }catch(IOException e){
            throw new FeatureExtractorInitException("Can't open keyboard input stream: "
                    + e.getMessage(), e);
        }
    }


    public void close(){
        _shouldRun = false;
    }


    public void collectData(List<MonitoredData> monitoredData, ParcelableDate endTime){
        for (Sensor s : _sensors.values()){
            s.collectData(monitoredData, endTime);
        }
    }


    public void run(){
        int n;
        int pos = 0;
        byte[] buffer = new byte[256];

        for (;;){
            try{
                n = _fis.read(buffer, pos, EVENT_BYTE_SIZE);
                /*
                 * check if we are shutting down - this may have the thread hanging around
                 * until the next touch event comes in
                 */
                if (_shouldRun == false){
                    break;
                }
                pos += n;
                // Log.v(FE_TAG, "read touch screen event: " + n + " bytes\n");
                if (pos >= EVENT_BYTE_SIZE){
                    long currentTimeMillis = System.currentTimeMillis();
                    TouchEvent touchScreenEvent = new TouchEvent(buffer,
                            currentTimeMillis);
                    updateSensors(touchScreenEvent, currentTimeMillis);
                    pos -= EVENT_BYTE_SIZE;
                }
            }catch(IOException e){
                Log.e(FE_TAG, e.getMessage(), e);
            }
        }
    }

    private void updateSensors(TouchEvent touchScreenEvent, long currentTimeMillis){
        try{
            // currently filter out all non preassure event types
            // 
            switch ((int)touchScreenEvent.getCode()){
                case TouchEvent.X_POS_EVENT:
                case TouchEvent.Y_POS_EVENT:
                case TouchEvent.TOUCH_DEVICE_TYPE_EVENT:
                    break;
                case TouchEvent.ABS_PRESSURE_EVENT:
                    _sensors.get(AVG_TOUCH_PRESSURE).updateSensor(touchScreenEvent,
                        currentTimeMillis);
                    break;
                case TouchEvent.ABS_TOOL_WIDTH_EVENT:
                    _sensors.get(AVG_TOUCH_AREA).updateSensor(touchScreenEvent,
                        currentTimeMillis);
                    break;
                default:
                    Log.e(FE_TAG, "unrecognized touch event code :"
                            + touchScreenEvent.getCode());
                    break;
            }
        }catch(Exception e){
            Log.e(FE_TAG, e.getMessage(), e);
        }
    }


    public String toString(){
        return getClass().getSimpleName();
    }

    private static abstract class TouchScreenSensor extends Sensor{
        private TouchScreenSensor(String name, FeatureInfo info){
            //super(name, info.getValueTimeout());
            super(name);
        }

        public abstract void updateSensor(TouchEvent event, long currentTimeMillis);
    }

    private static class AvgTouchPressureSensor extends TouchScreenSensor{
        public AvgTouchPressureSensor(FeatureInfo info){
            super(AVG_TOUCH_PRESSURE, info);
        }


        public void updateSensor(TouchEvent event, long currentTimeMillis){
            addToAvg(event.getValue(), currentTimeMillis);
        }
    }

    private static class AvgTouchAreaSensor extends TouchScreenSensor{
        public AvgTouchAreaSensor(FeatureInfo info){
            super(AVG_TOUCH_AREA, info);
        }


        public void updateSensor(TouchEvent event, long currentTimeMillis){
            addToAvg(event.getValue(), currentTimeMillis);
        }
    }
}

Sensor.java

import java.util.List;


public class Sensor{
    private final String _name;

    private Double _avg;

    private int _count;

    private long _lastValueUpdateTime;

    /**
     * Constructor
     * 
     * @param name The name of the feature that is collected by this sensor
     * @param valueTimeout The time period of no value changes it takes for the current
     *        value to reset to the initial value (in millis)
     */
    public Sensor(String name){
        _lastValueUpdateTime = 0;
        _name = name;
        _avg = null;
        _count = 0;
    }

    public void collectData(List<MonitoredData> monitoredData, ParcelableDate endTime){
        Double value = getValue(endTime.getTime());

        if (value != null){
            value = Utils.truncateDouble(value);
        }

        monitoredData.add(new MonitoredData(_name, value, endTime));
    }

    public Double getValue(long time){
        if (time - _lastValueUpdateTime > MainActivity.getAgentLoopTime()){
            _avg = null;
            _count = 0;
        }

        return _avg;
    }

    public String getName(){
        return _name;
    }

    public void addToAvg(double value, long time){      
        Double avg = getValue(time);

        if (avg == null){
            avg = value; // Initial value
        }else{
            value = (avg * _count + value) / (_count + 1);
        }   
        ++_count;

        _avg = value;
        _lastValueUpdateTime = time;
    }

    @Override
    public String toString(){
        return _name;
    }
}

TouchEvent.java

import android.util.Log;
import dt.util.Utils;

    public class TouchEvent{

        public static final int ABS_PRESSURE_EVENT = 0x18;

        public static final int ABS_TOOL_WIDTH_EVENT = 0x1c;

        public static final int X_POS_EVENT = 0x0;

        public static final int Y_POS_EVENT = 0x1;

        /* type of touching device ie. finger, stylus etc. */
        public static final int TOUCH_DEVICE_TYPE_EVENT = 0x14a;

        // private final long _timeStamp;

        // private final int _sec;

        // private final int _usec;

        // 3, 1, 0 - ?
        // private final long _type;

        // different event types have different codes
        private final long _code;

        private final int _value;

        // 
        public TouchEvent(byte[] _buffer, long currentTimeMillis){
            int pos;
            byte b[] = new byte[4];
            byte s[] = new byte[2];

            // _timeStamp = currentTimeMillis;

            pos = 0;
            // _sec = Utils.LittleEndianBytesToInt(_buffer);
            pos += 4;
            System.arraycopy(_buffer, pos, b, 0, 4);
            // _usec = Utils.LittleEndianBytesToInt(b);
            pos += 4;
            // _type = Utils.LittleEndianBytesToUShort(s);
            pos += 2;
            System.arraycopy(_buffer, pos, s, 0, 2);
            _code = Utils.littleEndianBytesToUShort(s);
            pos += 2;
            System.arraycopy(_buffer, pos, b, 0, 4);
            _value = Utils.littleEndianBytesToInt(b);

            if (_code != X_POS_EVENT && _code != Y_POS_EVENT
                    && _code != TOUCH_DEVICE_TYPE_EVENT && _code != ABS_PRESSURE_EVENT
                    && _code != ABS_TOOL_WIDTH_EVENT){
                Log.d(FE_TAG, "unrecognized touch event code :" + _code);
            }
        }

        public long getCode(){
            return _code;
        }

        public double getValue(){
            return _value;
        }
    }

FeatureInfo.java

import java.util.HashMap;

public class FeatureInfo{
    /** The name of the feature */
    public final String name;

    /** The parameters relevant to the feature */
    public final HashMap<String, String> params;

    /**
     * Constructs a FeatureInfo object from the given parameters
     * 
     * @param name The name of the feature
     * @param params The parameters relevant to the feature
     */
    public FeatureInfo(String name, HashMap<String, String> params){
        this.name = name;
        this.params = (params == null) ? new HashMap<String, String>() : params;
    }

    @Override
    public String toString(){
        return name;
    }

    public int getTimeWindow() throws IllegalArgumentException{
        final String paramName = "Time_Window";
        try{
            int timeWindow = Integer.parseInt(params.get(paramName)) * 1000;
            if (timeWindow <= 0){
                throw new IllegalArgumentException("Must be a positive integer");
            }
            return timeWindow;
        }catch(Exception e){// NullPointer or Parsing
            throw new IllegalArgumentException("Corrupt parameter: " + paramName
                    + " in feature " + name, e);
        }
    }

//  public int getTimeWindow() throws IllegalArgumentException{
//      final String paramName = "Time_Window";
//      try{
//          int timeWindow = Integer.parseInt(params.get(paramName)) * 1000;
//          if (timeWindow <= 0){
//              throw new IllegalArgumentException("Must be a positive integer");
//          }
//          return timeWindow;
//      }catch(Exception e){// NullPointer or Parsing
//          throw new IllegalArgumentException("Corrupt parameter: " + paramName
//                  + " in feature " + name, e);
//      }
//  }

    public int getValueTimeout() throws IllegalArgumentException{
        final String paramName = "Value_Timeout";
        try{
            int valueTimeout = Integer.parseInt(params.get(paramName)) * 1000;
            if (valueTimeout <= 0){
                throw new IllegalArgumentException("Must be a positive integer");
            }
            return valueTimeout;
        }catch(Exception e){// NullPointer or Parsing
            throw new IllegalArgumentException("Corrupt parameter: " + paramName
                    + " in feature " + name, e);
        }
    }

    public double getMovieAverageWeight() throws IllegalArgumentException{
        final String paramName = "Moving_Average_Weight";
        try{
            double movingAverageWeight = Double.parseDouble(params.get(paramName));
            if (movingAverageWeight < 0 || movingAverageWeight > 1){
                throw new IllegalArgumentException("Must be positive and 1.0 at most");
            }
            return movingAverageWeight;
        }catch(Exception e){// NullPointer or Parsing
            throw new IllegalArgumentException("Corrupt parameter: " + paramName
                    + " in feature " + name, e);
        }
    }

    public boolean getIncludeEventTimes(){
        final String paramName = "Include_Event_Times";
        return Boolean.parseBoolean(params
            .get(paramName));
    }

    public boolean getIncludeMaximalEntity(){
        final String paramName = "Include_Maximal_Entity";
        return Boolean.parseBoolean(params
            .get(paramName));
    }
}

MonitoredData.java

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

@SuppressWarnings("unchecked")
public class MonitoredData implements Map, Parcelable{
    public static final int DEFAULT = 0;

    public static final int HAS_EXTRAS = 1;

    protected String _name;

    protected ParcelableDate _startTime, _endTime;

    protected Object _value;

    protected Bundle _extras;

    public static final Parcelable.Creator<MonitoredData> CREATOR = new Parcelable.Creator<MonitoredData>(){
        public MonitoredData createFromParcel(Parcel in){
            ClassLoader cl = ParcelableDate.class.getClassLoader();
            String name = in.readString();
            Object value = in.readValue(null);
            ParcelableDate startTime = (ParcelableDate)in.readParcelable(cl);
            ParcelableDate endTime = (ParcelableDate)in.readParcelable(cl);
            Bundle extras = in.readBundle();
            MonitoredData monitoredData = new MonitoredData(name, value, startTime,
                    endTime);
            if (extras != null){
                monitoredData.setExtras(extras);
            }
            return monitoredData;
        }

        public MonitoredData[] newArray(int size){
            return new MonitoredData[size];
        }
    };

    private static DateFormat _sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");

    public MonitoredData(String name, Object value, Date endTime){
        this(name, value, new ParcelableDate(endTime), new ParcelableDate(endTime));
    }

    public MonitoredData(String name, Object value, ParcelableDate endTime){
        this(name, value, endTime, endTime);
    }

    public MonitoredData(String name, Object value, Date startTime, Date endTime){
        this(name, value, new ParcelableDate(startTime), new ParcelableDate(endTime));
    }

    public MonitoredData(String name, Object value, Date startTime, ParcelableDate endTime){
        this(name, value, new ParcelableDate(startTime), endTime);
    }

    public MonitoredData(String name, Object value, ParcelableDate startTime,
        ParcelableDate endTime){
        _name = name;
        _startTime = startTime;
        _endTime = endTime;
        _value = value;
        _extras = null;
    }

    public void setExtras(Bundle extras){
        _extras = extras;
    }

    public Map<String, Object> toMap(){
        TreeMap<String, Object> map = new TreeMap<String, Object>();
        map.put("Name", _name);
        map.put("StartTime", _startTime);
        map.put("EndTime", _endTime);
        map.put("Value", _value);
        return map;
    }

    public String conciseToString(){
        String extrasToString = (_extras != null && !_extras.isEmpty()) ? " - "
                + _extras.toString() : "";
        return "{" + getName() + " = " + getValue() + "}" + extrasToString;
    }


    public int describeContents(){
        return (_extras == null || _extras.isEmpty()) ? DEFAULT : HAS_EXTRAS;
    }

    public ParcelableDate getEndTime(){
        return _endTime;
    }

    public String getName(){
        return _name;
    }

    public ParcelableDate getStartTime(){
        return _startTime;
    }

    public Object getValue(){
        return _value;
    }

    public Bundle getExtras(){
        return _extras;
    }


    public String toString(){
        StringBuilder sb = new StringBuilder("{");
        sb.append("Name = " + getName() + ", ");
        sb.append("Value = " + getValue() + ", ");
        sb.append("StartTime = " + _sdf.format(getStartTime()) + ", ");
        sb.append("EndTime = " + _sdf.format(getEndTime()));
        sb.append("}");
        return sb.toString();
    }


    public void writeToParcel(Parcel dest, int flags){
        dest.writeString(getName());
        dest.writeValue(getValue());
        dest.writeParcelable(getStartTime(), 0);
        dest.writeParcelable(getEndTime(), 0);
        dest.writeBundle(_extras);
    }


    public void clear(){
        throw new UnsupportedOperationException();
    }


    public boolean containsKey(Object key){
        throw new UnsupportedOperationException();
    }


    public boolean containsValue(Object value){
        throw new UnsupportedOperationException();
    }


    public Set entrySet(){
        return Collections.unmodifiableSet(toMap().entrySet());
    }


    public Object get(Object key){
        throw new UnsupportedOperationException();
    }


    public boolean isEmpty(){
        throw new UnsupportedOperationException();
    }


    public Set keySet(){
        throw new UnsupportedOperationException();
    }


    public Object put(Object key, Object value){
        throw new UnsupportedOperationException();
    }


    public void putAll(Map arg0){
        throw new UnsupportedOperationException();
    }


    public Object remove(Object key){
        throw new UnsupportedOperationException();
    }


    public int size(){
        throw new UnsupportedOperationException();
    }


    public Collection values(){
        throw new UnsupportedOperationException();
    }

    /**
     * Returns the value of the monitored data as a Double. 
     * Null is returned if the value is null or is can not be converted to double.
     * 
     * @return The value as double if possible, null otherwise
     */
    public Double mdToDouble(){
        Double sample;
        Object val = getValue();
        if (val instanceof Double){
            sample = ((Double)val).doubleValue();
        }else if (val instanceof Long){
            sample = ((Long)val).doubleValue();
        }else if (val instanceof Integer){
            sample = ((Integer)val).doubleValue();
        }else{
            sample = null;
        }
        return sample;
    }
}

Utils.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.Context;
import android.content.res.Resources;
import android.os.Environment;
import android.widget.Toast;

public class Utils{
    public static byte[] append(byte[] first, byte[] second){
        byte[] bytes;

        bytes = new byte[first.length + second.length];
        System.arraycopy(first, 0, bytes, 0, first.length);
        System.arraycopy(second, 0, bytes, first.length, second.length);

        return bytes;
    }

    public static int bytesToInt(byte[] bytes){
        return (bytes[3] & 0xFF) | ((bytes[2] & 0xFF) << 8) | ((bytes[1] & 0xFF) << 16)
                | ((bytes[0] & 0xFF) << 24);
    }

    public static int littleEndianBytesToInt(byte[] bytes){
        return (bytes[0] & 0xFF) | ((bytes[1] & 0xFF) << 8) | ((bytes[2] & 0xFF) << 16)
                | ((bytes[3] & 0xFF) << 24);
    }

    public static long littleEndianBytesToUShort(byte[] arr){
        return (arr[1] << 8) | arr[0];
    }

    public static void displayShortAlert(Context context, String message){
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
    }

    public static XmlPullParser getXPP(Context context, int resourceId, boolean isBinary){
        XmlPullParser xpp;
        Resources resources = context.getResources();

        if (isBinary){
            return resources.getXml(resourceId);
        }else{
            try{
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                xpp = factory.newPullParser();
                xpp.setInput(resources.openRawResource(resourceId), null);
            }catch(XmlPullParserException e){
                xpp = null;
            }
            return xpp;
        }
    }

    public static byte[] intToBytes(int i){
        byte[] bytes = new byte[]{(byte)((i >> 24) & 0xff), (byte)((i >> 16) & 0xff),
                (byte)((i >> 8) & 0xff), (byte)((i) & 0xff)};
        return bytes;
    }

    /*
     * debugging
     */
    public static String printByteArray(byte[] bytes, int len){
        StringBuilder sb = new StringBuilder();
        sb.append("msg len: " + len + " :");
        Formatter f = new Formatter(sb);
        for (int i = 0; i < len; i++){
            f.format("%2x", bytes[i]);
        }
        sb.append("\n");
        return sb.toString();
    }

    public static List<Integer> getPids(String fileName){
        String line;
        int pidIndex = -1;

        try{
            Process p = Runtime.getRuntime().exec("ps " + fileName);
            p.waitFor();

            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()), 256);
            if ((line = br.readLine()) == null){
                throw new IllegalStateException("Unable to read ps output");
            }
            String[] tokens = line.split(" +");
            for (int i = 0; i < tokens.length; ++i){
                if (tokens[i].equalsIgnoreCase("pid")){
                    pidIndex = i;
                }
            }
            if (pidIndex < 0){
                throw new IllegalStateException("Unable to locate pid field in ps output");
            }

            List<Integer> pids = new ArrayList<Integer>();
            while ((line = br.readLine()) != null){
                tokens = line.split(" +");
                assert tokens.length < 9;

                try{
                    pids.add(Integer.parseInt(tokens[pidIndex]));
                }catch(NumberFormatException e){
                    throw new IllegalStateException("Pid is not an integer");
                }
            }

            br.close();
            return pids;
        }catch(Exception e){
            throw new IllegalStateException("Unable to read running process through ps: "
                    + e.getMessage(), e);
        }

    }

    public static void killProcesses(List<Integer> pids){
        for (Integer pid : pids){
            android.os.Process.killProcess(pid);
        }
    }

    public static void killProcesses(String processName){
        killProcesses(getPids(processName));
    }

    public static void suKillProcesses(List<Integer> pids){
        StringBuilder cmd = new StringBuilder("kill");
        for (Integer pid : pids){
            cmd.append(" ").append(pid);
        }
        try{
            Runtime.getRuntime().exec(new String[]{"su", "-c", cmd.toString()});
        }catch(IOException e){
            e.printStackTrace();
        }
    }

    public static void suKillProcess(int pid){
        try{
            Runtime.getRuntime().exec(new String[]{"su", "-c", "kill " + pid});
        }catch(IOException e){
            e.printStackTrace();
        }
    }

    public static void suKillProcesses(String processName){
        suKillProcesses(getPids(processName));
    }

    public static double truncateDouble(double d){
        long l = Math.round(d * 100);
        return l / 100.0;
    }

    public static double calcMovingAvg(double oldVal, double newVal, double newValWeight){
        return (oldVal * (1.0 - newValWeight)) + (newValWeight * newVal);
    }

    public static double calcAvg(double oldAvg, int count, double newVal){
        return (oldAvg * count + newVal) / (count + 1);
    }

    public static void writeLogToFile(Context context, boolean onSdcard, String prefix, int timeWindowInSeconds) throws Exception{
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss");
        final DateFormat logDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        final long currentTime = System.currentTimeMillis();
        final long startTime = currentTime - timeWindowInSeconds * 1000;
        final String currentYear = Calendar.getInstance().get(Calendar.YEAR) + "-";
        final String logFileName = prefix + sdf.format(new Date(currentTime)) + ".log";
        BufferedReader logcatIn;
        Process logcat;
        OutputStream logFile;

        try{
            logcat = Runtime.getRuntime().exec("logcat -v time -d *:d");
            logcatIn = new BufferedReader(new InputStreamReader(logcat
                    .getInputStream()), 1024);
        }catch(IOException e){
            throw new Exception("Unable to launch logcat: " + e.getMessage(), e);
        }

        try{
            if (onSdcard){
                logFile = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), logFileName));
            }else{
                logFile = context.openFileOutput(logFileName, 0);               
            }
        }catch(IOException e){
            throw new Exception("Unable to create log file: " + e.getMessage(), e);         
        }
        PrintWriter pw = new PrintWriter(logFile, false);

        String line;
        long logLineTime;
        while ((line = logcatIn.readLine()) != null){
            logLineTime = logDF.parse(currentYear + line.substring(0, line.indexOf(".") + 4)).getTime();
            if (logLineTime >= startTime){
                pw.println(line);
            }
        }

        pw.flush();
        pw.close();
        logcatIn.close();
        logcat.destroy();
    }
}

FeatureExtractor.java

import java.util.List;

/**
 * A class capable of extracting one or more features. It MUST have a public constructor
 * with the following parameters in this order:
 * <ul>
 * <li>Context context</li>
 * <li>Collection&lt;FeatureInfo&gt; featureInfos</li>
 * <li>Long timeStamp</li>
 * </ul>
 * 
 */
public interface FeatureExtractor{
    /**
     * Invoked during a data collection. It is up to the extractor to add the data
     * relevant to it's monitored features to the monitoredData list.
     * 
     * @param monitoredData The overall collected data (from all extractors) so far
     * @param endTime The time of the current data collection
     */
    public void collectData(List<MonitoredData> monitoredData, ParcelableDate endTime);

    /**
     * Invoked when the feature extractor is no longer needed. This is the place to
     * release any resources, unregister any listeners, close any threads, etc.
     */
    public void close();
}

FeatureExtractorInitException.java

public class FeatureExtractorInitException extends RuntimeException{
    private static final long serialVersionUID = 1L;

    public FeatureExtractorInitException(String message){
        super(message);
    }

    public FeatureExtractorInitException(String message, Throwable t){
        super(message, t);
    }

    public FeatureExtractorInitException(Throwable t){
        super(t);
    }
}
reuf

For example if you had an imageView one way of fetching coordinates is...

imageView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {
            int[] values = new int[2]; 
            view.getLocationOnScreen(values);
            Log.d("X & Y",values[0]+" "+values[1]);
        }
    });

Check out these ST threads:

If you use reuf codes,you will need to use ParcelableData.java.I add ParcelableData class that found here and hope to save your time:

package dev.drsoran.moloko.service.parcel;

import java.util.Date;

import android.os.Parcel;
import android.os.Parcelable;


public class ParcelableDate implements Parcelable
{

   public static final Parcelable.Creator< ParcelableDate > CREATOR = new Parcelable.Creator< ParcelableDate >()
   {

      public ParcelableDate createFromParcel( Parcel source )
      {
         return new ParcelableDate( source );
      }



      public ParcelableDate[] newArray( int size )
      {
         return new ParcelableDate[ size ];
      }

   };

   private final Date date;



   public ParcelableDate( final Date date )
   {
      this.date = date;
   }



   public ParcelableDate( long millis )
   {
      this.date = new Date( millis );
   }



   public ParcelableDate( Parcel source )
   {
      date = new Date( source.readLong() );
   }



   public Date getDate()
   {
      return date;
   }



   @Override
   public String toString()
   {
      return date.toString();
   }



   public int describeContents()
   {
      return 0;
   }



   public void writeToParcel( Parcel dest, int flags )
   {
      dest.writeLong( date.getTime() );
   }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!