Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Saturday, May 18, 2024

Android Transformation Matrix

Transformation Matrix

Based on the Affine transformation examples shown in https://en.wikipedia.org/wiki/Affine_transformation , a 2D transformation matrix for scale, skew and translation in x and y axes can be shown as follows:

scaleX      skewX        tranxX

skewY      scaleY        transY

0               0                1

For example,

In order to scale a canvas by 2x in x and y axes, the transform that needs to be applied (multiplied with the transform matrix of the canvas) is:

2                   0                   0

0                   2                   0

0                   0                   1

So a canvas that is scaled using the above transformation matrix would look like:

           Original                                                     Transformed

 
 


Saturday, April 13, 2024

Sliding Window Mean and Standard Deviation Calculation and Visualization


1. Create a folder named sliding-window.

2. Create a file named script.js inside the folder and paste the following content:

function id(id) { 
    return document.getElementById(id); 
} 
var count = 0; 
var pattern, text, Psize, Tsize; 
var idcountrater = 0; 
var conti = 0; 
const slidingWindowTech = async (pattern, Psize, sum, k) => { 
    console.log("hola") 
    var max_sum = 0; 
    let maxi = document.createElement('div'); 
    maxi.id = "message"; 
    maxi.classList.add("message"); 
    maxi.innerText = `Fluidity incident count is ${max_sum}` 
    console.log(maxi) 
    id("pattern_text").appendChild(maxi); 
    console.log(`Setting incidenetActive to false`);
    let incidentActive = false;
    let current_sum = 0; 
    let windowMean = 0;
    let windowSD = 0;
    let current = document.createElement('div'); 
    current.id = "message"; 
    current.classList.add("message"); 
    current.innerText = `CurrentSum is ${current_sum}` 
    id("pattern_text").appendChild(current);

    let mean = document.createElement('div');
    mean.id = "message";
    mean.classList.add("message");
    mean.innerText = `Mean is ${current_sum}`
    id("pattern_text").appendChild(mean);

    let sd = document.createElement('div');
    sd.id = "message";
    sd.classList.add("message");
    sd.innerText = `SD is ${current_sum}`
    id("pattern_text").appendChild(sd);

    let upfd = document.createElement('div');
    upfd.id = "message";
    upfd.classList.add("message");
    upfd.innerText = `UPFD (Mean + 2SD) is ${current_sum}`
    id("pattern_text").appendChild(upfd);

    for (let i = 0; i < Psize - k + 1; i++) { 
        await new Promise((resolve) => 
            setTimeout(() => { 
                resolve(); 
            }, 1000) 
        ) 
        console.log(i + " " + (i + k - 1)); 
        id(i).style.borderLeft = "2px solid white"
        id(i).style.borderTop = "2px solid white"
        id(i).style.borderBottom = "2px solid white"
        id(i + 1).style.borderBottom = "2px solid white"
        id(i + 1).style.borderTop = "2px solid white"
        id(i + 2).style.borderTop = "2px solid white"
        id(i + 2).style.borderBottom = "2px solid white"
        id((i + k - 1)).style.borderRight = "2px solid white"; 
        id(i + k - 1).style.borderTop = "2px solid white"
        id(i + k - 1).style.borderBottom = "2px solid white"
        if (i != 0) { 
            // current_sum=current_sum-pattern[i-1] 
            id(i - 1).style.color = "Red"
            await new Promise((resolve) => 
                setTimeout(() => { 
                    resolve(); 
                }, 1000) 
            ) 
            current_sum = current_sum - pattern[i - 1] 
            current.innerText = 
                `CurrentSum after subtracting ${i - 1}th ` + 
                `element from ${i} window is ${current_sum}` 
            id(i - 1).style.color = "white"
            await new Promise((resolve) => 
                setTimeout(() => { 
                    resolve(); 
                }, 1000) 
            ) 
            id(i + k - 1).style.color = "green"
            await new Promise((resolve) => 
                setTimeout(() => { 
                    resolve(); 
                }, 1000) 
            ) 
            current_sum = current_sum + pattern[i + k - 1] 
            current.innerText = 
`CurrentSum after adding ${i + k - 1}th in ${i} window is ${current_sum}` 
            windowMean = current_sum / k;
            mean.innerText = `Current mean is ${windowMean}`

            // Compute window standard deviation
            squared_sum = 0;
            for (let j = i; j < i + k; j++) {
                squared_sum += (pattern[j] - windowMean)*(pattern[j] - windowMean);
            }
            windowSD = Math.sqrt(squared_sum / k);
            sd.innerText = `Current SD is ${windowSD}`
            upfd.innerText = `Current UPFD is ${windowMean + 2 * windowSD}`
            id(i + k - 1).style.color = "white"
            await new Promise((resolve) => 
                setTimeout(() => { 
                    resolve(); 
                }, 1000) 
            ) 
        } 
        else { 
            for (let j = 0; j < k; j++) { 
                console.log("hola 1 " + current_sum) 
                id((i + j)).style.color = "Red"
                await new Promise((resolve) => 
                    setTimeout(() => { 
                        resolve(); 
                    }, 1000) 
                ) 
                current_sum = current_sum + pattern[i + j]; 
                current.innerText = 
                    `CurrentSum is for ${i}th window ${current_sum}` 
                await new Promise((resolve) => 
                    setTimeout(() => { 
                        resolve(); 
                    }, 1000) 
                ) 
                id((i + j)).style.color = "white"
            } 
            windowMean = current_sum / k;
            mean.innerText = `Current mean is ${windowMean}`

            // Compute window standard deviation
            squared_sum = 0;
            for (let j = i; j < i + k; j++) {
                squared_sum += (pattern[j] - windowMean)*(pattern[j] - windowMean);
            }
            windowSD = Math.sqrt(squared_sum / k);
            console.log(`Current Mean here is ${windowMean}`) 
            sd.innerText = `Current SD is ${windowSD}`
            upfd.innerText = `Current UPFD is ${windowMean + 2 * windowSD}`
        } 
        id(i).style.borderLeft = "none"
        id(i).style.borderTop = "none"
        id(i).style.borderBottom = "none"
        id(i + 1).style.borderBottom = "none"
        id(i + 1).style.borderTop = "none"
        id(i + 2).style.borderTop = "none"
        id(i + 2).style.borderBottom = "none"
        id((i + k - 1)).style.borderRight = "none"; 
        id(i + k - 1).style.borderTop = "none"
        id(i + k - 1).style.borderBottom = "none"
        //console.log(current_sum) 
        // Update result if required. 
        // max_sum = max(current_sum, max_sum); 
        //if (current_sum > max_sum) max_sum = current_sum; 

        // Report one incident when and until UPFD is above threshold.
        console.log(`incidentActive is ${incidentActive}`)
        if (windowMean + 2 * windowSD > 16 && !incidentActive) {
            max_sum += 1;
            incidentActive = true;
            console.log(`Setting incidentActive to true`)
        }
        // Reset once UPFD is back to normal
        if (incidentActive && windowMean + 2 * windowSD <= 16) {
            incidentActive = false;
        }
        maxi.innerText = `Fluidity incident count is ${max_sum}` 
    } 
    current.style.display = "none"
} 
let idcount = 0; 
window.onload = async () => { 
    id("displayer").style.display = "none"; 
    id("start").addEventListener('click', () => { 
        id("start").style.display = "none"
        id("displayer").style.display = "flex"; 
        //pattern = [16, 16, 16, 32, 16, 16, 16, 16, 16, 32, 16, 16, 16] 
        pattern = [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32] 
        Psize = 13
        sum = 24 
        let idcount1 = 0; 
        for (let i = 0; i < Psize; i++) { 
            let tile = document.createElement('span'); 
            tile.id = idcount; 
            tile.classList.add("tile"); 
            tile.innerText = pattern[i]; 
            id("pattern").appendChild(tile); 
            idcount++; 
        } 
        slidingWindowTech(pattern, Psize, sum, 4) 
    }) 
}

3. Create a file named style.css and paste the following content:

* { 
    color: white; 
    font-family: "Open sans", sans-serif; 
} 
  
html { 
    background-color: black; 
} 
  
body { 
    display: flex; 
    flex-direction: column; 
    align-items: center; 
    height: 100vmin; 
} 
  
h1 span { 
    font-size: 6vmin; 
    font-weight: normal; 
    text-shadow: 0 0 20px cyan, 
        0 0 40px cyan, 
        0 0 80px cyan; 
} 
  
#container { 
    display: flex; 
    flex-direction: column; 
    align-items: center; 
    justify-content: center; 
    height: 80%; 
    width: 80%; 
} 
  
#displayer { 
    display: flex; 
    flex-direction: column; 
    align-items: center; 
    width: 100%; 
    height: 90%; 
} 
  
#pattern, 
#message { 
    width: 100%; 
    height: 7vmin; 
    margin: 3vmin; 
    font-size: 5vmin; 
    display: flex; 
    align-items: center; 
    justify-content: center; 
} 
  
#message { 
    color: cyan; 
    font-size: 2vmin; 
} 
  
#pattern_text { 
    width: 100%; 
    height: 5vmin; 
    margin: 3vmin; 
    font-size: 5vmin; 
    display: flex; 
    align-items: center; 
    justify-content: center; 
    color: g; 
} 
  
#pattern_text { 
    width: 100%; 
    height: 5vmin; 
    margin: 3vmin; 
    font-size: 5vmin; 
    display: flex; 
    align-items: center; 
    justify-content: center; 
    color: g; 
} 
  
.tile { 
    width: 6vmin; 
    height: 6vmin; 
    margin: 10px; 
    text-align: center; 
    height: fit-content; 
    border: 2px pink; 
} 
  
#start { 
    align-self: center; 
    background-color: black; 
    font-size: 3vmin; 
    box-sizing: border-box; 
    padding: 1vmin; 
    color: white; 
    cursor: pointer; 
    border: none; 
    margin-top: 2vmin; 
    transition: 0.5s ease-in-out; 
    font-weight: bold; 
    letter-spacing: 4px; 
} 
  
#start:hover { 
    transform: scale(1.5); 
    text-shadow: 0 0 10px cyan, 
        0 0 20px cyan, 
        0 0 40px cyan; 
} 
  
h1 { 
    margin-top: 0; 
    text-align: center; 
    padding: 1vmin; 
    margin-bottom: 1vmin; 
    width: 100%; 
    font-size: 5vmin; 
    font-weight: normal; 
    letter-spacing: 2px; 
    border-bottom: 1px solid white; 
}

4. Create a file named index.html and paste the following content:


<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta name="viewport" content=
        "width=device-width, initial-scale=1.0">
    <link href=
"https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&display=swap"
          rel="stylesheet" />
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
    <title>Document</title>
</head>
 
<body>
    <h1>
        <span class="1">S</span>liding  
        <span class="2">W</span>indow  
        <span class="3">T</span>echnique
        <span>Visualizer</span>
    </h1>
    <div id="message">
        We will find the mean and UPFD using  
        sliding window technique in certain sized  
        window when window size is 4
    </div>
    <div id="threshold">
        <table>
            <tr>
                <td>Metric</td>
                <td>Expected Value</td>
            </tr>
            <tr>
                <td>Rolling FPS</td>
                <td>60</td>
            </tr>
            <tr>
                <td>Rolling UPFD</td>
                <td>16</td>
            </tr>
        </table>
    </div>
    <div id="container">
        <div id="displayer">
            <div id="pattern"></div>
            <div id="pattern_text"></div>
        </div>
          
        <div id="start">Begin</div>
    </div>
</body>
 
</html>

5. Open index.html in a Browser and click Begin button.


 

Monday, October 10, 2022

Shell Script to detect events in ADB Logcat in a loop

The following shell script performs an action (tap) on the screen, then checks that a particular event does not happen on the device. It then performs another action (press back button) and then checks the target event happens only once. Then it closes a process and iterates through the same steps in a loop 50 times.

#!/bin/sh

# Clean up any reminiscent from previous run of the script
rm -rf script_logs
mkdir script_logs
for i in {1..50}
do
	echo $i
	echo "Clearing device logs"
	adb logcat -c
	echo "Starting log recording"
	adb logcat >> script_logs/script_logs$i.txt &
	logcat_pid=$!
	echo "Clicking at a point on the screen"
	adb shell input tap 200 300
	echo "Waiting for 4 seconds for event to happen and logs generated"
	sleep 4
	events=`grep "<log_pattern>" script_logs/script_logs$i.txt | wc -l`
	if [ $events == 0 ]
	then
		echo "No event found"
	else
		echo "$events were found, the test failed"
		kill -9 $logcat_pid
		exit 1
	fi
	adb shell input keyevent KEYCODE_BACK
	echo "Waiting for 4 seconds for another event"
	sleep 4
	echo "Checking how many events were sent"
	events=`grep "<log_pattern>" script_logs/script_logs$i.txt | wc -l`
	if [ $events == 1 ]
	then
		echo "One and only one event was found"
	else
		echo "$events were found, the test failed"
		kill -9 $logcat_pid
		exit 1
	fi
	echo "Killing target process"
	pid=`adb shell pidof <process_name>`
	adb shell kill -9 $pid
	echo "Stopping logcat"
	kill -9 $logcat_pid
	sleep 2
done

Saturday, April 5, 2014

Communicating non-primitive data objects between Android Activities

Non-primitive types such as ArrayLists can be communicated between Activities in Android using Parcelable interface.
Sample Example:
Class Definition:


package com.example.comparisonapp;

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

public class Product implements Parcelable{
private String asin;
private String imageUrl;
private String description;
private String title;
private Double rating = 0.0;

public String getAsin() {
return asin;
}
public void setAsin(String asin) {
this.asin = asin;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Double getRating() {
return rating;
}
public void setRating(Double rating) {
this.rating = rating;
}

public Product() {;}

public Product(Parcel in) {
this.asin = in.readString();
this.imageUrl = in.readString();
this.description = in.readString();
this.title = in.readString();
this.rating = in.readDouble();
}

@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel arg0, int arg1) {
// TODO Auto-generated method stub
arg0.writeString(asin);
arg0.writeString(imageUrl);
arg0.writeString(description);
arg0.writeString(title);
arg0.writeDouble(rating);
}

public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Product createFromParcel(Parcel in) {
return new Product(in);
}
public Product[] newArray(int size) {
return new Product[size];
}
};
}


Caution:
1. The order of reading data from the Parcel in Parcel argument constructor must be the same as order of writing the data in the Parcel in the writeToParcel method.

Initializing the objects of the class and sending as intent.

products = new ArrayList<Product>();
for(int i=0;i<3;i++) {
Product product = new Product();
product.setAsin("asin " + i);
product.setTitle("Title " + i);
product.setDescription("description " + i);
product.setRating(4.5);
product.setImageUrl("imageUrl");
products.add(product);
}
intent.putExtra("products", products);
startActivity(intent);


Reading the data from the intent

Intent intent = getIntent();
ArrayList<Product> products = intent.getExtras().getParcelableArrayList("products");
for(int i=0;i<products.size();i++) {
Toast.makeText(getApplicationContext(), "Got: " + String.valueOf(products.get(i).getAsin()), Toast.LENGTH_SHORT).show();
}

Friday, October 19, 2012

Android Translation Apps

Useful links are as follow:
1. Using Bing translation API:
http://www.microsoft.com/web/post/using-the-free-bing-translation-apis
2. Using Google Translation API:
http://rupeshpatel.wordpress.com/2012/06/23/usage-of-google-translator-api-for-free/
3. Link for Google Translator App:
https://play.google.com/store/apps/details?id=com.google.android.apps.translate&hl=en
4. Link for iTranslate App:
https://play.google.com/store/apps/details?id=at.nk.tools.iTranslate&hl=en
5. A nice Translator App with video demo:
http://www.cellictica.com/products.html#
6. List of Translator Apps:
http://android.appstorm.net/roundups/utilities-roundups/translation-apps-roundup/

Using Text to Speech API in Android

Useful links are as follow:
1. App developed using the tts engine:
http://mobile.tutsplus.com/tutorials/android/android-sdk-using-the-text-to-speech-engine/
2. Android link to use the tts API:
http://developer.android.com/reference/android/speech/tts/TextToSpeech.html
3. Android Sample Text-to-Speech API usage:
http://android-developers.blogspot.in/2009/09/introduction-to-text-to-speech-in.html
4. Voice Recorder App in Android:
https://play.google.com/store/apps/details?id=com.tokasiki.android.voicerecorder&hl=en

Using Speech to Text API in Android

Useful links are as follow:
1. Good google search string: speech to text api android
2. Android emulator is not capable of audio record:
http://www.deveature.com/2011/11/28/speech-recognizer-does-not-work-on-android-emulator/
3. Audio-capture in android:
http://developer.android.com/guide/topics/media/audio-capture.html
4. Stack overflow link for using MediaRecorder in Android:
http://stackoverflow.com/questions/5254994/can-the-android-emulator-record-and-play-back-audio-using-pc-hardware
5. App developed using Recognizer Intent (speech-to-text API):
http://viralpatel.net/blogs/android-speech-to-text-api/
6. Speech Input API for Android:
http://android-developers.blogspot.in/2010/03/speech-input-api-for-android.html
7. Link for Android Sample Projects:
http://developer.android.com/tools/samples/index.html
8. Recognizer Intent in Android:
http://developer.android.com/reference/android/speech/RecognizerIntent.html
9. SDK Version Concept in Android:
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
10. Voice Search app in Android:
https://play.google.com/store/apps/details?id=com.google.android.voicesearch&feature=search_result