Wednesday, 19 August 2015

Android 6.0 Marshmallow: Top features

Android 6.0 Marshmallow
After the guessing game that went on for months, Google has finally announced its next Android iteration will be named after the sweet treat Marshmallow. So, now M is for Marshmallow.
Marshmallow was one of the highly speculated name that fits Google’s nomenclature of sweet treats like – Cup Cake, Eclair, Froyo, Gingerbread, Honeycomb, Ice Cream Sandwich, Jelly Bean, KitKat and Lollipop. It beat other probable names like mud pie, mousse, and our very favourite Malai Barfi.
The company revealed the name on its developers blog and alongside also revealed the final Android 6.0 SDK that will be available for download via the SDK Manager in Android Studio. It will bring access to final Android APIs and latest build tools.
“Today with the final Developer Preview update, we’re introducing the official Android 6.0 SDK and opening Google Play for publishing your apps that target the new API level 23 in Android Marshmallow,” Jamal Eason, Product Manager, Android writes in a blogpost.
Marshmallow brings new platform features such as fingerprint scanner and Doze power saving mode, but along with that also offers new permissions model.
Google Play is also made ready to accept API 23 apps via the Google Play Developer Console. At the consumer launch later this year, the Google Play store will be updated so that the app install and update process supports the new permissions model for apps using API 23.
“Classes for detecting and parsing bar codes are available in the com.google.android.gms.vision.barcode namespace. The BarcodeDetector class is the main workhorse — processing Frame objects to return a SparseArray<Barcode> types,” he further adds.
Google has also revaled its new lawn statue similar to the droid seen above.
Needless to say, Android Marshmallow brings new app permissions, custom Chrome Tabs, fingerprint support and improved power management.
Take a look at some of its cool new features announced earlier this year:
App Permissions 
The App Permissions got a major overhaul and Google will allow users to decide which permissions they want to allow or revoke, based on when those particular functions are used. Unlike the current implementation, where users have to agree to all app permissions on first install and also for updates, in Android M, users will get notifications asking for permissions only when they are using a particular function in an app.
Google has identified eight parameters including location, camera, contacts and so on, to help you give permissions for these. So for instance, in WhatsApp if you want to send a voice message, the App Permissions tab will pop up, asking you for permission to use the microphone. You can also revoke the permission later if you so wish. Also, app updates will also not ask you for permissions off the bat, unless you are using a feature which needs you to grant that particular app some permission.
Web Experience: Custom Chrome Tabs
The web browsing experience with the Chrome browser also gets a shot in the arm. Chrome Custom tabs, a new feature, that will let you include webviews within a particular app, without the need to switch to the Chrome browser on your phone. The Chrome browser will run atop your app (in case you click on any link within the app). Features such as automatic sign-in, saved passwords, autofill will work on the apps seamlessly. Also the Chrome Custom tab will take up the colours and fonts of the app it is being opened within, to make it seem like a seamless experience. In principle it seems closer to Facebook’s Instant Articles, with the difference being that the Chrome Custom tabs will make you feel like you are within the app that you are browsing.
App Linking
Android currently supports the app linking system, also known as Intents, which gives you the choice to open a particular web link in a web browser or an app. Before, if you had a Twitter link in say your inbox and you clicked on it, you got a prompt asking if you want to open the link in your browser or within the Twitter app, which is installed on your phone.
Android M will let developers add in an auto-verify feature within their code, which will help open the link within the respective app (provided the app is installed on your phone). In the background, the Android M OS will verify the link with the app’s server and post-authentication will proceed to open the link within the app itself, without asking you where you want to open the link.
Android Pay
This feature will let you make your payments using near-field communication (NFC) and host card emulation techniques for tap-to-pay services. You just need to unlock your phone, keep it near an NFC terminal and your payment is done, without opening any app. Google says when you add in your card details, a virtual account number is created to make your payments. Your actual card number is not shared with the store during the transaction.
According to Google, Android Pay will be pre-installed on AT&T, Verizon and T-Mobile devices and will be accepted in around 700,000 stores in the US which accept contact-less payment. Android Pay will replace the Google Wallet app. Android Pay can also be used to make in-app payments provided developers integrate Pay into their apps.
Fingerprint Support
Android M will standardise the fingerprint sensor support and it is working with various phones to make a standard API to go with their sensors. You can use your fingerprint to authorise an Android Pay transaction, unlock your device or make Play Store purchases.
Power management
Android M will feature a smart power-managing feature called Doze. This feature works by letting system optimally manage the background processes. The OS keeps a tab on the motion detection sensor and if there is no activity for a long time, the system shuts down some processes. Since it is in the Doze stage, the system can still get activated by alarms and high priority notifications. According to Google, this feature has helped increase the standby-time on the Nexus 9 by almost two times over the Android 5.0 Lollipop.
Android M will also support USB Type-C for charging. And considering USB Type-C is has a bi-directional port, you can use this port to either charge the phone as welll as charge another device.
Apart from these main features, some of the other improvements include a better implementation of Copy/Paste function. So in Android M, you will get a floating toolbar just above your selection with the Cut, Copy, Paste options. Direct Share feature will let you share images or links with your most frequently shared contacts or apps, using a single click. Volume controls will also give you a drop-down menu, a feature that is common on the Cyanogen OS.


Saving Data in SQL Databases

Using Databases
Saving data to a database is ideal for repeating or structured data, such as contact information. This class assumes that you are familiar with SQL databases in general and helps you get started with SQLite databases on Android. The APIs you'll need to use a database on Android are available in the android.database.sqlitepackage.
Define a Schema and Contract
One of the main principles of SQL databases is the schema: a formal declaration of how the database is organized. The schema is reflected in the SQL statements that you use to create your database. You may find it helpful to create a companion class, known as a contract class, which explicitly specifies the layout of your schema in a systematic and self-documenting way.
A contract class is a container for constants that define names for URIs, tables, and columns. The contract class allows you to use the same constants across all the other classes in the same package. This lets you change a column name in one place and have it propagate throughout your code.
A good way to organize a contract class is to put definitions that are global to your whole database in the root level of the class. Then create an inner class for each table that enumerates its columns.
Note: By implementing the BaseColumns interface, your inner class can inherit a primary key field called_ID that some Android classes such as cursor adaptors will expect it to have. It's not required, but this can help your database work harmoniously with the Android framework.
For example, this snippet defines the table name and column names for a single table:
public final class FeedReaderContract {
    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    public FeedReaderContract() {}
    /* Inner class that defines the table contents */
    public static abstract class FeedEntry implements BaseColumns {
        public static final String TABLE_NAME = "entry";
        public static final String COLUMN_NAME_ENTRY_ID = "entryid";
        public static final String COLUMN_NAME_TITLE = "title";
        public static final String COLUMN_NAME_SUBTITLE = "subtitle";
        ...
    }
}
Create a Database Using a SQL Helper
Once you have defined how your database looks, you should implement methods that create and maintain the database and tables. Here are some typical statements that create and delete a table:
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
    "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
    FeedEntry._ID + " INTEGER PRIMARY KEY," +
    FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
    FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
    ... // Any other options for the CREATE command
    " )";
private static final String SQL_DELETE_ENTRIES =
    "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;
Just like files that you save on the device's internal storage, Android stores your database in private disk space that's associated application. Your data is secure, because by default this area is not accessible to other applications.
A useful set of APIs is available in the SQLiteOpenHelper class. When you use this class to obtain references to your database, the system performs the potentially long-running operations of creating and updating the database only when needed and not during app startup. All you need to do is call getWritableDatabase() orgetReadableDatabase().
Note: Because they can be long-running, be sure that you call getWritableDatabase() orgetReadableDatabase() in a background thread, such as with AsyncTask or IntentService.
To use SQLiteOpenHelper, create a subclass that overrides the onCreate(), onUpgrade() and onOpen()callback methods. You may also want to implement onDowngrade(), but it's not required.
For example, here's an implementation of SQLiteOpenHelper that uses some of the commands shown above:
public class FeedReaderDbHelper extends SQLiteOpenHelper {
    // If you change the database schema, you must increment the database version.
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "FeedReader.db";
    public FeedReaderDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // This database is only a cache for online data, so its upgrade policy is
        // to simply to discard the data and start over
        db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}
To access your database, instantiate your subclass of SQLiteOpenHelper:
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
Put Information into a Database
Insert data into the database by passing a ContentValues object to the insert() method:
// Gets the data repository in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
// Insert the new row, returning the primary key value of the new row
long newRowId;
newRowId = db.insert(
         FeedEntry.TABLE_NAME,
         FeedEntry.COLUMN_NAME_NULLABLE,
         values);
The first argument for insert() is simply the table name. The second argument provides the name of a column in which the framework can insert NULL in the event that the ContentValues is empty (if you instead set this to"null", then the framework will not insert a row when there are no values).
Read Information from a Database
To read from a database, use the query() method, passing it your selection criteria and desired columns. The method combines elements of insert() and update(), except the column list defines the data you want to fetch, rather than the data to insert. The results of the query are returned to you in a Cursor object.
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
    FeedEntry._ID,
    FeedEntry.COLUMN_NAME_TITLE,
    FeedEntry.COLUMN_NAME_UPDATED,
    ...
    };
// How you want the results sorted in the resulting Cursor
String sortOrder =
    FeedEntry.COLUMN_NAME_UPDATED + " DESC";
Cursor c = db.query(
    FeedEntry.TABLE_NAME,  // The table to query
    projection,                               // The columns to return
    selection,                                // The columns for the WHERE clause
    selectionArgs,                            // The values for the WHERE clause
    null,                                     // don't group the rows
    null,                                     // don't filter by row groups
    sortOrder                                 // The sort order
    );
To look at a row in the cursor, use one of the Cursor move methods, which you must always call before you begin reading values. Generally, you should start by calling moveToFirst(), which places the "read position" on the first entry in the results. For each row, you can read a column's value by calling one of the Cursor get methods, such as getString() or getLong(). For each of the get methods, you must pass the index position of the column you desire, which you can get by calling getColumnIndex() or getColumnIndexOrThrow(). For example:
cursor.moveToFirst();
long itemId = cursor.getLong(
    cursor.getColumnIndexOrThrow(FeedEntry._ID)
);
Delete Information from a Database

To delete rows from a table, you need to provide selection criteria that identify the rows. The database API provides a mechanism for creating selection criteria that protects against SQL injection. The mechanism divides the selection specification into a selection clause and selection arguments. The clause defines the columns to look at, and also allows you to combine column tests. The arguments are values to test against that are bound into the clause. Because the result isn't handled the same as a regular SQL statement, it is immune to SQL injection.
// Define 'where' part of query.
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = { String.valueOf(rowId) };
// Issue SQL statement.
db.delete(table_name, selection, selectionArgs);
Update a Database
When you need to modify a subset of your database values, use the update() method.
Updating the table combines the content values syntax of insert() with the where syntax of delete().
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// New value for one column
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
// Which row to update, based on the ID
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };
int count = db.update(
    FeedReaderDbHelper.FeedEntry.TABLE_NAME,
    values,
    selection,
    selectionArgs);

Tuesday, 18 August 2015

External Memory in Android

FilesActivity.Java

package com.example.files;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class FilesActivity extends Activity {

EditText fname,fcontent,fnameread;
    Button write,read;
    TextView filecon;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_files);
        fname = (EditText)findViewById(R.id.fname);
        fcontent = (EditText)findViewById(R.id.ftext);
        fnameread = (EditText)findViewById(R.id.fnameread);
        write = (Button)findViewById(R.id.btnwrite);
        read = (Button)findViewById(R.id.btnread);
        filecon = (TextView)findViewById(R.id.filecon);
        write.setOnClickListener(new View.OnClickListener() {
 
        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
        String filename = fname.getText().toString();
        String filecontent = fcontent.getText().toString();
        FileOperations fop = new FileOperations();
        fop.write(filename, filecontent);
        if(fop.write(filename, filecontent)){
        Toast.makeText(getApplicationContext(), filename+".txt created", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(getApplicationContext(), "I/O error", Toast.LENGTH_SHORT).show();
 
        }
        }
    });
    read.setOnClickListener(new View.OnClickListener() {
 
        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            String readfilename = fnameread.getText().toString();
            FileOperations fop = new FileOperations();
            String text = fop.read(readfilename);
            if(text != null){
            filecon.setText(text);
            }
            else {
                Toast.makeText(getApplicationContext(), "File not Found", Toast.LENGTH_SHORT).show();
                filecon.setText(null);
            }
 
        }
    });
    }
    }

FileOperations.Java

package com.example.files;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import android.util.Log;

public class FileOperations {
public FileOperations() {
 
    }

 public Boolean write(String fname, String fcontent){
        try {

            String fpath = "/sdcard/"+fname+".txt";

            File file = new File(fpath);

            // If file does not exists, then create it
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(fcontent);
            bw.close();

            Log.d("Suceess","Sucess");
            return true;

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

 }

 public String read(String fname){

     BufferedReader br = null;
     String response = null;

        try {

            StringBuffer output = new StringBuffer();
            String fpath = "/sdcard/"+fname+".txt";

            br = new BufferedReader(new FileReader(fpath));
            String line = "";
            while ((line = br.readLine()) != null) {
                output.append(line +"n");
            }
            response = output.toString();

        } catch (IOException e) {
            e.printStackTrace();
            return null;

        }
        return response;

 }
}

Activity_files.XML

<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:layout_gravity="center"
    tools:context=".MainActivity" >
 
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        android:text="Android Read/Write File" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/fname"
        android:hint="File Name" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="100px"
        android:id="@+id/ftext"
        android:hint="File Text" />
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnwrite"
        android:text="Write File" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/fnameread"
        android:hint="File Name" />
       <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnread"
        android:text="Read File" />
       <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/filecon" />
 
</LinearLayout>

Manifestfile.XML

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".FilesActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
 

Output.XML


Internal Memory in Android

Mainactivity.Java

package com.example.internalmemory;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

EditText textmsg;
static final int READ_BLOCK_SIZE = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

textmsg=(EditText)findViewById(R.id.editText1);
}

// write text to file
public void WriteBtn(View v) {
// add-write text into file
try {
FileOutputStream fileout=openFileOutput("mytextfile.txt", MODE_PRIVATE);
OutputStreamWriter outputWriter=new OutputStreamWriter(fileout);
outputWriter.write(textmsg.getText().toString());
outputWriter.close();

//display file saved message
Toast.makeText(getBaseContext(), "File saved successfully!",
Toast.LENGTH_SHORT).show();

} catch (Exception e) {
e.printStackTrace();
}
}

// Read text from file
public void ReadBtn(View v) {
//reading text from file
try {
FileInputStream fileIn=openFileInput("mytextfile.txt");
InputStreamReader InputRead= new InputStreamReader(fileIn);

char[] inputBuffer= new char[READ_BLOCK_SIZE];
String s="";
int charRead;

while ((charRead=InputRead.read(inputBuffer))>0) {
// char to string conversion
String readstring=String.copyValueOf(inputBuffer,0,charRead);
s +=readstring;
}
InputRead.close();
Toast.makeText(getBaseContext(), s,Toast.LENGTH_SHORT).show();

} catch (Exception e) {
e.printStackTrace();
}
}
}

Activity_Main.XML

<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"
    tools:context="{relativePackage}.${activityClass}" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:background="#008080"
        android:padding="5dp"
        android:text="Android Read and Write Text form File"
        android:textColor="#fff" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="22dp"
        android:ems="10"
        android:layout_margin="5dp">
        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/editText1"
        android:text="Write Text into File"
        android:onClick="WriteBtn"
        android:layout_margin="5dp"/>
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/button1"
        android:text="Read Text From file"
        android:onClick="ReadBtn"
        android:layout_margin="5dp" />
</RelativeLayout>

Output:




Saving Files in Android

Android uses a file system that's similar to disk-based file systems on other platforms. This lesson describes how to work with the Android file system to read and write files with the File APIs.

A File object is suited to reading or writing large amounts of data in start-to-finish order without skipping around. For example, it's good for image files or anything exchanged over a network.

This lesson shows how to perform basic file-related tasks in your app. The lesson assumes that you are familiar with the basics of the Linux file system and the standard file input/output APIs in java.io.

Types of Saving Modes:
All Android devices have two file storage areas: "internal" and "external" storage. These names come from the early days of Android, when most devices offered built-in non-volatile memory (internal storage), plus a removable storage medium such as a micro SD card (external storage). Some devices divide the permanent storage space into "internal" and "external" partitions, so even without a removable storage medium, there are always two storage spaces and the API behavior is the same whether the external storage is removable or not. The following lists summarize the facts about each storage space.

Internal storage:
It's always available.
Files saved here are accessible by only your app by default.
When the user uninstalls your app, the system removes all your app's files from internal storage.
Internal storage is best when you want to be sure that neither the user nor other apps can access your files.
External storage:
It's not always available, because the user can mount the external storage as USB storage and in some cases remove it from the device.
It's world-readable, so files saved here may be read outside of your control.
When the user uninstalls your app, the system removes your app's files from here only if you save them in the directory from getExternalFilesDir().
External storage is the best place for files that don't require access restrictions and for files that you want to share with other apps or allow the user to access with a computer.
Obtain Permissions for External Storage
To write to the external storage, you must request the WRITE_EXTERNAL_STORAGE permission in your manifest file:
<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>
Caution: Currently, all apps have the ability to read the external storage without a special permission. However, this will change in a future release. If your app needs to read the external storage (but not write to it), then you will need to declare the READ_EXTERNAL_STORAGE permission. To ensure that your app continues to work as expected, you should declare this permission now, before the change takes effect.
<manifest ...>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    ...
</manifest>
However, if your app uses the WRITE_EXTERNAL_STORAGE permission, then it implicitly has permission to read the external storage as well.
You don’t need any permissions to save files on the internal storage. Your application always has permission to read and write files in its internal storage directory.
Save a File on Internal Storage
When saving a file to internal storage, you can acquire the appropriate directory as a File by calling one of two methods:
getFilesDir()
Returns a File representing an internal directory for your app.
getCacheDir()
Returns a File representing an internal directory for your app's temporary cache files. Be sure to delete each file once it is no longer needed and implement a reasonable size limit for the amount of memory you use at any given time, such as 1MB. If the system begins running low on storage, it may delete your cache files without warning.
To create a new file in one of these directories, you can use the File() constructor, passing the File provided by one of the above methods that specifies your internal storage directory. For example:
File file = new File(context.getFilesDir(), filename);
Alternatively, you can call openFileOutput() to get a FileOutputStream that writes to a file in your internal directory. For example, here's how to write some text to a file:
String filename = "myfile";
String string = "Welcome";
FileOutputStream outputStream;
try {
  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
  outputStream.write(string.getBytes());
  outputStream.close();
} catch (Exception e) {
  e.printStackTrace();
}
Or, if you need to cache some files, you should instead use createTempFile(). For example, the following method extracts the file name from a URL and creates a file with that name in your app's internal cache directory:
public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
        file = File.createTempFile(fileName, null, context.getCacheDir());
    catch (IOException e) {
        // Error while creating file
    }
    return file;
}
Note: Your app's internal storage directory is specified by your app's package name in a special location of the Android file system. Technically, another app can read your internal files if you set the file mode to be readable. However, the other app would also need to know your app package name and file names. Other apps cannot browse your internal directories and do not have read or write access unless you explicitly set the files to be readable or writable. So as long as you use MODE_PRIVATE for your files on the internal storage, they are never accessible to other apps.
Save a File on External Storage
Because the external storage may be unavailable—such as when the user has mounted the storage to a PC or has removed the SD card that provides the external storage—you should always verify that the volume is available before accessing it. You can query the external storage state by calling getExternalStorageState(). If the returned state is equal to MEDIA_MOUNTED, then you can read and write your files. For example, the following methods are useful to determine the storage availability:
/* 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;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}
Although the external storage is modifiable by the user and other apps, there are two categories of files you might save here:
Public files
Files that should be freely available to other apps and to the user. When the user uninstalls your app, these files should remain available to the user.
For example, photos captured by your app or other downloaded files.
Private files
Files that rightfully belong to your app and should be deleted when the user uninstalls your app. Although these files are technically accessible by the user and other apps because they are on the external storage, they are files that realistically don't provide value to the user outside your app. When the user uninstalls your app, the system deletes all files in your app's external private directory.
For example, additional resources downloaded by your app or temporary media files.
If you want to save public files on the external storage, use the getExternalStoragePublicDirectory() method to get a File representing the appropriate directory on the external storage. The method takes an argument specifying the type of file you want to save so that they can be logically organized with other public files, such as DIRECTORY_MUSIC or DIRECTORY_PICTURES. For example:
public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}
If you want to save files that are private to your app, you can acquire the appropriate directory by calling getExternalFilesDir() and passing it a name indicating the type of directory you'd like. Each directory created this way is added to a parent directory that encapsulates all your app's external storage files, which the system deletes when the user uninstalls your app.
For example, here's a method you can use to create a directory for an individual photo album:
public File getAlbumStorageDir(Context context, String albumName) {
    // Get the directory for the app's private pictures directory.
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}
If none of the pre-defined sub-directory names suit your files, you can instead call getExternalFilesDir() and pass null. This returns the root directory for your app's private directory on the external storage.
Remember that getExternalFilesDir() creates a directory inside a directory that is deleted when the user uninstalls your app. If the files you're saving should remain available after the user uninstalls your app—such as when your app is a camera and the user will want to keep the photos—you should instead use getExternalStoragePublicDirectory().
Regardless of whether you use getExternalStoragePublicDirectory() for files that are shared or getExternalFilesDir() for files that are private to your app, it's important that you use directory names provided by API constants like DIRECTORY_PICTURES. These directory names ensure that the files are treated properly by the system. For instance, files saved in DIRECTORY_RINGTONES are categorized by the system media scanner as ringtones instead of music.
Query Free Space
If you know ahead of time how much data you're saving, you can find out whether sufficient space is available without causing an IOException by calling getFreeSpace() or getTotalSpace(). These methods provide the current available space and the total space in the storage volume, respectively. This information is also useful to avoid filling the storage volume above a certain threshold.
However, the system does not guarantee that you can write as many bytes as are indicated by getFreeSpace(). If the number returned is a few MB more than the size of the data you want to save, or if the file system is less than 90% full, then it's probably safe to proceed. Otherwise, you probably shouldn't write to storage.
Note: You aren't required to check the amount of available space before you save your file. You can instead try writing the file right away, then catch an IOException if one occurs. You may need to do this if you don't know exactly how much space you need. For example, if you change the file's encoding before you save it by converting a PNG image to JPEG, you won't know the file's size beforehand.
Delete a File
You should always delete files that you no longer need. The most straightforward way to delete a file is to have the opened file reference call delete() on itself.
myFile.delete();
If the file is saved on internal storage, you can also ask the Context to locate and delete a file by calling deleteFile():
myContext.deleteFile(fileName);
Note: When the user uninstalls your app, the Android system deletes the following:
All files you saved on internal storage
All files you saved on external storage using getExternalFilesDir().
However, you should manually delete all cached files created with getCacheDir() on a regular basis and also regularly delete other files you no longer need.

Ads Inside Post