Screensaver Revival

Screensaver Projects

In the 1990s, my father obtained an Apple Mac 8100/80 for his screenprinting business. Compared to the Windows Pcs of the time, the thing was an absolute beast. Photoshop and Illustrator will still unknown to Windows users, knowing only of PaintshopPro and CorelDraw.

With this computing power, came opportunities for fun. Third party control panels were the source of all kinds of absurd desktop distractions. In my opinion, the most entertaining of these was the AfterDark series of screensavers. They were fairly expensive but damn were they ever entertaining.

Back in the 1990s, I created a number of little applications and screensaver hacks. I’ve decided to revisit them, and port some of them to Android.

Android Daydreams

The Android platform has a number of under-utilized features, some. One of these is the Daydream functionality, which is located under your Display Settings. In essence, a Daydream or DreamService is a screensaver. They can vary in complexity and even allow for some levels of user interaction. They’re most practical to use while charging so that they don’t chew up your battery.

From DOS To Android

The first place I decided to start wasn’t an actual screensaver, it was a simple DOS application that I wrote in Pascal called “Bob’s” Aphorisms. All it did was read a text file and output a random line from it. It was designed to display while starting up, adding a line to the AUTOEXEC.BAT.

At the core of the application was a text file. I didn’t actually create this file, it was assembled by another developer who created a 68K series Macintosh version, who went by the name Dad.

The Tools

I wish I still had the Pascal source to post here. On Ubuntu, I used Android Studio for development. I’ve used Eclipse in the past and in college but I really like the simplified approach to this specialized IDE.

AndroidStudio also has a simple template to create a basic Daydream. This was an excellent starting point.

Application Pieces

MainActivity.java

This is just the default activity, with the default name. Presently, it only contains a button to update the settings.

//set button handler

        //set button handler
        Button btnOpenSettings = (Button)findViewById(R.id.btnOpenSettings);
        btnOpenSettings.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {

                startActivityForResult(new Intent(Settings.ACTION_DREAM_SETTINGS), 0);
            }
        });

Aphorism.java

“An aphorism is a terse saying, expressing a general truth, principle, or astute observation, and spoken or written in a laconic (concise) and memorable form.”

— http://en.wikipedia.org/wiki/Aphorism

As usual in object oriented programming, I needed to create an object to represent the aphorism.

 

public class Aphorism {
    private long aphorismId;
    private String title;

    public Aphorism() {
    }

    public Aphorism(String title) {
        this.title = title;
    }

    public Aphorism(long aphorismId, String title) {
        this.aphorismId = aphorismId;
        this.title = title;
    }

    public long getAphorismId() {
        return aphorismId;
    }

    public void setAphorismId(long aphorismId) {
        this.aphorismId = aphorismId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}

ReadData.java

This helped to create an ArrayList of Aphorisms. I used the exact same file as the Pascal application. After reading up on where to put resources, I decided that /res/raw was a pretty good location. Using openRawResource() I was able to open the file without much messing around. I then used a BufferedReader to iterate through the text file.

 

public class ReadDataFile {
    public static ArrayList<Aphorism> ReadFile(Context ctx) {
        InputStream inputStream = ctx.getResources().openRawResource(R.raw.aphorism);
        ArrayList<Aphorism> aphorisms = new ArrayList<Aphorism>();

        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        try {
            String line = "";
            int lineNum = 1;
            do {
                line = reader.readLine();
                Aphorism item = new Aphorism(lineNum, line);
                aphorisms.add(item);

                lineNum++;
            } while (line != null);

            inputStream.close();
            reader.close();
       } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return aphorisms;
    }
}

AphorismDaydreamService.java

Letting AndroidStudio create this for you will get you going quickly. You can create a simple scrolling TextView that displays a preset message. I changed the direction it was scrolling, adjusted the width dynamically and read a random entry from the database. I kept about half of the code that was automatically created.

 

    private void startTextViewScrollAnimation() {
        String aphorismText = getTextFromPreferences();
        Aphorism aphorism = new Aphorism();

        try {
            db.open();
            Cursor c = db.fetchRandomAphorism();
            c.moveToFirst();

            //set aphorism text
            String title = c.getString(c.getColumnIndex("title"));
            if(title != "") {
                aphorismText = title;
            }
            db.close();
        } catch(SQLException sqlEx) {
            Log.e(TAG, sqlEx.getMessage());
        } catch(Exception ex) {
            Log.e(TAG, ex.getMessage());
        }

        mDreamTextView = (TextView) findViewById(R.id.dream_text);
        mDreamTextView.setText(aphorismText);

        mDreamTextView.measure(0, 0);
        int measuredWidth = mDreamTextView.getMeasuredWidth();

        // Refresh Size of Window
        getWindowManager().getDefaultDisplay().getSize(mPointSize);

        final int windowWidth = mPointSize.x;
        final int windowHeight = mPointSize.y;

        // Move TextView so it's moved all the way to the left
        mDreamTextView.setTranslationX(windowWidth);

        // Move TextView to random y value
        final int yRange = windowHeight - mDreamTextView.getHeight();
        mDreamTextView.setTranslationY(mRandom.nextInt(yRange));

        // Create an Animator and keep a reference to it
        int translationPosition = -1 * (mDreamTextView.getMeasuredWidth() + windowWidth);
        int animateDuration = aphorismText.length() * 100;
        mAnimator = mDreamTextView.animate().translationX(translationPosition)
            .setDuration(animateDuration)
            .setListener(mAnimListener)
            .setInterpolator(sInterpolator);

        // Start the animation
        mAnimator.start();
    }

Download

Get it on Google Play

You can download the Android version from the Play Store, or visit this website. WARNING: THE TEXT FILE CONTAINS LOTS OF OFFENSIVE LANGUAGE. You can still download the DOS version here.