Ignore:
Timestamp:
12/15/14 13:35:23 (10 years ago)
Author:
funger
Message:
Location:
trunk/autoquest-androidmonitor/src/main/java/de/ugoe/cs/autoquest/androidmonitor
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-androidmonitor/src/main/java/de/ugoe/cs/autoquest/androidmonitor/AndroidMonitor.java

    r1833 r1842  
    1919import de.ugoe.cs.autoquest.androidmonitor.AndroidMonitorCompositeOnClickListener; 
    2020import android.app.Activity; 
    21 import android.content.Context; 
    22 import android.content.pm.ApplicationInfo; 
    23 import android.content.pm.PackageManager; 
    24 import android.content.pm.PackageManager.NameNotFoundException; 
    2521import android.os.Build; 
    2622import android.text.Editable; 
     
    4844     * </p> 
    4945     */ 
    50     String activityName; 
     46    private String activityName; 
    5147 
    5248    /** 
     
    5551     * </p> 
    5652     */ 
    57     private AndroidMonitorLogFile logFile; 
     53    private static AndroidMonitorLogFile logFile = null; 
    5854 
    5955    /** 
     
    6662        return monitor; 
    6763    } 
     64    
    6865 
    6966    /** 
     
    7370     */ 
    7471    public void startMonitor(Activity activity) { 
    75         activityName = activity.getClass().getSimpleName(); 
    76  
    77         logFile = new AndroidMonitorLogFile(getAppLable(activity), activity.getFilesDir()); 
    78  
     72        //create logFile only once 
     73        if(AndroidMonitor.logFile == null){ 
     74            AndroidMonitor.logFile = new AndroidMonitorLogFile(activity); 
     75            Log.i("logfile", "file created"); 
     76        } 
     77        activityName = activity.getClass().getSimpleName();   
    7978        addLogListenerToView(getRootView(activity)); 
     79         
    8080 
    8181        // TODO 
    8282        // listen to changes and update own listener 
    83         // find out if it is possible to directly call addLogListenerToView 
    84         // again 
    85         // activity.onContentChanged(); 
    8683 
    8784        // write backPresss as event to xml file 
     
    9390        // http://developer.android.com/training/basics/activity-lifecycle/stopping.html 
    9491    } 
    95  
    96     /** 
    97      * get the root view of an activity 
     92    public void startMonitor(View view){ 
     93        addLogListenerToView(findFirstView(view)); 
     94    } 
     95     
     96    /** 
     97     * Get the root view of an activity. 
    9898     *  
    9999     * @param activity 
    100100     * @return 
    101101     */ 
    102     public View getRootView(Activity activity) { 
     102    private View getRootView(Activity activity) { 
    103103        // get root view of the activity as start point 
    104104        View view = activity.getWindow().getDecorView().getRootView(); 
     
    111111 
    112112    /** 
    113      * returns first view element of the tree 
     113     * Returns first view element of the tree. 
    114114     *  
    115115     * @param view 
     
    127127    /** 
    128128     * Replace the listener of each view with a composite listener which collects several listeners 
    129      * for one view. 
     129     * for one view. Add a TextWatcher to all TexView views. 
    130130     *  
    131131     * @param view 
    132132     *            to be monitored 
    133133     */ 
    134     public void addLogListenerToView(View view) { 
     134    private void addLogListenerToView(View view) { 
    135135        addLogListenerToView(view, 0); 
    136136    } 
     
    147147    private void addLogListenerToView(View view, int parentHash) { 
    148148 
    149         if (!logFile.isComponentLogged(view.hashCode())) { 
    150             logFile.addComponent(view, parentHash, activityName); 
     149        if (!AndroidMonitorLogFile.isComponentLogged(view.hashCode())) { 
     150            AndroidMonitor.logFile.addComponent(view, parentHash, activityName); 
     151 
     152            // save original listener to add it later on to the groupLisatener 
     153            View.OnClickListener onClickListener = getOnClickListener(view); 
     154 
     155            if (onClickListener != null) { 
     156                // create new compositeOnClickListener to handle multiple listeners 
     157                // for one view 
     158                AndroidMonitorCompositeOnClickListener groupListener = 
     159                    new AndroidMonitorCompositeOnClickListener(); 
     160                // replace the original onClickListener with the 
     161                // compositeOnClickListener 
     162                view.setOnClickListener(groupListener); 
     163                // add the tracking part as a several listener 
     164                groupListener.addOnClickListener(new View.OnClickListener() { 
     165                    public void onClick(View v) { 
     166 
     167                        AndroidMonitor.logFile.addEvent(v, "onClick"); 
     168                        // check if something changed in the activity 
     169                        startMonitor(v); 
     170                    } 
     171                }); 
     172 
     173                groupListener.addOnClickListener(onClickListener); 
     174            } 
     175            // if view is a TextView add a addTextChangedListener to this view 
     176            if (view instanceof TextView) { 
     177                final int hashOfView = view.hashCode(); 
     178                TextView textView = (TextView) view; 
     179                textView.addTextChangedListener(new TextWatcher() { 
     180                    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     181                        // do nothing 
     182                    } 
     183 
     184                    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     185                        // do nothing 
     186                    } 
     187 
     188                    public void afterTextChanged(Editable s) { 
     189                        AndroidMonitor.logFile.addEvent(hashOfView, "text", s.toString()); 
     190                    } 
     191 
     192                }); 
     193            } 
    151194        } 
    152195 
    153196        // hash code of the actual view element. Problem in using 
    154197        // view.getParent().hashCode() is described in 
    155         // de.ugoe.cs.autoquest.androidmonitor#addComponent() 
     198        // de.ugoe.cs.autoquest.androidmonitor.AndroidMonitorLogFile#addComponent() 
    156199        parentHash = view.hashCode(); 
    157200        // traverse all views of the activity 
     
    164207        } 
    165208 
    166         // save original listener to add it later on to the groupLisatener 
    167         View.OnClickListener onClickListener = getOnClickListener(view); 
    168  
    169         if (onClickListener != null) { 
    170             // create new compositeOnClickListener to handle multiple listeners 
    171             // for one view 
    172             AndroidMonitorCompositeOnClickListener groupListener = 
    173                 new AndroidMonitorCompositeOnClickListener(); 
    174             // replace the original onClickListener with the 
    175             // compositeOnClickListener 
    176             view.setOnClickListener(groupListener); 
    177             // add the tracking part as a several listener 
    178             groupListener.addOnClickListener(new View.OnClickListener() { 
    179                 public void onClick(View v) { 
    180  
    181                     logFile.addEvent(v, "onClick"); 
    182                 } 
    183             }); 
    184  
    185             groupListener.addOnClickListener(onClickListener); 
    186         } 
    187         // if view is a TextView add a addTextChangedListener to this view 
    188         if (view instanceof TextView) { 
    189             final int hashOfView = view.hashCode(); 
    190             TextView textView = (TextView) view; 
    191             textView.addTextChangedListener(new TextWatcher() { 
    192                 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
    193                     // do nothing 
    194                 } 
    195  
    196                 public void onTextChanged(CharSequence s, int start, int before, int count) { 
    197                     // do nothing 
    198                 } 
    199  
    200                 public void afterTextChanged(Editable s) { 
    201                     logFile.addEvent(hashOfView, "text", s.toString()); 
    202                 } 
    203  
    204             }); 
    205         } 
    206209    } 
    207210 
     
    212215     * @return the listener of the view or null if no listener exists 
    213216     */ 
    214     public View.OnClickListener getOnClickListener(View view) { 
     217    private View.OnClickListener getOnClickListener(View view) { 
    215218        // http://stackoverflow.com/questions/11186960/getonclicklistener-in-android-views 
    216219        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
     
    280283    } 
    281284 
    282     /** 
    283      * get application name as defined in Package Name 
    284      *  
    285      * @param pContext 
    286      *            package context; could also be an activity 
    287      * @return app name 
    288      */ 
    289     public String getAppLable(Context pContext) { 
    290         // source (2014-09-04): 
    291         // http://stackoverflow.com/questions/11229219/android-get-application-name-not-package-name 
    292         PackageManager lPackageManager = pContext.getPackageManager(); 
    293         ApplicationInfo lApplicationInfo = null; 
    294         try { 
    295             lApplicationInfo = 
    296                 lPackageManager.getApplicationInfo(pContext.getApplicationInfo().packageName, 0); 
    297         } 
    298         catch (final NameNotFoundException e) {} 
    299         return (String) (lApplicationInfo != null ? lPackageManager 
    300             .getApplicationLabel(lApplicationInfo) : "Unknown"); 
     285     
     286     
     287    /** 
     288     *  
     289     * <p> 
     290     * Return the AndroidMonitorLogFile that is used in the AndroidMonitor. 
     291     * </p> 
     292     * 
     293     * @return AndroidMonitorLogFile  
     294     *          that is used in the AndroidMonitor. 
     295     */ 
     296    public AndroidMonitorLogFile getLogFile(){ 
     297        return logFile;         
    301298    } 
    302299} 
  • trunk/autoquest-androidmonitor/src/main/java/de/ugoe/cs/autoquest/androidmonitor/AndroidMonitorLogFile.java

    r1833 r1842  
    2525import org.xmlpull.v1.XmlSerializer; 
    2626 
     27import android.app.Activity; 
     28import android.content.Context; 
     29import android.content.pm.ApplicationInfo; 
     30import android.content.pm.PackageManager; 
     31import android.content.pm.PackageManager.NameNotFoundException; 
    2732import android.util.Log; 
    2833import android.util.Xml; 
    2934import android.view.View; 
    3035import android.view.ViewGroup; 
     36import android.widget.ImageView; 
     37import android.widget.TextView; 
    3138 
    3239/** 
    3340 * <p> 
    34  * TODO comment 
     41 * Writes informations about the device, the application, the components of the activity and the 
     42 * events in a log file. File is stored in the space of the application. Path is normally internal 
     43 * storage: data/data/<package name of the application using the AndroidMonitor>/files/ e.g. 
     44 * data/data/de.ugoe.cs.autoquest.androidmonitor.testApp/files/ 
    3545 * </p> 
    3646 *  
     
    4555     * </p> 
    4656     */ 
    47     private String name; 
    48      
    49     /** 
    50      * <p> 
    51      * File representation to store monitored information.  
    52      * </p> 
    53      */ 
    54     private File file; 
    55      
     57    private static String name; 
     58 
     59    /** 
     60     * <p> 
     61     * Name of the Application which is monitored. 
     62     * </p> 
     63     */ 
     64    private static String appName; 
     65 
     66    /** 
     67     * <p> 
     68     * File representation to store monitored information. 
     69     * </p> 
     70     */ 
     71    private static File file; 
     72 
    5673    /** 
    5774     * <p> 
     
    5976     * </p> 
    6077     */ 
    61     private List<Integer> currentLoggedComponents; 
     78    private static List<Integer> currentLoggedComponents; 
    6279 
    6380    /** 
     
    6683     * Constructor. Creates a new AndroidmonitorLogFile. 
    6784     * </p> 
    68      * 
     85     *  
    6986     * @param appName 
    70      *          Name of the calling application. 
     87     *            Name of the calling application. 
    7188     * @param dir 
    72      *          Folder to store the log file. 
    73      */ 
    74     public AndroidMonitorLogFile(String appName, File dir) { 
    75          
    76         currentLoggedComponents = new ArrayList<Integer>(); 
    77          
    78         this.name = "androidLogFile_" + appName + System.currentTimeMillis() + ".log"; 
    79  
    80         try { 
    81                 // prove if file exists 
    82                 this.file = new File(dir, this.name); 
    83                 /* 
    84                  * if file does not exists write device and app information to a new 
    85                  * file. Otherwise use existing file and add activity information to 
    86                  * file. 
    87                  */ 
    88                 // TODO prove if file exists and add activity information 
    89                 if (true) { // !this.file.exists() 
    90                         /* 
    91                          * create log file. Using method openFileOutput() does not work 
    92                          * for this project due to the reason that this method would try 
    93                          * to create the file in the directory of the non-existing 
    94                          * directory de.ugoe.cs.androidmonitor. This directory does not 
    95                          * exist due to the reason that this project is a library and 
    96                          * the file has to be stored in the directory of the running 
    97                          * application. Furthermore it would not be possible to write in 
    98                          * another app directory as the own one. 
    99                          */ 
    100  
    101                         String string = "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><sessions>"; 
    102                          
    103                         try { 
    104                                 FileOutputStream outputStream = new FileOutputStream( 
    105                                                 this.file); 
    106                                 outputStream.write(string.getBytes()); 
    107                                 outputStream.close(); 
    108                         } catch (Exception e) { 
    109                                 Log.e("this.file", "outputstream: " + e.getMessage()); 
    110                         } 
    111                          
    112                         setDeviceInformation(); 
    113                         setAppInformation(); 
    114  
    115                 }  
    116                 /*else { 
    117                         // TODO add activity information 
    118                 }*/ 
    119         } catch (Exception e) { 
    120                 e.printStackTrace(); 
    121                 Log.e("file", "file: " + e.getMessage()); 
    122         } 
     89     *            Folder to store the log file. 
     90     */ 
     91    public AndroidMonitorLogFile(Activity activity) { 
     92 
     93        AndroidMonitorLogFile.currentLoggedComponents = new ArrayList<Integer>(); 
     94 
     95        AndroidMonitorLogFile.appName = getAppLable(activity); 
     96 
     97        createFile(activity); 
    12398    } 
    12499 
     
    128103     * Get file name which is in use. 
    129104     * </p> 
    130      * 
     105     *  
    131106     * @return filename 
    132107     */ 
    133     public String getFileName() { 
    134             return this.name; 
     108    public static String getFileName() { 
     109        return AndroidMonitorLogFile.name; 
     110    } 
     111 
     112    /** 
     113     * Get application name as defined in Package Name 
     114     *  
     115     * @param pContext 
     116     *            package context; could also be an activity 
     117     * @return app name 
     118     */ 
     119    private String getAppLable(Context pContext) { 
     120        // source: 
     121        // http://stackoverflow.com/questions/11229219/android-get-application-name-not-package-name 
     122        // (last call 2014-09-04) 
     123        PackageManager lPackageManager = pContext.getPackageManager(); 
     124        ApplicationInfo lApplicationInfo = null; 
     125        try { 
     126            lApplicationInfo = 
     127                lPackageManager.getApplicationInfo(pContext.getApplicationInfo().packageName, 0); 
     128        } 
     129        catch (final NameNotFoundException e) {} 
     130        return (String) (lApplicationInfo != null ? lPackageManager 
     131            .getApplicationLabel(lApplicationInfo) : "Unknown"); 
     132    } 
     133 
     134    /** 
     135     *  
     136     * <p> 
     137     * Get package Name. 
     138     * </p> 
     139     *  
     140     * @param pContext 
     141     *            package context; could also be an activity 
     142     * @return package name 
     143     */ 
     144    private String getAppPackageName(Context pContext) { 
     145        return pContext.getPackageName(); 
    135146    } 
    136147 
     
    140151     * Writes information about the application to the log file. 
    141152     * </p> 
    142      * 
    143      */ 
    144     private void setAppInformation() { 
    145             // TODO create app information in the same manner as coded in 
    146             // getDeviceInformation 
    147              
     153     *  
     154     * @param activity 
     155     *  
     156     */ 
     157    private void setAppInformation(Activity activity) { 
     158 
     159        XmlSerializer serializer = Xml.newSerializer(); 
     160        StringWriter writer = new StringWriter(); 
     161        try { 
     162            serializer.setOutput(writer); 
     163 
     164            serializer.startTag("", "application"); 
     165 
     166            serializer.startTag("", "param"); 
     167            serializer.attribute("", "value", getAppPackageName(activity)); 
     168            serializer.attribute("", "name", "package"); 
     169            serializer.endTag("", "param"); 
     170 
     171            serializer.startTag("", "param"); 
     172            serializer.attribute("", "value", getAppLable(activity)); 
     173            serializer.attribute("", "name", "name"); 
     174            serializer.endTag("", "param"); 
     175 
     176            serializer.endTag("", "application"); 
     177            serializer.endDocument(); 
     178 
     179            writeToFile(writer.toString()); 
     180        } 
     181        catch (IllegalArgumentException e) { 
     182            e.printStackTrace(); 
     183            Log.e("file", "outputstream: " + e.getMessage()); 
     184        } 
     185        catch (IllegalStateException e) { 
     186            e.printStackTrace(); 
     187            Log.e("file", "outputstream: " + e.getMessage()); 
     188        } 
     189        catch (IOException e) { 
     190            e.printStackTrace(); 
     191            Log.e("file", "outputstream: " + e.getMessage()); 
     192        } 
    148193    } 
    149194 
     
    155200     */ 
    156201    private void setDeviceInformation() { 
    157             
    158             XmlSerializer serializer = Xml.newSerializer(); 
    159             StringWriter writer = new StringWriter(); 
    160             try { 
    161                     serializer.setOutput(writer); 
    162                     serializer.startTag("", "device"); 
    163                     serializer.startTag("", "param"); 
    164                     serializer.attribute("", "value", "" 
    165                                     + android.os.Build.VERSION.SDK_INT); 
    166                     serializer.attribute("", "name", "sdk_version"); 
    167                     serializer.endTag("", "param"); 
    168  
    169                     serializer.startTag("", "param"); 
    170                     serializer.attribute("", "value", android.os.Build.DEVICE); 
    171                     serializer.attribute("", "name", "device"); 
    172                     serializer.endTag("", "param"); 
    173  
    174                     serializer.startTag("", "param"); 
    175                     serializer.attribute("", "value", android.os.Build.MANUFACTURER); 
    176                     serializer.attribute("", "name", "manufacturer"); 
    177                     serializer.endTag("", "param"); 
    178  
    179                     serializer.startTag("", "param"); 
    180                     serializer.attribute("", "value", android.os.Build.MODEL); 
    181                     serializer.attribute("", "name", "model"); 
    182                     serializer.endTag("", "param"); 
    183  
    184                     // TODO get resolution ... 
    185  
    186                     serializer.endTag("", "device"); 
    187                     serializer.endDocument(); 
    188                      
    189                     writeToFile(writer.toString()); 
    190  
    191             } catch (IllegalArgumentException e) { 
    192                 // TODO Auto-generated catch block 
    193                 e.printStackTrace(); 
    194                 Log.e("file", "outputstream: " + e.getMessage()); 
    195             } catch (IllegalStateException e) { 
    196                     // TODO Auto-generated catch block 
    197                     e.printStackTrace(); 
    198                     Log.e("file", "outputstream: " + e.getMessage()); 
    199             } catch (IOException e) { 
    200                     // TODO Auto-generated catch block 
    201                     e.printStackTrace(); 
    202                     Log.e("file", "outputstream: " + e.getMessage()); 
    203             } 
    204  
    205              
     202 
     203        XmlSerializer serializer = Xml.newSerializer(); 
     204        StringWriter writer = new StringWriter(); 
     205        try { 
     206            serializer.setOutput(writer); 
     207            serializer.startTag("", "device"); 
     208            serializer.startTag("", "param"); 
     209            serializer.attribute("", "value", "" + android.os.Build.VERSION.SDK_INT); 
     210            serializer.attribute("", "name", "sdk_version"); 
     211            serializer.endTag("", "param"); 
     212 
     213            serializer.startTag("", "param"); 
     214            serializer.attribute("", "value", android.os.Build.DEVICE); 
     215            serializer.attribute("", "name", "device"); 
     216            serializer.endTag("", "param"); 
     217 
     218            serializer.startTag("", "param"); 
     219            serializer.attribute("", "value", android.os.Build.MANUFACTURER); 
     220            serializer.attribute("", "name", "manufacturer"); 
     221            serializer.endTag("", "param"); 
     222 
     223            serializer.startTag("", "param"); 
     224            serializer.attribute("", "value", android.os.Build.MODEL); 
     225            serializer.attribute("", "name", "model"); 
     226            serializer.endTag("", "param"); 
     227 
     228            // TODO get resolution ... 
     229 
     230            serializer.endTag("", "device"); 
     231            serializer.endDocument(); 
     232 
     233            writeToFile(writer.toString()); 
     234 
     235        } 
     236        catch (IllegalArgumentException e) { 
     237            e.printStackTrace(); 
     238            Log.e("file", "outputstream: " + e.getMessage()); 
     239        } 
     240        catch (IllegalStateException e) { 
     241            e.printStackTrace(); 
     242            Log.e("file", "outputstream: " + e.getMessage()); 
     243        } 
     244        catch (IOException e) { 
     245            e.printStackTrace(); 
     246            Log.e("file", "outputstream: " + e.getMessage()); 
     247        } 
     248 
    206249    } 
    207250 
     
    219262     */ 
    220263    public void addComponent(View view, int parentHash, String activityName) { 
    221             XmlSerializer serializer = Xml.newSerializer(); 
    222             StringWriter writer = new StringWriter(); 
    223              
    224             try { 
    225                     serializer.setOutput(writer); 
    226                     serializer.startTag("", "component"); 
    227                     // TODO find a way in that the hash code is unique over time and 
    228                     // target 
    229                     /* 
    230                      * (non-Javadoc) view.getId() seems to be unique over time and 
    231                      * targets but there is a problem. In some cases there is no ID 
    232                      * (value: -1). 
    233                      */ 
    234                     serializer.attribute("", "hash", "" + view.hashCode()); 
    235                      
    236  
    237                     serializer.startTag("", "param"); 
    238                     serializer.attribute("", "name", "id"); 
    239                     serializer.attribute("", "value", "" + view.getId()); 
    240                     serializer.endTag("", "param"); 
    241  
    242                     serializer.startTag("", "param"); 
    243                     serializer.attribute("", "name", "path"); 
    244                     serializer.attribute("", "value", activityName + "/" 
    245                                     + getViewPath(view) + view.getClass().getSimpleName()); 
    246                     serializer.endTag("", "param"); 
    247  
    248                     serializer.startTag("", "param"); 
    249                     serializer.attribute("", "name", "class"); 
    250                     serializer.attribute("", "value", view.getClass().getName()); 
    251                     serializer.endTag("", "param"); 
    252  
    253                     serializer.startTag("", "param"); 
    254                     serializer.attribute("", "name", "parent"); 
    255                     // Problem in using view.getParent().hashCode(): 
    256                     // http://developer.android.com/reference/android/view/View.html#getParent() 
    257                     // tells: "... parent is a ViewParent and not necessarily a View." 
    258                     // ViewParent does not have a method hashCode(). Solution is done 
    259                     // add parentHash as parameter to method addComponent() and 
    260                     // Androidmonitor-> addLogListenerToView. 
    261                     serializer.attribute("", "value", "" + parentHash); 
    262                     serializer.endTag("", "param"); 
    263  
    264                     // TODO add title e.g. android:text="Button" 
    265  
    266                     serializer.startTag("", "ancestors"); 
    267                      
    268                     Class<? extends Object> classobject = view.getClass(); 
    269                      
    270                     while((classobject != null)){ 
    271                             serializer.startTag("", "ancestor"); 
    272                             serializer.attribute("", "name", classobject.getName()); 
    273                             serializer.endTag("", "ancestor"); 
    274                             classobject = classobject.getSuperclass(); 
    275                     } 
    276                     serializer.endTag("", "ancestors"); 
    277  
    278                     serializer.endTag("", "component"); 
    279                     serializer.endDocument(); 
    280  
    281                     writeToFile(writer.toString()); 
    282  
    283             } catch (IllegalArgumentException e) { 
    284                     // TODO Auto-generated catch block 
    285                     e.printStackTrace(); 
    286                     Log.e("file", "outputstream: " + e.getMessage()); 
    287             } catch (IllegalStateException e) { 
    288                     // TODO Auto-generated catch block 
    289                     e.printStackTrace(); 
    290                     Log.e("file", "outputstream: " + e.getMessage()); 
    291             } catch (IOException e) { 
    292                     // TODO Auto-generated catch block 
    293                     e.printStackTrace(); 
    294                     Log.e("file", "outputstream: " + e.getMessage()); 
     264        XmlSerializer serializer = Xml.newSerializer(); 
     265        StringWriter writer = new StringWriter(); 
     266 
     267        try { 
     268            serializer.setOutput(writer); 
     269            serializer.startTag("", "component"); 
     270            /* 
     271             * (non-Javadoc) TODO find a way in that the hash code is unique over time and target 
     272             *  
     273             * view.getId() seems to be unique over time and targets but there is a problem. In some 
     274             * cases there is no ID (value: -1). 
     275             *  
     276             * view.getId() is not unique in every case. E.g. in the application timerdroid the id 
     277             * of the list elements changes when calling home button. 
     278             */ 
     279            serializer.attribute("", "hash", "" + view.hashCode()); 
     280            currentLoggedComponents.add(view.hashCode()); 
     281 
     282            serializer.startTag("", "param"); 
     283            serializer.attribute("", "name", "id"); 
     284            serializer.attribute("", "value", "" + view.getId()); 
     285            serializer.endTag("", "param"); 
     286 
     287            if (view instanceof TextView) { 
     288                serializer.startTag("", "param"); 
     289                serializer.attribute("", "name", "title"); 
     290                TextView textView = (TextView) view; 
     291                serializer.attribute("", "value", "" + textView.getText()); 
     292                serializer.endTag("", "param"); 
    295293            } 
     294            //TODO in case of an image add file name 
     295            if (view instanceof ImageView) { 
     296                serializer.startTag("", "param"); 
     297                serializer.attribute("", "name", "title"); 
     298                
     299                 
     300                serializer.attribute("", "value", "image:" ); 
     301                serializer.endTag("", "param"); 
     302            } 
     303 
     304            serializer.startTag("", "param"); 
     305            serializer.attribute("", "name", "path"); 
     306            serializer.attribute("", "value", activityName + "/" + getViewPath(view) + 
     307                view.getClass().getSimpleName()); 
     308            serializer.endTag("", "param"); 
     309 
     310            serializer.startTag("", "param"); 
     311            serializer.attribute("", "name", "class"); 
     312            serializer.attribute("", "value", view.getClass().getName()); 
     313            serializer.endTag("", "param"); 
     314 
     315            serializer.startTag("", "param"); 
     316            serializer.attribute("", "name", "parent"); 
     317            /* 
     318             * (non-Javadoc) Problem in using view.getParent().hashCode(): 
     319             * http://developer.android.com/reference/android/view/View.html#getParent() tells: 
     320             * "... parent is a ViewParent and not necessarily a View." ViewParent does not have a 
     321             * method hashCode(). Solution is done add parentHash as parameter to method 
     322             * addComponent() and Androidmonitor-> addLogListenerToView. 
     323             */ 
     324            serializer.attribute("", "value", "" + parentHash); 
     325            serializer.endTag("", "param"); 
     326 
     327            serializer.startTag("", "ancestors"); 
     328 
     329            Class<? extends Object> classobject = view.getClass(); 
     330 
     331            while ((classobject != null)) { 
     332                serializer.startTag("", "ancestor"); 
     333                serializer.attribute("", "name", classobject.getName()); 
     334                serializer.endTag("", "ancestor"); 
     335                classobject = classobject.getSuperclass(); 
     336            } 
     337            serializer.endTag("", "ancestors"); 
     338 
     339            serializer.endTag("", "component"); 
     340            serializer.endDocument(); 
     341 
     342            writeToFile(writer.toString()); 
     343 
     344        } 
     345        catch (IllegalArgumentException e) { 
     346            e.printStackTrace(); 
     347            Log.e("file", "outputstream: " + e.getMessage()); 
     348        } 
     349        catch (IllegalStateException e) { 
     350            e.printStackTrace(); 
     351            Log.e("file", "outputstream: " + e.getMessage()); 
     352        } 
     353        catch (IOException e) { 
     354            e.printStackTrace(); 
     355            Log.e("file", "outputstream: " + e.getMessage()); 
     356        } 
    296357 
    297358    } 
     
    303364     *  
    304365     * @param hash 
    305      *                      hash value of the calling view of the listener 
     366     *            hash value of the calling view of the listener 
    306367     * @param type 
    307      *                      the type of listener e.g. textView ... 
     368     *            the type of listener e.g. textView ... 
    308369     * @param message 
    309      *                      message typed in 
    310      */ 
    311     public void addEvent(int hash, String type, String message){ 
    312             XmlSerializer serializer = Xml.newSerializer(); 
    313             StringWriter writer = new StringWriter(); 
    314  
    315             try { 
    316                     serializer.setOutput(writer); 
    317  
    318                     serializer.startTag("", "event"); 
    319                     serializer.attribute("", "id", type); 
    320  
    321                     serializer.startTag("", "param"); 
    322                     serializer.attribute("", "value", "" + hash); 
    323                     serializer.attribute("", "name", "source"); 
    324                     serializer.endTag("", "param"); 
    325                      
    326                     serializer.startTag("", "param"); 
    327                     serializer.attribute("", "value", message); 
    328                     serializer.attribute("", "name", "message"); 
    329                     serializer.endTag("", "param"); 
    330  
    331                     serializer.startTag("", "param"); 
    332                     serializer.attribute("", "value", "" + System.currentTimeMillis()); 
    333                     serializer.attribute("", "name", "timestamp"); 
    334                     serializer.endTag("", "param"); 
    335  
    336                     serializer.endTag("", "event"); 
    337                     serializer.endDocument(); 
    338  
    339                     writeToFile(writer.toString()); 
    340             } catch (IllegalArgumentException e) { 
    341                     // TODO Auto-generated catch block 
    342                     e.printStackTrace(); 
    343                     Log.e("file", "outputstream: " + e.getMessage()); 
    344             } catch (IllegalStateException e) { 
    345                     // TODO Auto-generated catch block 
    346                     e.printStackTrace(); 
    347                     Log.e("file", "outputstream: " + e.getMessage()); 
    348             } catch (IOException e) { 
    349                     // TODO Auto-generated catch block 
    350                     e.printStackTrace(); 
    351                     Log.e("file", "outputstream: " + e.getMessage()); 
    352             } 
    353     } 
    354      
     370     *            message typed in 
     371     */ 
     372    public void addEvent(int hash, String type, String message) { 
     373        XmlSerializer serializer = Xml.newSerializer(); 
     374        StringWriter writer = new StringWriter(); 
     375 
     376        try { 
     377            serializer.setOutput(writer); 
     378 
     379            serializer.startTag("", "event"); 
     380            serializer.attribute("", "id", type); 
     381 
     382            serializer.startTag("", "param"); 
     383            serializer.attribute("", "value", "" + hash); 
     384            serializer.attribute("", "name", "source"); 
     385            serializer.endTag("", "param"); 
     386 
     387            serializer.startTag("", "param"); 
     388            serializer.attribute("", "value", message); 
     389            serializer.attribute("", "name", "message"); 
     390            serializer.endTag("", "param"); 
     391 
     392            serializer.startTag("", "param"); 
     393            serializer.attribute("", "value", "" + System.currentTimeMillis()); 
     394            serializer.attribute("", "name", "timestamp"); 
     395            serializer.endTag("", "param"); 
     396 
     397            serializer.endTag("", "event"); 
     398            serializer.endDocument(); 
     399 
     400            writeToFile(writer.toString()); 
     401        } 
     402        catch (IllegalArgumentException e) { 
     403            e.printStackTrace(); 
     404            Log.e("file", "outputstream: " + e.getMessage()); 
     405        } 
     406        catch (IllegalStateException e) { 
     407            e.printStackTrace(); 
     408            Log.e("file", "outputstream: " + e.getMessage()); 
     409        } 
     410        catch (IOException e) { 
     411            e.printStackTrace(); 
     412            Log.e("file", "outputstream: " + e.getMessage()); 
     413        } 
     414    } 
     415 
    355416    /** 
    356417     * <p> 
     
    365426    public void addEvent(View view, String type) { 
    366427 
    367             String x = "" + view.getX(); 
    368             String y = "" + view.getY(); 
    369  
    370             XmlSerializer serializer = Xml.newSerializer(); 
    371             StringWriter writer = new StringWriter(); 
    372  
    373             try { 
    374                     serializer.setOutput(writer); 
    375  
    376                     serializer.startTag("", "event"); 
    377                     serializer.attribute("", "id", type); 
    378  
    379                     serializer.startTag("", "param"); 
    380                     serializer.attribute("", "value", x); 
    381                     serializer.attribute("", "name", "X"); 
    382                     serializer.endTag("", "param"); 
    383  
    384                     serializer.startTag("", "param"); 
    385                     serializer.attribute("", "value", y); 
    386                     serializer.attribute("", "name", "Y"); 
    387                     serializer.endTag("", "param"); 
    388  
    389                     serializer.startTag("", "param"); 
    390                     serializer.attribute("", "value", "" + view.hashCode()); 
    391                     serializer.attribute("", "name", "source"); 
    392                     serializer.endTag("", "param"); 
    393  
    394                     serializer.startTag("", "param"); 
    395                     serializer.attribute("", "value", "" + System.currentTimeMillis()); 
    396                     serializer.attribute("", "name", "timestamp"); 
    397                     serializer.endTag("", "param"); 
    398  
    399                     serializer.endTag("", "event"); 
    400                     serializer.endDocument(); 
    401  
    402                     writeToFile(writer.toString()); 
    403             } catch (IllegalArgumentException e) { 
    404                     // TODO Auto-generated catch block 
    405                     e.printStackTrace(); 
    406                     Log.e("file", "outputstream: " + e.getMessage()); 
    407             } catch (IllegalStateException e) { 
    408                     // TODO Auto-generated catch block 
    409                     e.printStackTrace(); 
    410                     Log.e("file", "outputstream: " + e.getMessage()); 
    411             } catch (IOException e) { 
    412                     // TODO Auto-generated catch block 
    413                     e.printStackTrace(); 
    414                     Log.e("file", "outputstream: " + e.getMessage()); 
     428        String x = "" + view.getX(); 
     429        String y = "" + view.getY(); 
     430 
     431        XmlSerializer serializer = Xml.newSerializer(); 
     432        StringWriter writer = new StringWriter(); 
     433 
     434        try { 
     435            serializer.setOutput(writer); 
     436 
     437            serializer.startTag("", "event"); 
     438            serializer.attribute("", "id", type); 
     439 
     440            serializer.startTag("", "param"); 
     441            serializer.attribute("", "value", x); 
     442            serializer.attribute("", "name", "X"); 
     443            serializer.endTag("", "param"); 
     444 
     445            serializer.startTag("", "param"); 
     446            serializer.attribute("", "value", y); 
     447            serializer.attribute("", "name", "Y"); 
     448            serializer.endTag("", "param"); 
     449 
     450            serializer.startTag("", "param"); 
     451            serializer.attribute("", "value", "" + view.hashCode()); 
     452            serializer.attribute("", "name", "source"); 
     453            serializer.endTag("", "param"); 
     454 
     455            serializer.startTag("", "param"); 
     456            serializer.attribute("", "value", "" + System.currentTimeMillis()); 
     457            serializer.attribute("", "name", "timestamp"); 
     458            serializer.endTag("", "param"); 
     459 
     460            serializer.endTag("", "event"); 
     461            serializer.endDocument(); 
     462 
     463            writeToFile(writer.toString()); 
     464        } 
     465        catch (IllegalArgumentException e) { 
     466            e.printStackTrace(); 
     467            Log.e("file", "outputstream: " + e.getMessage()); 
     468        } 
     469        catch (IllegalStateException e) { 
     470            e.printStackTrace(); 
     471            Log.e("file", "outputstream: " + e.getMessage()); 
     472        } 
     473        catch (IOException e) { 
     474            e.printStackTrace(); 
     475            Log.e("file", "outputstream: " + e.getMessage()); 
     476        } 
     477    } 
     478 
     479    /** 
     480     *  
     481     * <p> 
     482     * Creates a new file to store information. 
     483     * </p> 
     484     *  
     485     * @param activity 
     486     *            Calling application. 
     487     */ 
     488    private void createFile(Activity activity) { 
     489 
     490        AndroidMonitorLogFile.name = 
     491            "androidLogFile_" + AndroidMonitorLogFile.appName + System.currentTimeMillis() + ".log"; 
     492        try { 
     493            AndroidMonitorLogFile.file = 
     494                new File(activity.getFilesDir(), AndroidMonitorLogFile.name); 
     495            if (AndroidMonitorLogFile.file.exists() && !AndroidMonitorLogFile.file.isDirectory()) { 
     496                createFile(activity, 0); 
    415497            } 
    416     } 
    417  
    418     /** 
    419      * <p> 
    420      * Writes given information to the file. e.g. previous produced XML 
    421      * statements. 
     498            else { 
     499                writeHeaderToFile(activity); 
     500            } 
     501        } 
     502        catch (Exception e) { 
     503            e.printStackTrace(); 
     504            Log.e("AndroidMonitorLogFile.file", "file: " + e.getMessage()); 
     505        } 
     506    } 
     507 
     508    /** 
     509     *  
     510     * <p> 
     511     * Creates a new file to store information. Counts up if file exists. 
     512     * </p> 
     513     *  
     514     * @param activity 
     515     *            Calling application. 
     516     * @param count 
     517     *            File number. 
     518     */ 
     519    private void createFile(Activity activity, int count) { 
     520        AndroidMonitorLogFile.name = 
     521            "androidLogFile_" + count + "_" + AndroidMonitorLogFile.appName + 
     522                System.currentTimeMillis() + ".log"; 
     523        try { 
     524            AndroidMonitorLogFile.file = 
     525                new File(activity.getFilesDir(), AndroidMonitorLogFile.name); 
     526            if (AndroidMonitorLogFile.file.exists() && !AndroidMonitorLogFile.file.isDirectory()) { 
     527                count++; 
     528                createFile(activity, count); 
     529            } 
     530            else { 
     531                writeHeaderToFile(activity); 
     532            } 
     533        } 
     534        catch (Exception e) { 
     535            e.printStackTrace(); 
     536            Log.e("AndroidMonitorLogFile.file", "file: " + e.getMessage()); 
     537        } 
     538    } 
     539 
     540    /** 
     541     *  
     542     * <p> 
     543     * Writes XML head, device and application information to file. 
     544     * </p> 
     545     *  
     546     * @param activity 
     547     *            Calling application. 
     548     */ 
     549    private void writeHeaderToFile(Activity activity) { 
     550        writeToFile("<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><sessions>"); 
     551        setDeviceInformation(); 
     552        setAppInformation(activity); 
     553    } 
     554 
     555    /** 
     556     * <p> 
     557     * Writes given information to the file. e.g. previous produced XML statements. 
    422558     * </p> 
    423559     *  
     
    427563    private void writeToFile(String data) { 
    428564 
    429             FileOutputStream outputStream; 
    430             try { 
    431                     outputStream = new FileOutputStream(file, true); 
    432                     outputStream.write(data.getBytes()); 
    433                     outputStream.close(); 
    434             } catch (FileNotFoundException e) { 
    435                     e.printStackTrace(); 
    436                     Log.e("file", "outputstream: " + e.getMessage()); 
    437             } catch (IOException e) { 
    438                     e.printStackTrace(); 
    439                     Log.e("file", "outputstream: " + e.getMessage()); 
    440             } 
     565        FileOutputStream outputStream; 
     566        try { 
     567            outputStream = new FileOutputStream(AndroidMonitorLogFile.file, true); 
     568            outputStream.write(data.getBytes()); 
     569            outputStream.close(); 
     570        } 
     571        catch (FileNotFoundException e) { 
     572            e.printStackTrace(); 
     573            Log.e("file", "outputstream: " + e.getMessage()); 
     574        } 
     575        catch (IOException e) { 
     576            e.printStackTrace(); 
     577            Log.e("file", "outputstream: " + e.getMessage()); 
     578        } 
    441579 
    442580    } 
     
    451589     */ 
    452590    private String getViewPath(View view) { 
    453             return getViewPath(view, null); 
     591        return getViewPath(view, null); 
    454592    } 
    455593 
     
    464602     */ 
    465603    private String getViewPath(View view, String path) { 
    466             if (path == null) { 
    467                     path = ""; 
    468             } else { 
    469                     path = view.getClass().getSimpleName() + "/" + path; 
    470             } 
    471             if (view.getParent() != null && (view.getParent() instanceof ViewGroup)) { 
    472                     return getViewPath((View) view.getParent(), path); 
    473             } else { 
    474                     return path; 
    475             } 
    476     } 
    477      
     604        if (path == null) { 
     605            path = ""; 
     606        } 
     607        else { 
     608            path = view.getClass().getSimpleName() + "/" + path; 
     609        } 
     610        if (view.getParent() != null && (view.getParent() instanceof ViewGroup)) { 
     611            return getViewPath((View) view.getParent(), path); 
     612        } 
     613        else { 
     614            return path; 
     615        } 
     616    } 
     617 
    478618    /** 
    479619     *  
     
    481621     * Check whether a component is still written to log file. 
    482622     * </p> 
    483      * 
     623     *  
    484624     * @param hashCode 
    485      *          hash code of the view 
     625     *            hash code of the view 
    486626     * @return 
    487627     */ 
    488     public Boolean isComponentLogged(Integer hashCode){ 
    489         return currentLoggedComponents.contains(hashCode); 
    490     } 
    491      
    492      
     628    public static Boolean isComponentLogged(Integer hashCode) { 
     629        return AndroidMonitorLogFile.currentLoggedComponents.contains(hashCode); 
     630    } 
     631 
    493632} 
Note: See TracChangeset for help on using the changeset viewer.