Pages

Showing posts with label android app. Show all posts
Showing posts with label android app. Show all posts

Tuesday, November 26, 2013

Image Slideshow

In this post, you will learn to create a simple image slideshow app for Android. The user can select multiple images from the external card. Then by selecting the show menu item, the images will be displayed in slideshow view. The slideshow process will stop when all images are displayed.
Now, to develop the image slideshow app, you will need to create a new Android project. The project name is ImageSlider.

The first interface that you will see when the app starts up is the list of files and folders in the root directory. From this list, you can navigate to any sub-directory that contains the images to show. You can select or deselect multiple images as you want. The text box above the list displays the current directory. Making change to path in the text box will change the contents of the list. You can use this text box to navigate back and forth in the directory structure.

image slideshow


In this app, a class called BrowseFragment that extends the Fragment class is used to display the list of files and folders from which the user can select images to show or navigate to a lower-level sub-folder. Its layout file (browse_view.xml) defines two components: one EditText and one ListView. The data source of the ListView that contains names of files and folders is set to the ListView by calling the listDirContents method of the MainActivity class. The MainActivity class is discussed later in this tutorial.  Here are the contents of the BrowserFragment.java and browse_view.xml files.

BrowseFragment.java file

package com.example.imageslider;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class BrowseFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.browse_view, container, false);
}

public static BrowseFragment newInstance(String str){

return(new BrowseFragment());
}

public void onStart(){
super.onStart();

}


}


browse_view.xml file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/txt_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/text_hint" />
 <ListView
        android:id="@+id/files_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
         >
     
   </ListView>

</LinearLayout>


Each item of the ListView contains text and check box. The text represents a file or folder. The check box allows the user to select a file or multiple files. If a folder is selected, the files and sub-folders in that folder will be listed. The file that defines the layout of list item is called mulliststyle.xml in the res/layout directory.

mulliststyle.xml

<?xml version="1.0" encoding="utf-8"?>

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:paddingLeft="6dip"
    android:paddingRight="6dip"
/>

When the user selects the show menu item, the images will be displayed in slideshow view. You will need one more class that extends the Fragment class to display the image. This class is called ContentFragment and its layout file is content_view.xml file. The content_view.xml file simply contains the blank LinearLayout container. The component that is used to show the image will be added to the container later by code.

ContentFragment.java file

package com.example.imageslider;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class ContentFragment extends Fragment{
private static Activity mAct;
private static ArrayList<String> args;
private ArrayList<Bitmap> bitmapRes;
private LinearLayout ll;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
View v=inflater.inflate(R.layout.content_view, container, false);
ll=(LinearLayout) v.findViewById(R.id.layout_view);
//add SurfaceView representing the draw area to the layout
ll.addView(new MyDrawArea(this.getActivity()));
//Toast.makeText(this.getActivity(),"Hello="+ll.getWidth(), Toast.LENGTH_SHORT).show();
return ll;

}
public static ContentFragment newInstance(ArrayList<String> res){
args=res;
return(new ContentFragment());
}

public void onAttach(Activity activity){
super.onAttach(activity);
mAct=activity;

}

public void onStart(){
super.onStart();
//decode images
bitmapRes=processBitmap();
}

class ItemList implements OnItemClickListener{
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        Toast.makeText(mAct.getBaseContext(), "" + position, Toast.LENGTH_SHORT).show();
        }
}

public ArrayList<Bitmap> processBitmap(){
ArrayList<Bitmap>lst=new ArrayList<Bitmap>();
//get screen dimension
DisplayMetrics metrics=new DisplayMetrics();
mAct.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int rqwidth=metrics.widthPixels;
int rqheight=metrics.heightPixels;
//decode all images
for(int i=0;i<args.size();i++){
Bitmap image=decodeBitmap(args.get(i),rqwidth,rqheight);
lst.add(image);
}
return lst;
}

public Bitmap decodeBitmap(String path,int rqwidth,int rqheight){
BitmapFactory.Options option=new BitmapFactory.Options();
//specify decoding options
option.inJustDecodeBounds=true;
BitmapFactory.decodeFile(path,option);
option.inSampleSize=getSampleSize(option,rqwidth,rqheight);
option.inJustDecodeBounds=false;
return BitmapFactory.decodeFile(path,option);
}

public int getSampleSize(BitmapFactory.Options option, int rqwidth,int rqheight){
int samplesize=1;
int width=option.outWidth;
int height=option.outHeight;
if(width>rqwidth || height>rqheight){
int widthradio=Math.round((float)width/(float)rqwidth);
int heightradio=Math.round((float)height/(float)rqheight);
samplesize=widthradio<heightradio? widthradio:heightradio;

}
return samplesize;
}
//An image can be drawn on SurfaceView
class MyDrawArea extends SurfaceView implements Callback{
private Bitmap bitImage;
Paint p;
MyDrawArea(Context context){
super(context);
getHolder().addCallback(this);
getHolder().setFormat(PixelFormat.TRANSPARENT);
p=new Paint();


}
//This method will be called from the run method to show the image
public void drawImage(){

   Canvas canvas = this.getHolder().lockCanvas();
   canvas.drawColor(Color.BLACK);
   canvas.drawBitmap(bitImage, 0, 0, p);
   this.getHolder().unlockCanvasAndPost(canvas);
}
public void surfaceCreated(SurfaceHolder holder){
SlideThread thread=new SlideThread(holder,this);
thread.start(); //start images slide show
requestLayout();
}
public void surfaceDestroyed(SurfaceHolder holder){

}
public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){

}

public void setBitmap(Bitmap bitmap){
bitImage=bitmap;
}
}

class SlideThread extends Thread{
MyDrawArea marea;
SlideThread(SurfaceHolder holder,MyDrawArea area){
marea=area;
}

public void run(){
for(int i=0;i<bitmapRes.size();i++){
try{
marea.setBitmap(bitmapRes.get(i)); //set the image to show on the drawing area
marea.drawImage(); //call the drawImage method to show the image
Thread.sleep(2200); //delay each image show
}catch(InterruptedException ie){}

}
}

}
}


content_view.xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal"
/>



In the ContentFragment class, the drawing area object (MyDrawArea class extended SurfaceView class) is added to layout so that the images can be displayed. The SurfaceView class has a method called surfaceCreated. In this method, you will write code to show an images in slideshow view. The SlideThread extends the Thread class handles the image slideshow process. This thread will start from the surfaceCreated method. The run method of the SlideThread class is called when the thread starts. It loops throught the ArrayList object that contains the decoded images. The delay time between images show is specified by the sleep method of the Thread class. While the loop is working the drawImage method is called to show the image on the drawing area.
The ArrayList bitmapRes is used to store the decoded images. The processImage method is called when the ContentFragment starts. The processImage method will decode the images and add them to the bitmapRes. When decoding the image, you can specify a single dimension for all images to fit the screen. It is not good to display an 1050 x 1000 image on the 240 x 432 screen.

The MainActivity class that extends the FragmentActivity class will be used as the container of the BrowseFragment and ContentFragment. When the app firstly starts, BrowseFragment is added to container to display list of files and folders. The BrowseFragment is replaced by the ContentFragment when the user touches the show menu item to display the images. Below are the content of the MainActivity.java file and the layout file of the MainActivity class.

MainActivity.java file

package com.example.imageslider;
import java.io.File;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends FragmentActivity {
ArrayList<String> lstcheckeditems;
int mindex=0;
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState != null) {
        return;
        }
        //display the browse fragment to show the list of files and folders
        BrowseFragment bf=new BrowseFragment();
        FragmentTransaction transact=getSupportFragmentManager().beginTransaction();
        transact.add(R.id.fragment_container,bf);
        transact.addToBackStack(null);
        transact.commit();
     
 
    }

public void onBackPressed() {
LinearLayout view = (LinearLayout) findViewById(R.id.layout_view);      
if(view!=null){
BrowseFragment df=new  BrowseFragment();
FragmentTransaction transact=getSupportFragmentManager().beginTransaction();
transact.replace(R.id.fragment_container, df);
transact.addToBackStack(null);
transact.commit();
onStart();
}
else
System.exit(0);
}

public void onStart(){
 super.onStart();
 regControls();
 lstcheckeditems=new  ArrayList<String>() ;
}

public void regControls(){
EditText et=(EditText) findViewById(R.id.txt_input);
    et.addTextChangedListener(new ChangeListener());
    et.setText("/");
    ListView lv=(ListView) findViewById(R.id.files_list);
    lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    lv.setOnItemClickListener(new ClickListener());
}

class ChangeListener implements TextWatcher{
   
    public void beforeTextChanged(CharSequence s, int start, int before, int count){
   
   
    }
   
    public void onTextChanged(CharSequence s, int start, int before, int count){
    EditText et=(EditText) findViewById(R.id.txt_input);
    String txt=et.getText().toString();
    listDirContents(txt);
    }
   
    public void afterTextChanged(Editable ed){
   
   
    }
    }
 
    class ClickListener implements OnItemClickListener{
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      // selected item
            String selectedItem = ((TextView) view).getText().toString();
            EditText et=(EditText) findViewById(R.id.txt_input);        
            String path=et.getText().toString()+"/"+selectedItem;          
            File f=new File(path);
            if(f.isDirectory())
            et.setText(path);            
         
            else if(f.isFile() && (path.endsWith(".jpg") || path.endsWith(".png") || path.endsWith(".gif")))
            {
            if(lstcheckeditems.contains(path))
            lstcheckeditems.remove(path);
            else
            lstcheckeditems.add(path);
            }
           
      }
      public void onNothingSelected(AdapterView<?> parent){
     
      }
     
     
      }
 

 
    public void listDirContents(String path){
    ListView l=(ListView) findViewById(R.id.files_list);
   
    if(path!=null){
    try{
    File f=new File(path);    
    if(f!=null){
    String[] contents=f.list();
    if(contents.length>0){
    ArrayAdapter<String> aa=new ArrayAdapter<String>(this,R.layout.muliststyle,contents);
    l.setAdapter(aa);
    }
    }
    }catch(Exception e){}
    }
   
 
   
    }

    public void show(ArrayList<String> res){
    if(res.size()>0){
    ContentFragment cf=ContentFragment.newInstance(res);
    FragmentTransaction transact=getSupportFragmentManager().beginTransaction();
    transact.replace(R.id.fragment_container, cf);
    transact.addToBackStack(null);
    transact.commit();
    }
   
    }
 
 
 
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
    public boolean onOptionsItemSelected(MenuItem item)
    {
     
        switch (item.getItemId())
        {
        case R.id.menu_show:
        show(lstcheckeditems);
             return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }  

 
}

activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

The regControls method registers the text change event to the EditText component and the click event to the ListView component so that the user can make change to the text box and select items of the list. It is called when the main activity starts.
The listDirContents is also called when the main activity starts to read the files and folders from the root directory of Android device and show them in the list.
The show method is called when the user touches the show menu item. This method will replace the BrowseFragment by the ContentFragment fragment on the MainActivity. Then the images slideshow works. You will need to edit the main.xml file in the res/menu directory. This file defines the show menu item. The content of the main.xml file should look similar to the following:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:id="@+id/menu_show"
     android:title="Show" />
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:title="@string/action_settings"/>
 

</menu>

Now you are ready to run the program and test it. If you have questions, please leave them at the comment section. I will reply as soon as possible.
Merge or Combine PDF, Txt, Images

Friday, November 8, 2013

Keyboard

In this post, you will learn to set up a custom keyboard in your Android app. Implementing the custom keyboard can be useful when your app has to work with a language rather than English.
For this tutorial, i will talk about setting up a custom keyboard that has only twelve buttons. The nine-digit buttons are labeled from 0 to 9. The remaining two buttons are the delete button (represented by the delete icon) and the dot button. When a digit button is pressed, its label will be appended to the EditText component. The delete button will remove the last character from the EditText. The dot button allows the user to append a dot sign (.) to the EditText.

 keyboard


To follow this tutorial, now you need to create a new Android project in Eclipse. The project name will be Keyboard.
The first step you will do in setting up the custom keyboard is adding the KeyboardView component in the activity_main.xml file. We also need an EditText component to display the characters pressed by the user. Here is the content of the activity_main.xml file.
activity_main.xml file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/txt_edit"
        android:layout_width="wrap_content"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:gravity="top"
         />

    <android.inputmethodservice.KeyboardView
        android:visibility="gone"
        android:id="@+id/customkeyboard"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_gravity="bottom"
     
   />


</LinearLayout>


For another step, you have to write the buttons of the keyboard in a layout xml file. In this tutorial, this layout xml file of the keyboard is called keyboard.xml. The buttons can be grouped in rows by using the row tags. Each row consists of four to five buttons. You need to specify the code of each button and its label or icon. All row tags will be placed in the Keyboard tag. Below is the content of the keyboard.xml file.

keyboard.xml file

<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="33%p" android:horizontalGap="0px"
    android:verticalGap="0px" android:keyHeight="54dip">
     <Row>
             
                <Key android:codes="49" android:keyLabel="1" />
                <Key android:codes="50" android:keyLabel="2" />              
          <Key android:codes="51" android:keyLabel="3"/>
          <Key android:codes="8"  android:keyIcon="@drawable/delete_icon" />
        </Row>

        <Row>
             
                <Key android:codes="52" android:keyLabel="4" />
                <Key android:codes="53" android:keyLabel="5" />
                <Key android:codes="54" android:keyLabel="6" />
                <Key android:codes="55" android:keyLabel="7" />
        </Row>
        <Row>
             
                <Key android:codes="56" android:keyLabel="8" />
                <Key android:codes="57" android:keyLabel="9" />
                <Key android:codes="48" android:keyLabel="0" />
                <Key android:codes="46" android:keyLabel="."/>
        </Row>

</Keyboard>


In the keyboard.xml file, the delete button is presented by the delete icon. Instead of using the keyLabel to specifying label of the button, you will use the keyIcon to specify the icon of the delete button.

In the last step, you need to write code to place the keyboard layout on the KeyboardView component and show it and to receive keys pressed by the user. The code will be written in the MainAcivity.java file. The Keyboard object will be created to point to the layout file. Then this object is supplied to KeyboardView component so that it is ready to show.
To receive the keys pressed on the keyboard, the KeyboardView component must be registered with the KeyboardActionListenter interface. The onPress method of the interface has to be implemented to receive the keys. Here is the content of the MainActivity.java file.

MainActivity.java file

package com.example.keyboard;


import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
import android.os.Bundle;
import android.app.Activity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity{

    private EditText et;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //create Keyboard object
        Keyboard keyboard=new Keyboard(this, R.layout.keyboard);
        //create KeyboardView object
        KeyboardView keyview=(KeyboardView)findViewById(R.id.customkeyboard);
        //attache the keyboard object to the KeyboardView object
        keyview.setKeyboard(keyboard);
        //show the keyboard
        keyview.setVisibility(KeyboardView.VISIBLE);
        //take the keyboard to the front
        keyview.bringToFront();
        //register the keyboard to receive the key pressed
        keyview.setOnKeyboardActionListener(new KeyList());
        et=(EditText)findViewById(R.id.txt_edit);
     
    }
    class KeyList implements OnKeyboardActionListener{
    public void onKey(View v, int keyCode, KeyEvent event) {
   
    }
      public void onText(CharSequence text){
   
    }
    public void swipeLeft(){
   
    }
    public void onKey(int primaryCode, int[] keyCodes) {
   
    }
    public void swipeUp(){
   
    }
    public void swipeDown() {
   
    }
    public void swipeRight() {
   
    }
    public void onPress(int primaryCode) {
   
    if(primaryCode==8){ //take the last character out when delete button is pressed.
    String text=et.getText().toString();
    if(et.length()>0){
    text=text.substring(0,text.length()-1);
    et.setText(text);
    et.setSelection(text.length());
    }
    }
    else{
    char ch=(char)primaryCode;
    et.append(""+ch);
    }
    }
    public void onRelease(int primaryCode) {
   
    }
    }
 

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
}

Now you are ready to run the Keyboard app. If you have any questions, please leave them at the comment section. I will reply as soon as possible.

compass app flashLight app

Thursday, October 31, 2013

NotePad

In this post, you will learn to create a simple NotePad app for Android. The NotePad app can be used to view files that contain text inside. These files can be txt, html, xml, and java files. You can open the app and then browse for a file to open or alternatively you can select a file from Android to open. The current document can be edited and saved. The user can create a new file by clicking the new document icon from the action bar. The new file will be stored in the notes directory of external card of the device.

NotePad for Android


To start developing the NotePad app, now you need to create a new project. The project name will be NotePad. There are two activities in this app. The first one is the MainActivity that firstly runs when the NotePad opens. This activity represents the interface that allows the user to select a file to open.

NotePad browse for file


This MainActivity will list files and folders in the external card of the device. Below is the content of the activity_main.xml file. In this file, one ListView component is defined. The ListView will display the list of files and folders for selection.

activity_main.xml file

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
            android:id="@+id/files_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingBottom="5dp"
            android:paddingTop="5dp"
     
            />

</RelativeLayout>


Each row or item of the ListView displays both image and text. The image will be the file icon image or directory image. Thus it must be customized to work in this way. When customizing the ListView, as i mentioned in the previous posts, you need to define the layout file of the list and the data source of the list. Here is the content of the listlayout.xml file of the list.

listlayout file

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

<ImageView
    android:id="@+id/icon"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="5sp"
    android:contentDescription="icon_image"
 />

<TextView
    android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#0000ff"
        android:textStyle="bold" >
</TextView>
</LinearLayout>


The data source of the list will be an instance of the class that extends the ArrayAdapter class. I call it ListAdapterModel class. You can download the ListAdapterModel.java file from here.
To get explanation about customizing the data source of the ListView, you might want to read the File Chooser post.

When a file is selected from the list, another activity will open and the content of the file is shown there. The data to be sent from the MainActity of the second activity (NoteActivity) is the full path of the file. The openNoteActivity method of the MainActivity class will be called to send the path file to the NoteActivity. Click the MainActivity to download the MainActivity.java file.
On the NoteActivity, you will see the content of the selected file. The EditText component is used to display the file content and allow the user to edit the content. Below is the layout file of the NoteActivity.

activity_note.xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"  
    android:background="#dfdfdf"    
     >

 <EditText
     android:id="@+id/txt_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:scrollbars="vertical"  
     android:textColor="#000000"
     android:gravity="top"
     android:inputType="text"
     android:textSize="16sp" />

</RelativeLayout>

You can download the NoteActivity.java file from here. The NoteActivity has an action bar. To support the old Android versions, the NotePad app uses the SherlockActionBar library to set up the action bar. You might want to read TexViewer to learn how to import this library in to your project. On the action bar, there are four items. The first item represented by the new document icon will be clicked to call the createNew method so that a new blank document will open. The second item allows you to save the edited document by calling the saveWork document. The third and forth items allow you to zoom in or zoom out the content of the current document by calling the zoomin and zoomout methods.. The items of the action bar are defined in the note.xml file that is stored in the menu folder of the project.

note.xml file

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/Theme.Sherlock"
    >
 
    <item
        android:id="@+id/newitem"
        android:icon="@drawable/new_icon"
        android:title="new"
        android:showAsAction="always"
        style="@style/Theme.Sherlock"
     
    />
    <item
        android:id="@+id/saveitem"
        android:title="save"
        android:showAsAction="always"
        android:icon="@drawable/save_icon"
        style="@style/Theme.Sherlock"
    />
    <item
        android:id="@+id/zoomin"
        android:title="zoomin"
        android:showAsAction="always"
        android:icon="@drawable/zoomin"
        style="@style/Theme.Sherlock"
    />

    <item
        android:id="@+id/zoomout"
        android:title="zoomout"
        android:showAsAction="always"
        android:icon="@drawable/zoomout"
        style="@style/Theme.Sherlock"
    />

</menu>

Before running the NotePad app, you need to edit the AndroidManifest file of the project to allow the app to use the external sdcard and to register the app in the list of avaiable apps to open the selected file. Here is the content of the AndroidManifest.xml file.

AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.notepad"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/note_icon"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock.Light.DarkActionBar" >
        <activity
            android:name="com.example.notepad.MainActivity"
            android:configChanges="orientation"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.txt" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.rtf" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.java" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.xml" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.html" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.txt" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.rtf" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.java" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.xml" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.html" />
                <data android:host="*" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.notepad.NoteActivity"
            android:label="@string/title_activity_note"
            android:configChanges="orientation"
            android:parentActivityName="MainActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="MainActivity" />
        </activity>
    </application>

</manifest>


Download the apk file of the NotePad app

Sunday, October 27, 2013

Assignment Manager

This is an Assignment Manager app for students. The Assignment Manager app can be used to store information about your assignments and people in each assignment. You can add new assignments to the database or delete assignments from the database. It will alert you three days in advance before the deadline of the assignment. It allows you to add people to an assignment and delete people from the assignment. You are easily to share information about the assignment and group members with file attachment to all members in the assignment.
To start developing the Assignment Manager app, you need to create a new project in Eclipse. This application name will be called AssMger. There are two activities in this app. The first one, the main activity or user interface that lists the recent added assignments, allows the user to add new assignments to the database, to delete assignments from the databases, and to open another activity to manage people in the selected assignment.

assignment manager main interface


By pushing the detail button (>>) next to the assignment, the assignment detail will be shown on the dialog. Each assignment contains the following information: id, topic, description, lecturer/teacher name, room number/code, and deadline.

assignment detail


To open the user interface for managing the members in the assignment, you will push the member button (next to the detail button). These buttons are available only if there is at least one assignment in the list.

The SherlockFragmentActivity class is used to construct the main interface. The AManager class extends SherlockFragmentActivity to represent the main interface.The layout file of the AManager class simply contains a FrameLayout. The FrameLayout is the container of all sub-interfaces. This layout file is called activity_amanager.xml. You can download all layout files in this app from here.

activity_amanager.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ass_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>


On the main interface, there are two sub-interfaces that will be added and removed dynamically. One sub-interface is defined by the AssListFragment class that extends the SherlockFragment class. This sub-interface will be shown when the showAssList method of the AManager class method is called. The layout file (asslist_view.xml file) of the AssListFragment class contains a ListView component.

asslist_view.xml file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/back_style"
>

 
    <ListView
        android:id="@+id/ass_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
     
    </ListView>

</LinearLayout>


The ListView component is used to display assignment icon, assignment id, detail button, and member button. So each item of the ListView contains four elements. Here is the content of listlayout.xml file that defines the four elements of the ListView.

listlayout.xml file

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

<ImageView
    android:id="@+id/icon"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="5sp"
    android:contentDescription="@string/image_des"
 />

<TextView
    android:id="@+id/key"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#0000ff"
        android:textStyle="bold" >
</TextView>
<Button
    android:id="@+id/btdetail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#0000ff"
        android:textStyle="bold"
        android:onClick="showDetail"  
  android:focusable="false"
  android:background="@drawable/bt_style"
 
         >
</Button>

<Button
    android:id="@+id/btmember"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#0000ff"
        android:textStyle="bold"
        android:onClick="linkToMember"  
  android:focusable="false"
  android:background="@drawable/bt_style"
  android:drawableLeft="@drawable/people_small"
 
         />

</LinearLayout>


Each button has the same background style. The background style for all buttons in this applications is defined in the bt_style.xml file that is stored in the drawable folder.

bt_style.xml file

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid
                android:color="#ff00ff" />
            <stroke
                android:width="1dp"
                android:color="#171717" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                android:startColor="#000000"
                android:endColor="#000000"
                android:angle="270" />
            <stroke
                android:width="1dp"
                android:color="#171717" />
            <corners
                android:radius="1dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>

The ListModelAdapter class that represents the data source of the ListView is defined in the ListAdapterModel.java file. If you are new to the ListView customization, you will need to read FileChooser page.
By pushing the detail button (>>) , the showDetail method of the AManager class displays the detail of the assignment in a dialog. The dialog is displayed by calling the showAlert method of the MessageAlert class that is defined in the MessageAlert.java file.

MessageAlert.java file

package com.example.assmger;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.View;

public class MessageAlert {
private View view;
private Context context;
MessageAlert(View view, Context context){
this.view=view;
this.context=context;

}
//This method will be invoked to display alert dialog
    public void showAlert(String title){
   
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage(title);
        builder.setCancelable(true);
        builder.setView(view);
        builder.setPositiveButton("OK", new OnClickListener(){
        public void onClick(DialogInterface dialog, int which) {
          dialog.dismiss();
          }

        });
     
        AlertDialog dialog = builder.create();      
        dialog.show();
   
    }
}


When the member button (represented by the human icon) is clicked, the linkToMember of the AManager class is called to open another activity that lets you add members to the database, delete members from the database, and share information to all members in the assignment.
Another sub-interface allows you to add a new assignment to the database. This sub-interface defined by the AddAssFragment class displays when the user touches the new icon from the action bar. The showAddAssForm of the AManager class is called to display the sub-interface. On this interface, you will fill all required information about the new assignment and press the Go button to invoke the addAss method of the AManager class to add the assignment information to the database.

add new assignment


The items (represented by the new and delete icons) of the action bar are defined in the amanager.xml file that is in the menu folder. All icons of the items are stored in the drawable folder. You can download them from here. The new icon will be pushed to pop up a form that lets the user fill in the assignment information and add the information to the database. By selecting an assignment from the list and pressing the delete icon, the deleteAss method of the AManger class will be invoked to delete the assignment from the database. This will also delete all people in the assignment from the database. In this app, the SherlockActionBar library is used to set up the action bar so you need to import the SherlockActionBar project in to the Assignment Manager app. If you are new to SherlockActionBar, please read the TextViewer post. It helps you get start setting up action bar by using the SherlockActionBar library.

amanager.xml file

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/Theme.Sherlock"
    >
 
    <item
        android:id="@+id/addass"
        android:title="@string/item_add"
        android:icon="@drawable/new_ass"
        android:showAsAction="always"
        style="@style/Theme.Sherlock"
    />
    <item
        android:id="@+id/deleteass"
        android:title="@string/item_delete"
        android:showAsAction="always"
        android:icon="@drawable/delete_ass"
        style="@style/Theme.Sherlock"
    />

 

</menu>


Another activity is called MManager class. It is defined in the MManager.java file. The second activity is launched when the user clicks the member button from the main activtivity (AManager). The second activity allows you to add people to the selected assignment, delete people from the assignment, and share information about assignment and people with file attachment to all people in the assignment. Similarly, on the MManager activity there are two sub-activities or interfaces. One sub-activity that extends the SheklockFragment class is called MemListFragment. This sub-interface shows a list of people in the assignment. Here is the content of the MemListFragment.java file and its resource layout file (memlist_view.xml).

MemListFragment.java file

package com.example.assmger;

import com.actionbarsherlock.app.SherlockFragment;

import android.os.Bundle;
//import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MemListFragment extends SherlockFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.memlist_view, container, false);
}

public static MemListFragment newInstance(String str){

return(new MemListFragment());
}


}


memlist_view.xml file

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/back_style"
>

 
    <ListView
        android:id="@+id/mem_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
   
        >
     
    </ListView>

</LinearLayout>



If you want to view the detail about a person, click the detail button (>>) next to the name of that person. This will show a dialog that contains the detail about the person.


member detail


The ListView used in the MemListFragment also must be customized to show the human icons, person's names, and the detail buttons. So each item of the ListView has three components that need to be defined in its listlayout_member.xml file. The data source of the ListView is defined by the ListAdapterModelMember class. Click here to download the ListAdapterModelMember class.java file.

listlayout_member.xml file

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

<ImageView
    android:id="@+id/icon"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="5sp"
    android:contentDescription="@string/image_des"
 />

<TextView
        android:id="@+id/mem_name"
        android:layout_width="180dp"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#0000ff"
        android:textStyle="bold" >
</TextView>
<Button
        android:id="@+id/btmemberdetail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#0000ff"
        android:textStyle="bold"
        android:onClick="showDetail"  
        android:focusable="false"
        android:background="@drawable/bt_style"
         >
</Button>

</LinearLayout>


The MManager class also has its own layout file that will be used as the container of all its sub-interfaces. This layout file is called activity_mmanager.xml file.

activity_mmanager.xml file

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mem_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"

/>

Another sub-activity or interface is defined by the AddMemFragment class. This sub-activity allows you to fill in the required information about a person of the assignment and add the person in the database. Here is the content of the AddMemFragment class and its layout file (mem_add.xml).

AddMemFragment.java file

package com.example.assmger;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;


public class AddMemFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment

return inflater.inflate(R.layout.mem_add, container, false);
}
public static AddMemFragment newInstance(String str){
return(new AddMemFragment());
}


public void onAttach(Activity activity){
super.onAttach(activity);
}

public void onStart(){
super.onStart();
setUpSpinnerData();
}
public void setUpSpinnerData(){
    Spinner sp=(Spinner)getActivity().findViewById(R.id.sex_spinner);
    String[] items={"F","M"};
    ArrayAdapter<String> aa=new ArrayAdapter<String>(getActivity(),R.layout.spinner_style,items);
    sp.setAdapter(aa);
   
    }

}

mem_add.xml file

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"

     android:layout_width="match_parent"
     android:layout_height="match_parent"
 
     >  

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@drawable/back_style"
    >

    <EditText
        android:id="@+id/member_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="@string/member_name" />


    <Spinner
android:id="@+id/sex_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
 
    <EditText
        android:id="@+id/member_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/member_tel"
        android:inputType="phone" />

     <EditText
         android:id="@+id/member_email"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:hint="@string/member_email"
         android:inputType="textEmailAddress" />

     <EditText
        android:id="@+id/member_task"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:gravity="top"
        android:hint="@string/member_task" />

 
<Button
   android:id="@+id/bt_addmember"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bt_save"
android:textColor="#0000ff"
android:background="@drawable/bt_style"
android:onClick="addMember" />

</LinearLayout>
</ScrollView>


The MManager activity also has the action bar. The action bar contains three items that are defined in the mmanager.xml file stored in the menu folder.

mmanager.xml file

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/Theme.Sherlock"
    >
 
    <item
        android:id="@+id/addmember"
        android:title="@string/item_add"
        android:icon="@drawable/people"
        android:showAsAction="always"
        style="@style/Theme.Sherlock"
    />
    <item
        android:id="@+id/deletemember"
        android:title="@string/item_delete"
        android:showAsAction="always"
        android:icon="@drawable/delete_ass"
        style="@style/Theme.Sherlock"
    />
      <item
        android:id="@+id/share"
        android:title="@string/item_share"
        android:showAsAction="always"
        android:icon="@drawable/share_ass"
        style="@style/Theme.Sherlock"
    />

 

</menu>

The first item of the action bar is the new icon. It will be touched to show the AddMemFragment interface by calling the addMember method of the MManager class.

add new member

By clicking the delete icon, the selected person will be removed from the assignment by calling the deleteMemer method of the MManager class. The last item allows you to display the file chooser dialog for file attachment and send all information about the selected assignment and its members with file attachment to all members in the assignment by calling the sendEmail method of the MManager class.

attach file chooser


The FileChooser class is constructed as sub class of the MManager class to show the file chooser dialog and handle file and folder section. The FileChooser also use a ListView component to display files and folders for selection. This ListView also customized to display both icons and text. Here is the content of the layout file of the ListView used in the FileChooser class.

listlayout_filechooser.xml file

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip"
 
    >


<ImageView
    android:id="@+id/icon"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="5sp"
    android:contentDescription="@string/image_des"
 />

<TextView
    android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textStyle="bold" >
</TextView>
</LinearLayout>


For the complete code of the ListAdapterModelFileChooser class that acts as the data source of the ListView can be download from here.
There are some string variables that are used in different layout files of the app. These string variables are defined in the strings.xml file. Here is the content of the strings.xml file.

strings.xml file

 <?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">AssMger</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="title_activity_amanager">AManager</string>
    <string name="title_activity_mmanager">MManager</string>
    <string name="ass_id">Enter id</string>
    <string name="ass_topic">Enter topic</string>
    <string name="ass_des">Enter description</string>
    <string name="ass_lecturer">Enter lecturer name</string>
    <string name="ass_room">Enter room</string>
    <string name="ass_deadline">Deadline</string>
    <string name="ass_days">How many days to alert before the deadline reaches?</string>
    <string name="bt_pickdate">Pick</string>
    <string name="member_name">Enter name</string>
    <string name="member_tel">Enter phone</string>
    <string name="member_email">Enter email</string>
    <string name="member_task">Enter tasks to do</string>
    <string name="bt_save">Go</string>
    <string name="item_add">Add</string>
    <string name="item_delete">Delete</string>
    <string name="item_share">Share</string>
    <string name="bt_pick">Pick</string>
    <string name="image_des">Icon Image</string>
</resources>

Setup Notification for the Assignment Manager

As i mentioned above, the Assignment Manager is able to alert the user three days in advance before the deadline is reached. In Android, we can accomplish this task by using the AlarmManager class and NotificationManager class. The AlarmManager class is used to schedule the date and time to notify the user. The NotificationManager class will be used to handle the notification to the user at the specified date and time.

In the AManager, there is a method called setUpAlarm. This method will be invoked immediately after a new assignment is added to the database. This method accepts the number of days between the current date and the deadline to be its argument. This number of days will be subtracted by 3. The result of the subtraction will be added to the Carlendar object so that the date to alert the user is in the future that is three days before the deadline. The number of days between the current date and the deadline is calculated by using the Days class of the Joda-Time library. You need to copy and paste the Joda-Time library jar file to the lib folder of the project.
The setUpAlarm method specifies the PendingIntent object and the date and time to send this intent object to the broadcast receiver. This date and time will be three days before the deadline of the assignment. The broadcast receiver defined in MyReceiver class that extends the BroadcastReceiver class will get the intent object sent from the alarm mamanager. Then the notification object is constructed to handle the notification to the user. Here is the content of the MyReceiver class.

MyReceiver.java file

package com.example.assmger;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;


public class MyReceiver extends BroadcastReceiver {
private static final int MY_NOTIFICATION_ID=1;
    NotificationManager notificationManager;
    Notification myNotification;
 
 
public void onReceive(Context c, Intent i) {
         PendingIntent pi = PendingIntent.getBroadcast(c, 0, new Intent("com.example.assmger"),0 );
         myNotification=new NotificationCompat.Builder(c)
         .setContentTitle("Your assignment dealine is comming soon.")
         .setContentText("Assignment Notification")      
         .setTicker("Notification!")
         .setWhen(System.currentTimeMillis())
         .setContentIntent(pi)
         .setDefaults(Notification.DEFAULT_SOUND)                      
         .setAutoCancel(true)
         .setSmallIcon(R.drawable.assmanager)
         .build();
         
         notificationManager = (NotificationManager)c.getSystemService(Context.NOTIFICATION_SERVICE);
         notificationManager.notify(MY_NOTIFICATION_ID, myNotification);
       
         }
}


This broadcast receiver has to register in AndroidManifest.xml file so that it can receive the intent sent from the alarm manager. The content of the AndroidManifest file is modified to the following.

AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.assmger"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/assmanager"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock.Light.DarkActionBar" >
        <activity
            android:name="com.example.assmger.AManager"
            android:label="@string/app_name"
            android:configChanges="orientation"
             >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="com.example.assmger.MyReceiver" >
            <intent-filter>
                <action android:name="com.example.assmger" />
            </intent-filter>
        </receiver>

        <activity
            android:name="com.example.assmger.MManager"
            android:label="@string/title_activity_mmanager"
            android:configChanges="orientation"
            android:parentActivityName="com.example.assmger.AManager" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.assmger.AManager" />
        </activity>
    </application>

</manifest>

Setup Database for the Assignment Manager

The Assignment Manager app uses SQLite database to store information about assignments and members of the assignments. The DataHelper class is written to help us in creating database and tables. Here is the content of the DataHelper class.

DataHelper. java file

package com.example.assmger;
import com.example.assmger.DDataScema.MetaInfo;
import com.example.assmger.DDataScema.MetaInfoMem;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DataHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "assmger.db";
private String createtbl="CREATE TABLE "+MetaInfo.TABLE_NAME+" ("+MetaInfo.COL_NAME_KEY+" TEXT PRIMARY KEY UNIQUE, "+
MetaInfo.COL_NAME_TOPIC+" TEXT, "+MetaInfo.COL_NAME_DES+" TEXT, "+MetaInfo.COL_NAME_LEC+" TEXT, "+MetaInfo.COL_NAME_ROOM+" TEXT, "
+MetaInfo.COL_NAME_DEADLINE+" TEXT)";
private static final String deletetbl="DROP TABLE IF EXISTS " + MetaInfo.TABLE_NAME;

private String createtblmem="CREATE TABLE "+MetaInfoMem.TABLE_NAME+" ("+MetaInfoMem.COL_NAME_NAME+" TEXT PRIMARY KEY UNIQUE, "+
MetaInfoMem.COL_NAME_SEX+" TEXT, "+MetaInfoMem.COL_NAME_PHONE+" TEXT, "+MetaInfoMem.COL_NAME_EMAIL+" TEXT, "+MetaInfoMem.COL_NAME_TASK+" TEXT, "+MetaInfoMem.COL_NAME_KEY+" TEXT)";

private static final String deletetblmem="DROP TABLE IF EXISTS " + MetaInfoMem.TABLE_NAME;
public DataHelper(Context context){
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}

public void onCreate(SQLiteDatabase db){
db.execSQL(createtbl);
db.execSQL(createtblmem);
}

public void onUpgrade(SQLiteDatabase db,int olv,int newv){
db.execSQL(deletetbl);
db.execSQL(deletetblmem);
onCreate(db);
}


}


When you create an instance or object of the DataHelper class, its constructor is called to create a database file (if it does not exist). The onCreated method will be called automatically after you create the instance or object of the DataHelper class. This will create two tables (if they do not exist). One table is for storing the assignments' information and another one is for storing the people's information. The names of the tables and their columns or fields are defined in the DDSchema class. Here is the content of the DDSchema.java file.

DDSchema.java file

package com.example.assmger;

import android.provider.BaseColumns;

public class DDataScema {
public DDataScema(){}
public static abstract class MetaInfo implements BaseColumns{
public static final String TABLE_NAME="tblassigments";
public static final String COL_NAME_KEY="AssId";
public static final String COL_NAME_TOPIC="AssTopic";
public static final String COL_NAME_DES="AssDes";
public static final String COL_NAME_ROOM="AssRoom";
public static final String COL_NAME_LEC="Lecturer";
public static final String COL_NAME_DEADLINE="AssDeadline";

}

public static abstract class MetaInfoMem implements BaseColumns{
public static final String TABLE_NAME="tblmembers";
public static final String COL_NAME_KEY="AssId";
public static final String COL_NAME_NAME="MemName";
public static final String COL_NAME_SEX="MemSex";
public static final String COL_NAME_PHONE="MemPhone";
public static final String COL_NAME_EMAIL="MemEmail";
public static final String COL_NAME_TASK="MemTask";

}
}


The DataHelper class is used in both the AManager class and the MManager class. The readAss of the AManager method is called from the showAssList method to retrieve the assignments'information from the tblassigments table and show them on the list. Its addAss method will be called to insert the new assignment to the table.
Similarly, in the MManager class, the readMem method is called from the showMemList method to retrieve people's information from the tblmembers table. Its addMember method will be called to insert a new person'information to the table.

DatePickerDialog

On the AddAssFragment interface that allows you to fill in the new assignment information and submit the information to the database, you will see the Pick button. This button allows you to select a date from the date picker dialog. The date picker dialog can be created by using a dialog fragment class that implements the DatePickerDialog.OnDateSetListener. In the Assignment Manager app, the DateDialog class (the inner class or sub class of the AManager class) extends the SherlockFragmentDialog is written to provide the date picker dialog to the user.

date picker


Now you are ready to try the Assignment Manager app. If you have any questions, please feel free to leave them at the comment section below. You can download the Assignment Manager apk file to install on your Android device from the link below.

Download the apk file of the Assignment Manager app

nightmode  app Digital clock tdve wallpaper app