Monday, October 7, 2013

Entering text and pausing for android

This is a test of calling the default input scheme,  whatever it is, and obtaining a "keyboard", i.e., alpha numeric, input for future use.  Also, we look into timing, sequencing, and pausing. This code was stolen from http://stackoverflow.com/questions/4111905/how-do-you-have-the-code-pause-for-a-couple-of-seconds-in-android. Other code was stolen from http://stackoverflow.com/questions/12622742/get-value-from-dialogfragment.


package com.mycompany.test1;

import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
import android.content.Intent;
import android.widget.EditText;



public class MainActivity extends Activity
{

public final static String EXTRA_MESSAGE = "com.wpd0101.firstapp.MESSAGE";
/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
{
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
/*System.out.println("hello");*/
    }
/** Called when the user clicks the Send button */
public void sendMessage(View view)
{
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}

Comments:
1)  /*System.out.println("hello");*/ is a commented out statement to show us that the program started,. LogCat needs to be viewed in order to see this comment.
2)  Intent intent = new Intent(this, DisplayMessageActivity.class); This defines an "intent". DisplayMessageActivity is what used to be called an external subroutine. It's code can be found below. It is held in a separate file in the same directory as the source (above).


package com.mycompany.test1;
/*
http://stackoverflow.com/questions/4111905/how-do-you-have-the-code-pause-for-a-couple-of-seconds-in-android
*/
import android.app.*;
import android.content.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class DisplayMessageActivity extends Activity
{
private Handler handler = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState)
{
        super.onCreate(savedInstanceState);

// Get the message from the intent
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

// Create the text view
final TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);

// Set the text view as the activity layout
setContentView(textView);
CharSequence text = message;
int duration = Toast.LENGTH_LONG;

Toast toast = Toast.makeText(getApplicationContext(), text, duration);
toast.show();
text = text + " 2nd message";
toast = Toast.makeText(getApplicationContext(), text, duration);
toast.show();
handler.postDelayed(new Runnable() {
public void run()
{
// doStuff();
textView.append(", delay");
}
}, 5000);
handler.postDelayed(new Runnable() {
public void run()
{
// doStuff();
textView.setText("try 2");
setContentView(textView);
}
}, 5000);
}

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
{
        switch (item.getItemId())
{
case android.R.id.home:
return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
Here we use "toast" to put messages on the screen. Playing around with the delays and messages might help to clarify what's going on.

parsing filename into parts

This is an example of String manipulation using Android/Java. The code uses a subroutine to do the work, and is explained below. First the complete code:




package com.wpd0101.parseFileName;

import android.app.*;
import android.os.*;
import android.util.*;

public class MainActivity extends Activity
{
    /** Called when the activity is first created. */
//http://android-er.blogspot.com/2011/04/how-to-get-file-extension-using-java.html?m=1
private static final String TAG = "DEBUG-parseFileName";
    @Override
    public void onCreate(Bundle savedInstanceState)
{
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

String infile = "jack.jpg";
String first = myFileName(infile);
Log.v(TAG," result = "+first);
    }
In above code, the call to the subroutine returns a value (String) of "first". Presumably, one would do something with this value elsewhere in one's programming.

public String myFileName(String infile){
Log.e("arg was ",infile);
int dotposition= infile.lastIndexOf(".");
Log.v("dotpos = ",String.valueOf(dotposition));
return(infile.substring(0,dotposition));
//ext = file.substring(dotposition + 1, file.length());
}
}
The second part of the code takes this incoming complete filename, locates the position of the "dot", and returns the string of characters leading up to but not including the "dot" itself. If one needed the extension, one could define a String called "ext" in this example, and remove the "//" from the code to pass that value back.

Tuesday, March 5, 2013

File Writing in Android

Android programming is Java "in mufti". The following is an example  which will be added to as time goes on. The work was performed on a Kindle, using AIDE. The text are largely plagiarized from public sources on the internet, here being brought into small, bite (hah) sized portions.

This example illustrates writing text to a file. Notice that I made a mistake in naming the file, as "MainActivity" is meaningless when it shows up as a choice in the Apps screen. It seems to me very confusing at the beginning to choose names before it is clear where those names will be used.

package com.wpd0101.filewritetest;

import android.app.*;
import android.os.*;
import android.util.*;
import android.widget.*;
import java.io.*;

public class MainActivity extends Activity
{
private static final String LOG_TAG = "FileWriteTestDebug";
    /** Called when the activity is first created. */
    Toast toast;
@Override
    public void onCreate(Bundle savedInstanceState)
{
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
String filename = "wpd_test_file.txt";
String data_string = "Written by filewritetest into newly created (or not) directory";

if (isExternalStorageWritable())
{
toast = Toast.makeText(getApplicationContext(), "yes external storage is writeable", Toast.LENGTH_LONG);
toast.show();
// }

TextView textView = new TextView(this);
textView.setTextSize(40);

String pathToExternalStorage = Environment.getExternalStorageDirectory().toString();
File appDirectory = new File(pathToExternalStorage + "/newDirectory");

// have the object build the directory structure, if needed.
appDirectory.mkdirs();

filename = "./newDirectory/" + filename;
textView.setText(filename);
setContentView(textView);

File file = new File(Environment.getExternalStorageDirectory(), filename);
FileOutputStream fos;
byte[] data = data_string.getBytes();
try
{
fos = new FileOutputStream(file);
fos.write(data);
fos.flush();
fos.close();
toast = Toast.makeText(getApplicationContext(), "file written as desired", Toast.LENGTH_SHORT);
toast.show();
}
catch (FileNotFoundException e)
{
// handle exception
toast = Toast.makeText(getApplicationContext(), "FilrNotFoundException", Toast.LENGTH_LONG);
toast.show();
}
catch (IOException e)
{
// handle exception
// toast = Toast.makeText(getApplicationContext(), "IOException", Toast.LENGTH_LONG);
// toast.show();
myToast("IOException");
}
}
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable()
{
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state))
{
return true;
}
return false;
}
public void myToast(String toast_msg)
{
toast = Toast.makeText(getApplicationContext(), toast_msg, Toast.LENGTH_LONG);
toast.show();
}
}



This code starts with a global declaration for a "Toast", which is a way of communicating while debugging to see what's going on. AIDE does not have debugging facilities, so one is reduced to writing debugging information on the screen as the program chugs along in this (and other) manners. This one (Toast) is easy to use.
The LOG_TAG is defined so that we can label outputs which use the "Log.e()" function. We didn't use it in this example.

PLEASE REMEMBER TO INCLUDE THE APPROPRIATE STATEMENT IN THE ANDROID MANIFEST TO ALLOW WRITING TO THE sdcard. Without this permission, writing is impossible. This is a protective feature.

Upon starting, we need to create definitions which will be used further on in the code. The first two lines are created by AIDE, and of course the rest is discretionary.


  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
String filename = "wpd_test_file.txt";
String data_string = "Written by filewritetest into newly created (or not) directory";

The "data_string" is text which will be written into the newly created file.

The following code tests to see if the sdcard is writeable:

if (isExternalStorageWritable())
{
toast = Toast.makeText(getApplicationContext(), "yes external storage is writeable", Toast.LENGTH_LONG);
toast.show();
// }
and writing this code and running it, you see that it is, indeed writeable. Toast is a method of outputing intermediate information without goofing up the layout of the output screen.

The following creates a region of the screen for outputting text, and then creates a new directory connected to the current directory, whatever it is, as a sub-directory:

TextView textView = new TextView(this);
textView.setTextSize(40);

String pathToExternalStorage = Environment.getExternalStorageDirectory().toString();
File appDirectory = new File(pathToExternalStorage + "/newDirectory");

// have the object build the directory structure, if needed.
appDirectory.mkdirs();

filename = "./newDirectory/" + filename;
textView.setText(filename);
setContentView(textView);
"pathToExternbalStorage" establishes where we are on the sdcard, and the next two lines create the subdirectory. Finally, we concatenate the current path with the new directory name with the to-be-created file name and check that we've got it right by writing it to the textView.

Finally, we write the data to the new file:

File file = new File(Environment.getExternalStorageDirectory(), filename);
FileOutputStream fos;
byte[] data = data_string.getBytes();
try
{
fos = new FileOutputStream(file);
fos.write(data);
fos.flush();
fos.close();
toast = Toast.makeText(getApplicationContext(), "file written as desired", Toast.LENGTH_SHORT);
toast.show();
}
catch (FileNotFoundException e)
{
// handle exception
toast = Toast.makeText(getApplicationContext(), "FilrNotFoundException", Toast.LENGTH_LONG);
toast.show();
}
catch (IOException e)
{
// handle exception
// toast = Toast.makeText(getApplicationContext(), "IOException", Toast.LENGTH_LONG);
// toast.show();
myToast("IOException");
}
Toasting as we go if there are errors or successes. rather than use the same code, we create a subroutine, myToast, to Toast for us:
public void myToast(String toast_msg)
{
toast = Toast.makeText(getApplicationContext(), toast_msg, Toast.LENGTH_LONG);
toast.show();
}
Note that this internal subroutine (old fashioned language, sorry) gets its toast content from the caller. It reduces toasting to a 1-line invocation.


March 5, 2013