Home

JavocSoft edited this page Nov 3, 2015 · 68 revisions

Index

ToolBox

Is the main class of the library. It contains a large set of useful methods when programming for Android. The utility methods are ordered by functionalities:

  • Storage
  • System
  • Animation
  • Media
  • Web
  • View
  • Share
  • Screen
  • Preferences
  • Powersaving
  • Notifications
  • Net
  • Intent
  • Media
  • Market
  • IO
  • Graphics
  • Font
  • Dialogs
  • Device
  • Crypto
  • Application
  • Application Information
  • Analytics
  • AdMob
  • Activity

To locate a method just use ToolBox.functionality_method().

Now the library is adapted to the last Android notification creation API so is possible to get notifications with a progress bar or with custom actions.

Notification with Progress Bar
Only for Android 4.0+ (API Level 14+). Determinate or indeterminate can be used. A runnable class does operations while informing to the notification about its progress. The class NotificationProgressBarRunnable must be extended to create a progress bar notification. Once runnable finishes, a text can be shown and notification can then be discarded. An example implementation:

public static class NotificationProgressBarDeterminateImpl extends ToolBox.NotificationProgressBarRunnable {
    @Override
    protected void doTask() {
        for (int i = 0; i <= 100; i+=5) {
            try {
                Thread.sleep(5*1000);
                //pBarProgress=i;
                //notify(pBarProgress);
            } catch (InterruptedException e) {
                Log.d(NotificationModule.TAG, "sleep failure");
            }                
        }           
        notifyFinish(null);
    }
}

Notification with Custom Actions
For Android 4.1+ (API Level 16+). If set, such actions will be presented in the notification. Remember that to close the notification after action is clicked, you should use the "notifyID" parameter and set it as an extra of your action to be able to close the notification from your application.

PackageManager manager = context.getPackageManager();<br>
Intent intent = manager.getLaunchIntentForPackage("<app_package>");<br>
intent.addCategory(Intent.CATEGORY_LAUNCHER);<br>
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);<br><br>

Action action = new Action(R.drawable.ic_lib, getString(R.string.app_name), pIntent);<br>
action.getExtras().putInt("NOTIFICATION_ID", "<not_id>");

Then, in the opened application:

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(getIntent().getIntExtra(NOTIFICATION_ID, -1));

to cancel the notification.

Facebook

FB - Login

Useful links

Create Facebook Application

Create your Application in the Facebook developer portal at https://developers.facebook.com/, configure it properly. Save the facebook application id.

Prepare your application

Edit AndroidManifest.xml

Add in the "application" XML tag the following:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/fb_app_id" />  
<activity android:name="com.facebook.LoginActivity" />  

And before the "application" XML tag the required permissions:

<uses-permission android:name="android.permission.INTERNET"/>  
Set your Facebook Application id

In your "strings.xml" file add a new string called "fb_app_id" containing the id of the application in Facebook Developer portal https://developers.facebook.com/.

Decide where to put the Facebook Login in your Activity

Paste the layout code bellow in your activity layout where you want it:

<fragment android:id="@+id/fbLoginFragment"
      android:name="es.javocsoft.android.lib.toolbox.facebook.FacebookLoginFragment"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"          
      tools:layout="@layout/fragment_fb_logn" />
Iniitialize the Facebook Login Button

To do so you must:

Prepare facebook Event listeners:

  • Create a login action listener by creating a class extending FacebookLoginFragment.OnLoginActionCallback, implementing the required methods.
  • Create a logout action listener by creating a class extending FacebookLoginFragment.OnLogoutActionCallback, implementing the required methods.

Now, add in your Activity's onCreate:

FragmentManager fragmentManager = getSupportFragmentManager();  
FacebookLoginFragment fbLoginFragment = (FacebookLoginFragment)fragmentManager.findFragmentById(R.id.fbLoginFragment);
fbLoginFragment.initialize("public_profile,email", login_action_listener, logout_action_listener);

Whenever you need to show the Facebook Login button follow this step.

FB - Share

Note:To share, a valid active Facebook logged session must exists, use the this library Facebook Login procedure to get a valid session. See Facebook Login.

The steps once we have a valid session are:

Decide where to put the Facebook Share in your Activity

Paste the layout code bellow in your activity layout where you want it:

<fragment android:id="@+id/fbShareFragment"
      android:name="es.javocsoft.android.lib.toolbox.facebook.FacebookShareFragment"
      android:layout_width="match_parent"
      android:layout_height="wrap_content" 
      tools:layout="@layout/fragment_fb_share" />

Iniitialize the Facebook Share Button

To do so you must:

Prepare Facebook Event listeners:

  • Create a login action listener by creating a class extending OnLoginActionCallback, implementing the required methods.
  • Create a logout action listener by creating a class extending OnLogoutActionCallback, implementing the required methods.
  • Create a sucess share action listener by creating a class extending OnShareSuccessActionCallback, implementing the required methods.
  • Create a fail share action listener by creating a class extending OnShareFailActionCallback, implementing the required methods.
  • Create a cancel share action listener by creating a class extending OnShareCancelledActionCallback, implementing the required methods.

Now, add in your Activity's onCreate:

FragmentManager fragmentManager = getSupportFragmentManager();  
FacebookShareFragment fbShareFragment = (FacebookShareFragment)fragmentManager.findFragmentById(R.id.fbShareFragment);  
fbShareFragment.initialize("app_Name", "some_caption", "some_description", "some_link", "some_picture_url", login_action_listener, logout_action_listener, share_sucess_listener, share_fail_listener, share_cancel_listener);

Ads Module

Generate your banners and interstitial

Generate your Ads configuration in the AdMob portal at https://apps.admob.com/ (to do so you need to have an AdSense, http://www.adsense.com, account and also an AdWords, https://adwords.google.com, accounts properly configured)

Save the banner and interstitial ids.

Prepare your application

Edit AndroidManifest.xml

Add in the "application" XML tag the following:

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
<meta-data android:value="true" android:name="ADMOB_ALLOW_LOCATION_FOR_ADS" />
<activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"  android:theme="@android:style/Theme.Translucent" />

And before "application" XML tag the required permissions:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Create a Fragment extending AdFragment and set your AdMob Banner Id

Create a class called for example "your.package.MyAdsFragment" extending es.javocsoft.android.lib.toolbox.ads.AdFragment and modify the onCreateView() method:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
              Bundle savedInstanceState) {

          //Set your AdMob banner id.
          super.setAdUnitId("ca-app-pub-XXXX/XXXXX" );

          return super .onCreateView(inflater, container, savedInstanceState );
}

Decide where to put the Banner in your Activity

Paste the layout code bellow, for example, in a Relative Layout, in the bottom:

<fragment android:id="@+id/adFragment"
      android:name="your.package.MyAdsFragment"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      tools:layout="@layout/fragment_ad" />

Be sure to set correctly the rest of elements of the layout. One has to have:

android:layout_above="@+id/adFragment"

Show the banner

First, put in your onCreate() method:

FragmentManager fragmentManager = getSupportFragmentManager();
ads = (AdFragment) fragmentManager.findFragmentById(R.id.adFragment);

And finally, in your onResume() method:

ads.showAds();

Hide the banner

Simply, use::

ads.hideAds();

Show an Interstitial

It is quite easy, just put this line when you want it:

AdInterstitial.getInstance().requestInterstitial("<your_admob_interstitial_id>", this, null);

It is possible also to set an interstitial click listener to be able to do something when user clicks on an interstitial ad. To achieve this just create a class that implements InterstitialAdsListener.OnInterstitialClickCallback. Implement the required methods and pass an instance of it to the interstitial call:

InterstitialClickCallback interstitialClickcallback = new InterstitialClickCallback();
AdInterstitial.getInstance().requestInterstitial("<your_admob_interstitial_id>", this, interstitialClickcallback);

Notes

You can use the "ca-app-pub-3940256099942544/6300978111" ads unit id just for testing.

Useful Links

Google Ads - Quick-Start

Google Cloud Messaging (GCM) Module

You must follow the following steps:

  1. Configure your application in Google Cloud Console
    1. Create a project for your application .
    2. Activate the Google cloud Messaging.
    3. Generate Keys to send notifications from your server.
  2. Prepare your application.
    1. Prepare AndroidManifest.xml.
    2. Prepare your code.
    3. Use the included GCM Delivery Java classes to send notification under the package es.javocsoft.android.lib.toolbox.gcm.send.

Note: Under a WiFi connection, If your organization has a firewall that restricts the traffic to or from the Internet, you'll need to configure it to allow connectivity with GCM. The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs. It changes IPs frequently..

Configure your application in Google Cloud Console

Create your Project

  1. Go to http://console.developers.google.com and log in. Locate the "Create Project" button and press it to create a new one.
    GCM - Google Cloud API - Step1
  2. Set your project name in the window that appears and press "Create" button. Now Google will process the request, it can take some time.
    GCM - Google Cloud API - Step2 When Google Cloud Console finishes, it will show a verification mark in the bottom right corner.
    GCM - Google Cloud API - Step3
  3. Save the "Project Number" number somewhere. This number will be used in your Android application to tell it from which apps can receive notifications.
    GCM - Google Cloud API - Step4

Enable GCM in your project

Now, we need to enable the Google Cloud Messaging system in order to be able to send and receive notifications in our application. To do so:

Go to "APIs & auth" section and select "APIs" option. Locate the "Google Cloud Messaging for Android" API and activate it by pressing the ON/IOFF button.

GCM - Google Cloud API - Step5

Generate Keys to send notifications from your server

These keys will allow us to send notifications to our Apps by using the Google Cloud Messaging API. To get this key:

  1. Go to "APIs & auth" -> "Credentials" and press the button "Create new key".
    GCM - Google Cloud API - Step6
  2. Select "Server key" if we are going to send notification within a server application, that is our case.
    GCM - Google Cloud API - Step7
  3. Just put now the IP address or the subnet of the server that your are going to use to send the notifications to your application.
    GCM - Google Cloud API - Step8
  4. Once done, we shoukd see a new informative box like this:
    GCM - Google Cloud API - Step9
    Save the API KEY somewhere. This is your key for sending notifications.

Prepare your application

Depending of the used IDE you have two options:

  • Android Studio. **You need to add these lines to the file "build.gradle" in your "app" module. compile 'com.google.android.gms:play-services:5.2.08' compile files('libs/javocsoft_toolbox.jar') ...the "javocsoft-toolbox.jar" must be copied into the libs folder.
  • Eclipse. ** Add "javocsoft-toolbox.jar" to the libs folder.
Prepare AndroidManifest.xml

Add before "application" XML tag the required permissions:

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

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<permission android:name="<your_application_package>.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="<your_application_package>.permission.C2D_MESSAGE" />

And in "application" XML tag the following:

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<receiver android:name="es.javocsoft.android.lib.toolbox.gcm.core.CustomGCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
   <intent-filter>
      <action android:name="com.google.android.c2dm.intent.RECEIVE" />
      <category android:name="<your_application_package>" />
   </intent-filter>
</receiver>
<service android:name="es.javocsoft.android.lib.toolbox.gcm.core.GCMIntentService" />

Where "your_application_package" is the package of your Android application.

Prepare your code

Declare these variables in your Main class:

//GCM Module -------------------------------------------------------------------------------
private NotificationModule notificationModule;
private CustomNotificationReceiver notReceiver;
private final String gcmAppSenderId = "<gcm_project_id>";
//END GCM Notification Module --------------------------------------------------------------

Put in method onCreate() the following:

    //GCM Module -------------------------------------------------------------------------------
    final boolean multipleNotifications = false;
    final String groupNotificationsKey = "basetestapp";

    notificationModule = NotificationModule.getInstance(this, EnvironmentType.SANDBOX,
                                gcmAppSenderId,
                                new GCMRegCallback(),
                                new GCMNotOpenCallback(),
                                new GCMUnregCallback(),
                                new GCMNotReceivedCallback(),
                                multipleNotifications,
                                groupNotificationsKey);
    if(notReceiver==null) {
        notReceiver = new CustomNotificationReceiver();
        registerReceiver(notReceiver,
                new IntentFilter(NotificationModule.NEW_NOTIFICATION_ACTION));
    }
    //END GCM Notification Module --------------------------------------------------------------

In your onResume() method:

   //GCM Module -------------------------------------------------------------------------------
    try {
        notificationModule.gcmRegisterDevice(this,"Testing GCM", MainActivity.class);
    } catch (GCMException e) {
        Log.e(NotificationModule.TAG, "Error registering with GCM: " + e.getMessage() + ".", e);
    }
    notificationModule.gcmCheckForNotificationReceival(this, getIntent());
    //END GCM Notification Module --------------------------------------------------------------

Also in onNewIntent() method:

    //GCM Module -------------------------------------------------------------------------------
    notificationModule.gcmCheckForNotificationReceival(this, intent);
    //END GCM Notification Module --------------------------------------------------------------

And finally, in onDestroy() method:

    //GCM Module -------------------------------------------------------------------------------
    unregisterReceiver(notReceiver);
    //END GCM Notification Module --------------------------------------------------------------

Now, to handle GCM events:

  • On new Notification Received -> Event class: GCMIntentService.OnNewNotificationCallback
  • On Notification Opened -> Event class: CustomNotificationReceiver.OnAckCallback
  • On Registration with GCM -> Event class: GCMIntentService.OnRegistrationCallback
  • On Unregistration from GCM -> Event class: GCMIntentService.OnUnregistrationCallback

Create your event classes by extending the specified event classes. The implemented event classes are set when the Notification module is initialized.

Notes

The notification content must be sent through GCM under a key called "message".

Useful Links

GCM - Client
GCM - Advanced
GCM - Server
GCM - Server - Error Codes

Google Analytics Campaigns & Tracking

Note: This only work if the application is installed through the Google Play application.

Prepare your application

Edit AndroidManifest.xml

Add before "application" XML tag the required permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

And in "application" XML tag the following:

 <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
 <meta-data android:name="com.google.android.gms.analytics.globalConfigResource" android:resource="@xml/global_tracker"/>

 <service android:name="com.google.android.gms.analytics.CampaignTrackingService" />
    <receiver android:name="es.javocsoft.android.lib.toolbox.analytics.CustomCampaignTrackingReceiver" android:exported="true">
        <intent-filter>
            <action android:name="com.android.vending.INSTALL_REFERRER" />
    </intent-filter>
 </receiver>

Analytics Configuration files

First, create the Analytics global configuration file "global_tracker.xml" in a folder called "xml" (create it if does not exists) under your "res" folder. Paste the text bellow:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 
    This is the global analytics configuration. Required.
    (it is set in the AndroidManifest.xml)

    See:
        https://developers.google.com/analytics/devguides/collection/android/v4/
        https://developer.android.com/reference/com/google/android/gms/analytics/GoogleAnalytics.html
    -->

    <integer name="ga_sessionTimeout">300</integer>
    <!-- Enable automatic Activity measurement -->
    <bool name="ga_autoActivityTracking">true</bool>
    <bool name="ga_reportUncaughtExceptions">true</bool>

    <!-- Frequency of automatic dispatch (in seconds). Default is 1800 -->
    <integer name="ga_dispatchPeriod">60</integer>
    <string name="ga_logLevel">verbose</string>
    <!-- Toggles dry run mode. In dry run mode, the normal code paths are executed 
    locally, but hits are not sent to Google Analytics servers. This is useful 
    for debugging calls to the Google Analytics SDK without polluting recorded data.
    -->
    <bool name="ga_dryRun">false</bool>

</resources>

Second, create the application Analytics configuration file "app_tracker.xml" in the same folder called "xml" (create it if does not exists) under your "res" folder. Paste the text bellow, replacing "ga_trackingId" value with your analytics tracking code:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--  The following value should be replaced with correct property id. -->
    <string name="ga_trackingId">UA-XXXXXXXX-X</string>

    <integer name="ga_sessionTimeout">300</integer>
    <!-- Enable automatic Activity measurement -->
    <bool name="ga_autoActivityTracking">true</bool>        

    <!-- The screen names that will appear in reports -->
    <screenName name="es.javocsoft.basetestapp.MainActivity">MainActivity</screenName>
</resources>

Generate your application campaign

You can generate a campaign URL by using the Google provide tool Google Campaign URL Tool

Testing

You can test easily if all the system is well mounted by executing from the shell or prompt:

 adb shell am broadcast
              -a com.android.vending.INSTALL_REFERRER
              -n es.javocsoft.basetestapp
                     /es.javocsoft.android.lib.toolbox.analytics.CustomCampaignTrackingReceiver
              --es "referrer" "utm_source%3Dfacebook%26utm_medium%3Dbanner%26utm_content%3Dbanner1%26utm_campaign%3DcampaignOne"

..if the test goes well an output like this should be seen:

Broadcasting: Intent { act=com.android.vending.INSTALL_REFERRER cmp=es.javocsoft.basetestapp/.CustomCampaignTrackingReceiver (has extras) }
Broadcast completed: result=0

Execute something when Campign data is received

You can also do something with the received campaign info. To do so, just create a class that extends CustomCampaignTrackingReceiver.OnProcessCampaignDataCallback and implement the class methods. Set an instance of your class in "onCreate()" method of your application main activity:

//Your analytics campaign custom class callback
AnalyticsCampaignCallback analyticsCampaignCallback = new AnalyticsCampaignCallback();
//Set your callback to the campaign analytics tracker.
CustomCampaignTrackingReceiver.onCampaignInfoReceivedCallback = analyticsCampaignCallback;

Tracking of application events in Analytics

If you declined to use the auto-tracking by setting "ga_autoActivityTracking" to FALSE, in the activity that you want to track, put in onStart():

 GoogleAnalytics.getInstance(this).reportActivityStart(this);

And finally, in onStop():

 GoogleAnalytics.getInstance(this).reportActivityStop(this);

Useful Links

Usage

Android Campaigns
Android Analytics

iOS Campaigns
iOS Analytics

How To Test
Analytics Tracker Class
Analytics Protocol Parameters Reference
Issues

Google Drive

Now your applications can store data in the Cloud through Google Drive storage. This is quite useful to be able for example, to recover the user configuration or some files if the application is unninstalled and installed again. Library also allows to store this data in the "application folder" in the cloud, a place that can not be tampered.

Set-Up the Drive module

1. Authorize your application to use Google Drive API

See Google Drive API AUTH to know how to achieve this step.

2. Get an instance of TBDrive Library Google Drive object

TBDrive is a singleton so save this call somewehere and call it whenever you need to do something with Google Drive. A goo place to get the instance of TBDrive could be in the onCreate() method of your activity.

TBDrive.getInstance(this, 
    new TBDriveConnectionFailureListener(getApplicationContext()), 
    new TBDriveConnectionListener(getApplicationContext()),
    new TBDriveConnectionSuspendedListener(getApplicationContext()));

The callbacks TBDriveConnectionFailureListener, TBDriveConnectionListener and TBDriveConnectionSuspendedListener extend TBDriveConnectionCallback. This allows to trigger something when connection is done, fails or is suspended. You can leave them null if not required but at least a TBDriveConnectionListener should be used to check if connection is successfully done or not.

3. Configure onPause()

Add to your activity onPause() a call to TBDrive.drive_onPause().

4. Configure your Activity's onActivityResult()

Add in your Activity's onActivityResult the call to TBDrive.drive_checkForResolutionResult(). This allows to log-in in Google Drive if the user still has not granted the access to the application to its Google Drive.

5. Connect to Google Drive

Call TBDrive.drive_connect() to connect with Google Drive. A good place could be onStart() of your activity. To disconnect from Drive use TBDrive.drive_disconnect().

Usage

There is a set of methods to operate with Google Drive. These methods can be done in a synchronous way or asynchrnously.

  • Synchronous, the call to a method does not end until the operation with Google Drive is done.
  • Asynchronous, the operation needs a callback. This callback will be triggered when operation finishes to let you do your stuff. See the package es.javocsoft.android.lib.toolbox.drive.callback for a list of available callbacks to implement.

The module allows you to:

  • Create a file (with the posibility of creating it in the secure application folder).
  • Search for files.
  • Get a file given its name or title
  • Get the file contents.
  • Pin a file (this makes Google Drive to store a copy of its metadata locally in the Device).
  • Trash/Un-trash a file.
  • Be notified when a file changes (see TBDrive#addFileChangeListener() and TBChangeListener.java)
  • Subscribe to file changes (notifications are received even if the application is not running. See TBDrive#subscribeToFile() and TBDriveEventService.java).
  • Commit/Discard changes to a file (also be notified when Google Drive servers finish applying changes, see TBDriveEventService.java)
  • Get file contents as an String.
  • Append/Replace text to a file.
  • Get a DriveFile object from an encoded DriveId string.

Notes

When subscribing to changes in a file or when we want Google Drive to notify us whenever finishes applying changes in the remote data, we need to add:

<service android:name=".TBDriveEventListener" android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.drive.events.HANDLE_EVENT"/>
    </intent-filter>
</service>

...where TBDriveEventListener is a class that must extends TBDriveEventService.java.

Useful Links

For more information, see:

Google Drive API
Google Drive API Reference

SMS Observer

The device must have telephony capabilities in order to be able to sent/receive SMSs.

This class allows to be able of doing something when a new SMS is received or sent. To use it, simply initialize it by using this piece of code:

Handler smsHandler = new Handler();      
if(ToolBox.device_isHardwareFeatureAvailable(this, PackageManager.FEATURE_TELEPHONY)){
    smsObserver = new SMSObserver(smsHandler, getApplicationContext(), <b>msgReceivedCallback</b>, <b>msgSentCallback</b>);              
    ContentResolver mContentResolver = getContentResolver();
    mContentResolver.registerContentObserver(Uri.parse("content:// sms/"),true, smsObserver);
}

The object msgReceivedCallback and msgSentCallback are classes that must implement SMSObserver.SMSRunnableTask class. Whenever a SMS is received/sent, these two classes will allow you to do something. SMSRunnableTask provides you with the SMS data and context.

CMT Info Helper

By using this class you will be able to get the owner company info for the given short-number. The information is obtained from the official CMT web page at http://www.cmt.es.

Usage

Get an instance of the class:

CMTInfoHelper cmtInfoHelper = CMTInfoHelper.getInstance(this, cmtInfoReceivedCallback);
//you can also get an instance that will keep updated the downloaded info from the CMT:  
//CMTInfoHelper cmtInfoHelper = CMTInfoHelper.getInstance(this, cmtInfoReceivedCallback, true, 1440);  

Once instantiated, it will download the information from the official CMT page. To get the number information just use:

Map<String,String> cmtSNInfo = cmtInfoHelper.getShortNumbersInformation();  
String company = cmtSNInfo.get("795XXX");  

The class saves in shared preferences the list, just in case no internet is not available when applications starts.

Media Scanner Notifier

This class allows notifying to Android about a new image so it can appear in the Gallery. To use simply:

 String res = "path to the resource";
 String filePath = getFileStreamPath(res).getAbsolutePath();
 new MediaScannerNotifier(context,filePath,"image/*", false);

Unzipper

Use this class to unzip a file.

Usage

String zipFile = Environment.getExternalStorageDirectory() + "/files.zip";
String unzipLocation = Environment.getExternalStorageDirectory() + "/unzipped/";  

//Unzip      
Unzipper d = new Unzipper(zipFile, unzipLocation, true);
d.unzip();

Android SQLite

Use this set of classes to work with SQLite in Android.

Usage

It is quite simple:

  1. Think about your schema and create classes extending base class DBTable.java for each table you have or need. Each class must have your table fields.
  2. Create a class extending DBSQLite class. This class will have your database creation DDL and database versions upgrade scripts.
  3. Create a class extending DBHelper.java. DBHelper class is a class that contains a set of common operations that you can use in your own extending class. Put in this class also any custom method for your needs.
  4. Initialize your database and open it.
  5. Do any usage of it and when you do not need it, close it.

Examples

A table class:

import es.javocsoft.android.lib.toolbox.db.DBTable;

public class Item extends DBTable {

public Integer id;
public String name;
public Integer inStore;
public Integer enabled;


public Item(String tableName) {
    super(tableName);       
}
}

Your database creation/upgrade class:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import es.javocsoft.android.lib.toolbox.db.DBSQLite;

public class DatabaseSQLite extends DBSQLite {  

public DatabaseSQLite(Context context, String dbName, int dbVersion) {
    super(context, dbName, dbVersion);      
}   

@Override
public void doOnCreate(SQLiteDatabase db) {
    //TABLES
    db.execSQL("CREATE TABLE store (id INTEGER PRIMARY KEY, name VARCHAR(255), inStore INTEGER, enabled TINYINT(1))");

    //INDEXES
    db.execSQL("CREATE INDEX store_id_idx ON store (id)");
}

@Override
public void doOnUpgrade(SQLiteDatabase db) {
    // TODO Auto-generated method stub

}
}

Your database operations helper:

import android.database.Cursor;
import es.javocsoft.android.lib.toolbox.db.DBHelper;
import es.javocsoft.android.lib.toolbox.db.DBTable;

public class DatabaseHelper extends DBHelper<DatabaseSQLite> {

public DatabaseHelper(DatabaseSQLite mDbHelper) {
    super(mDbHelper);       
}

public int insertItem(Item item) {      
    return insert(item, null);
}

public Item getItem(int id){
    Item item = null;

    Cursor c = get("store", DBTable.getColumnsAsArray(Item.class), "id=" + id, null, null, null, null, null);
    if(c.moveToFirst()) {
        item = new Item("store");
        item.id = c.getInt(c.getColumnIndex("id"));
        item.name = c.getString(c.getColumnIndex("name"));
        item.inStore = c.getInt(c.getColumnIndex("inStore"));
        item.enabled = c.getInt(c.getColumnIndex("enabled"));
    }
    c.close();

    return item;
}
}

Once you have all required classes ready, use them like follows:

//Initialize your Database
DatabaseSQLite myDB = new DatabaseSQLite(getApplicationContext(), "MYDB", 1);
//Create/upgrade the database
DatabaseHelper mDatabaseHelper = new DatabaseHelper(myDB);

//Open it
mDatabaseHelper.open();

//Create a new item and insert it       
Item item1 = new Item("<table>");
item1.id=1;
item1.name="item_name_1";
item1.inStore=1;
item1.enabled=1;        
int res = mDatabaseHelper.insertItem(item1);

//Get an item from the database
Item i = mDatabaseHelper.getItem(1);

//Delete an item
res = mDatabaseHelper.deleteById("store", "id", 1);

//Check for the deleted item
i = mDatabaseHelper.getItem(1); //should return not found

//Create a new item
Item item2 = new Item("store");
item2.id=2;
item2.name="item_name_2";
item2.inStore=3;
item2.enabled=1;        
res = mDatabaseHelper.insertItem(item2);        

//Get the new item
i = mDatabaseHelper.getItem(2);

//Delete with conditions
res = mDatabaseHelper.deleteWhere("store", new String[]{"id"}, new String[]{"2"});

//Delete all of a table
res = mDatabaseHelper.deleteAll("store");

//Delete using an IN SQL clause.
//res = mDatabaseHelper.deleteIn("store", "id", new Integer[]{1,2});

mDatabaseHelper.close();

As you can see, it is quite easy.

Messenger

To connect with an application messenger service and send message use the class Mezzenger.java. To use it:

Mezzenger messenger = new Mezzenger("Inner", getApplicationContext());
messenger.connect("application.package.service.ACTION");
messenger.sendMessage(MSG_EVT_HI, 0, 0, null);

Messenger Service

To have a messenger service in your app follow these steps:

First create the messenger service message handler by extending the class MessengerIncomingHandler.java and implement the method "doWork(Message msg)" of MessengerIncomingHandler.java:

public class MyMessengerIncomingHandler extends MessengerIncomingHandler {
    //Messenger WHAT possible values
    public static final int MSG_EVT_HI = 1000;

    public MyMessengerIncomingHandler(Context context) {
        super(context);
    }

    @Override
    protected void doWork(Message msg) {
        switch (msg.what) {
            case MSG_EVT_HI:
                Log.i(Constants.TAG, "Messenger received: Hi!!");
                break;
            default:
                super.handleMessage(msg);
        }
    }
}

Second, create your messenger service by extending MessengerService.java and implement the method "getMessageIncomingHandler()":

public class MyMessengerService extends MessengerService {
    @Override
    protected MessengerIncomingHandler getMessageIncomingHandler() {
        return new MyMessengerIncomingHandler(context);
    }
}

And third, add the messenger service to your application AndroidManifest.xml.

<!-- Application messenger -->
<service android:name="your.application.package.messenger.MyMessengerService" 
         android:enabled="true" android:exported="true" >
    <intent-filter>
        <action android:name="your.application.package.service.messenger.ACTION_BIND" />
    </intent-filter>
</service>

Android 6+ Permissions handle

Description

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. If the device is running Android 5.1 (API level 22) or lower, or the app's targetSdkVersion is 22 or lower, the system asks the user to grant the permissions at install time.

System permissions are divided into two categories, normal and dangerous (more info.):

  • Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically. See the list here.
  • Dangerous permissions can give the app access to the user's confidential data. If your app lists a normal permission in its manifest, the system grants the permission automatically. If you list a dangerous permission, the user has to explicitly give approval to your app. If an app requests a dangerous permission listed in its manifest, and the app already has another dangerous permission in the same permission group, the system immediately grants the permission without any interaction with the user.

See Google Developer Permissions to know more about it.

An application prepared for Android 6+ has to be able to deal with these use cases:

  • Start the App. Ask for permission (showing a message telling why do you need before ask for them)
    • Accept -> App runs normally with the service that requires the permissions
    • Not accept -> App runs normally without the service that requires the permissions
  • With previously granted permissions, start the App:
    • Start the App -> App runs normally with the service that requires the permissions
  • In a running App with granted permissions:
    • Deny the permissions -> When returning to the App, it Asks for permissions (showing a message telling why do you need before ask for them):
      • Accept -> App runs normally with the service that requires the permissions
      • Not accept -> App runs normally without the service that requires the permissions
  • User denies the permission and marks "Never ask again"
    • Start the App:
      • Show a message to the user about the required permissions (showing a message telling why do you need before ask for them)
        • Accept. Ask for permissions
          • Accept -> App runs normally with the service that requires the permissions
          • Not accept -> App runs normally without the service that requires the permissions
        • Cancel. App runs normally without the service that requires the permissions

Android < 6

Start the App:

  • Do not ask for permissions and runs normally

Usage

ToolBox provides methods to check for permissions allowing us to present to the user an informative dialog and also ask to allow them if they are not already granted. ToolBox uses the Android Support Library for backward Android compatibility.

The functions to handle permissions are:

  • permission_askFor
  • permission_checkAskPermissionsresult
  • permission_isGranted
  • permission_areGranted

ToolBox also provides a set of permissions packages according with Google permissions group. This makes easy for you to ask for permissions for a service that requires a set of permissions.

  • PERMISSION_CALENDAR
  • PERMISSION_CAMERA
  • PERMISSION_LOCATION
  • PERMISSION_MICROPHONE
  • PERMISSION_PHONE
  • PERMISSION_SENSORS
  • PERMISSION_SMS
  • PERMISSION_STORAGE

Here is an example of usage. In this case we are going to use the localization service. This service requires two permissions that are not automatically granted (not in Google NORMAL permissions group):

  • ACCESS_COARSE_LOCATION
  • ACCESS_FINE_LOCATION

ToolBox has these two permissions in the PERMISSION_LOCATION set. We will use this set to ask for permission to the user:

<!-- Before use it, we check if the permissions are already granted. -->
if(!ToolBox.permission_areGranted(TheActivity.this, ToolBox.PERMISSION_LOCATION.keySet())) {
    //Permissions not yet granted, we need to be ask.
    ToolBox.permission_askFor(TheActivity.this, ToolBox.PERMISSION_LOCATION,     
            ToolBox.PERMISSIONS_REQUEST_CODE_ASK_LOCATION, 
        getString(R.string.permissions_required_title), 
        getString(R.string.permissions_button_ok),
        getString(R.string.permissions_button_deny),
        getString(R.string.permissions_location_required_text),
            true,
            false,
        null);
}else{
     //Permissions are already granted, continue using the localization service...

}

To handle the permissions ask response, we must do the following:

<!-- This method handles the response -->
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    permissionsLocationGranted = checkAskPermissionsresult(requestCode, permissions, grantResults);
    Log.i(Constants.TAG, "Location permissions granted? " + permissionsLocationGranted);
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if(permissionsLocationGranted) {
        //Continue with the usage of the service that needs the permissions...

    }else{
        //Do something if required...
    }        
}

private boolean checkAskPermissionsresult(int requestCode, String[] permissions, int[] grantResults) {
    boolean res = false;   
    if(requestCode == ToolBox.PERMISSIONS_REQUEST_CODE_ASK_LOCATION) {
        //We could check the permissions in our system
        //res = ToolBox.permission_areGranted(SplashActivity.this, Arrays.asList(permissions));         
        //We check the returned result. Only returns TRUE if all permissions are granted.
        res = ToolBox.permission_checkAskPermissionsresult(permissions, grantResults);
    }
    return res;
}

Have in mind that every time you use a service o function that requires permissions, you should check the current permissions by using:

ToolBox.permission_areGranted(TheActivity.this, ToolBox.PERMISSION_LOCATION.keySet());

Location Service

Description

ToolBox provides a localization service (class) ready to use in a project by declaring it properly in your Androidmanifest.xml. Enabling it makes your application to be aware of any location change even if the application is not started.

This service informs to an application about these events:

  • LOCATION_SERVICE_STARTED. Intent filter name: es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_STARTED
  • LOCATION_SERVICE_SHUTDOWN. Intent filter name: es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_SHUTDOWN
  • LOCATION_CHANGED. Intent filter name: es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_CHANGED
  • LOCATION_GPS_ENABLED. Intent filter name: es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_ENABLED
  • LOCATION_GPS_DISABLED. Intent filter name: es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_DISABLED

Usage

Just declare the localization service in your AndroidManifest.xml:

<service android:name="es.javocsoft.android.lib.toolbox.location.service.LocationService" 
         android:label="Location Service" android:enabled="true"/>

And launch it:

Intent mLocServiceIntent = new Intent(getBaseContext(), LocationService.class);
Bundle extras = new Bundle();
extras.putInt(LocationService.LOCATION_SERVICE_PARAM_MIN_DISTANCE, 2);
extras.putInt(LocationService.LOCATION_SERVICE_PARAM_MIN_TIME, 4000);
mLocServiceIntent.putExtras(extras);
startService(mLocServiceIntent);

And to stop it, when required:

Intent mLocServiceIntent = new Intent(getBaseContext(), LocationService.class);
stopService(mLocServiceIntent);

And implement in your application a receiver that listens for the desired events in order to react to them properly. For example:

public class LocationChangedReceiver extends WakefulBroadcastReceiver { 
    protected static String TAG = "LocationChangedReceiver"; 

    public LocationChangedReceiver() {}

    @Override
    public void onReceive(Context context, Intent intent) { 
        Bundle bundle = intent.getExtras(); 
        if(intent.getAction().equals(LocationService.ACTION_LOCATION_CHANGED)) { 
            //The ToolBox Location service leaves the location in the extras using
            //the key LocationService.LOCATION_KEY.
            Location location = bundle.getParcelable(LocationService.LOCATION_KEY);
            //Do something
        }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_GPS_ENABLED)){
            //Do something
        }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_GPS_DISABLED)){
            //Do something
        }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_SERVICE_STARTED))
            //Do something 
        }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_SERVICE_SHUTDOWN)){
            //Do something
        }
    }
}

Declaring it in your AndroidManifest.xml:

<receiver android:name="your_application_package.LocationReceiver" android:enabled="true" android:exported="false"/>
  <intent-filter>
      <action  android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_STARTED"/>
   <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_SHUTDOWN"/>
   <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_CHANGED"/>
   <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_DISABLED"/>
   <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_ENABLED"/>
  </intent-filter>
<receiver/>

Notes

  • The localization service can be customized when starting by setting:
    • Time between localization changes. Default is 4 seconds (4000 milliseconds).
    • Distance between localization changes. Default is 2 meters.
    To set these values, set them through the service starting intent by using these keys in the bundle:
    • LOCATION_SERVICE_PARAM_MIN_DISTANCE
    • LOCATION_SERVICE_PARAM_MIN_TIME
  • If service gets stopped, it will automatically run again.