Android orientation locking for Titanium

Locking the orientation of a Titanium Android app if fairly straightforward after you’ve done it once or twice.  I thought it would be helpful to outline the steps that I follow to lock several of my applications in a portrait orientation.

To start with you first must build your Titanium Android app.  It doesn’t matter if you have any functionality in your project yet.  You just need to make sure an AndroidManifest.xml file is created in your project’s build/android folder.  Once you have done a build, you will need to open your AndroidManifest.xml and look for the android:name property of your launch activity.  You can see an example of this in the below snippet found in our AndroidTest AndroidManifest.xml. Look for the .AndroidtestActivity line.  This is the line and pattern you will want to look for in your project’s AndroidManifest.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
	<application android:icon="@drawable/appicon" 
           android:label="AndroidTest" 
           android:name="AndroidtestApplication" 
           android:debuggable="false" 
           android:theme="@style/Theme.AppCompat">
		<activity 
                 android:name=".AndroidtestActivity" 
                 android:label="@string/app_name" 
                 android:theme="@style/Theme.Titanium"       
                 android:configChanges="keyboardHidden|orientation|screenSize">
		   <intent-filter>
		     <action android:name="android.intent.action.MAIN"/>
		     <category android:name="android.intent.category.LAUNCHER"/>
		    </intent-filter>
		</activity>
	</application>
</manifest>

You can see the naming convention is a period then your project name with the first letter capitalized followed by Activity.  In our example project this is .AndroidtestActivity. This is the pattern you will want to look for in your AndroidManifest.xml.

Once you have the activity name of your launch activity you will want to replace the default Android configuration with a new template.

First open your project’s tiapp.xml and locate the below default Android entry.

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

Replace the default information with the below template.

    <android xmlns:android="http://schemas.android.com/apk/res/android">
        <manifest>
            <application>
                <activity
                    android:configChanges="keyboardHidden|orientation|screenSize"
                    android:screenOrientation="portrait"
                    android:name="[replace me]">
                    <intent-filter>
                        <action android:name="android.intent.action.MAIN"/>
                        <category android:name="android.intent.category.LAUNCHER"/>
                    </intent-filter>
                </activity>
                <activity
                    android:configChanges="keyboardHidden|orientation|screenSize"
                    android:name="org.appcelerator.titanium.TiActivity" 
                    android:screenOrientation="portrait"/>
                <activity
                    android:configChanges="keyboardHidden|orientation|screenSize"
                    android:name="org.appcelerator.titanium.TiTranslucentActivity"
                    android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Translucent"/>
            </application>
        </manifest>
    </android>

Next replace the [replace me] placeholder with the name of the launch activity you found earlier.  The below example shows this replacement being done for our AndroidTest app.  Please remember to remove the brackets when making the replacement.

    <android xmlns:android="http://schemas.android.com/apk/res/android">
        <manifest>
            <application>
                <activity
                    android:configChanges="keyboardHidden|orientation|screenSize"
                    android:screenOrientation="portrait"
                    android:name=".AndroidtestActivity">
                    <intent-filter>
                        <action android:name="android.intent.action.MAIN"/>
                        <category android:name="android.intent.category.LAUNCHER"/>
                    </intent-filter>
                </activity>
                <activity
                    android:configChanges="keyboardHidden|orientation|screenSize"
                    android:name="org.appcelerator.titanium.TiActivity" 
                    android:screenOrientation="portrait"/>
                <activity
                    android:configChanges="keyboardHidden|orientation|screenSize"
                    android:name="org.appcelerator.titanium.TiTranslucentActivity"
                    android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Translucent"/>
            </application>
        </manifest>
    </android>

Next you will need to tell Alloy to only create Windows with a portrait orientation.  This is super easy and can be done by adding one class to your app.tss as shown below.  Your app.tss can be located in your app/styles folder.  If your project doesn’t already contain an app.tss you can create one by simply creating a file called app.tss in your project’s style folder.  To learn more about global styles please read the documentation available here.  The following snippet creates a global style for the windows in your project setting the orientation to portrait.

"Window" : {
	orientationModes :[
		Ti.UI.PORTRAIT
	]
}
FAQ:
  • Q: Why lock at the Android Activity level, isn’t adding the Alloy style enough?
  • A: Unfortunately no. The Alloy style is applied after the window is created. So if the device is held in a landscape orientation you will see the window open and turn. Locking at the Android Activity level stops this behavior.
  • Q: Does this mean all of my Ti.UI.Window object will be locked in portrait?
  • A: Yes, this locks both at the Android Activity and Titanium object levels.
  • Q: Can I later change the orientation by updating my Ti.UI.Window orientation?
  • A: No, orientation is locked at the Android Activity level as well.

Android Text to Speech and Speech to Text

The latest version of Ti.Utterance adds Android support for both Text to Speech and Speech to Text.  The Ti.Utterance native module surfaces the native platform APIs for Text to Speech, and on Android now Speech to Text.

Text to Speech

The Speech proxy provides your Titanium apps Text to Speech capabilities on both iOS and Android.  Ti.Utterance uses AVSpeechUtterance on iOS and android.speech.tts.TextToSpeech on Android.  This enables you to provide the Ti.Utterance module with a string, such as “hello world” for the module to speak.

To learn more about Text to Speech please read the documentation:

Sample

Full example available here.


var utterance = require('bencoding.utterance'),
	textToSpeech = utterance.createSpeech();

textToSpeech.startSpeaking({
	text:"Hello World"
});	

Speech to Text

The SpeechToText proxy is available on Android and provides Speech to Text capabilities using your device’s native platform speech recognizer.  When the startSpeechToText method is called, a microphone dialog will appear and listen for input from the user.  When the user stops speaking, Android’s speech recognizer will convert what was said into one or more text phrases.  If Android is not fully able to match was is said, the speech recognizer will provide a list of options in the order it feels is the best match.

To learn more about Speech to Text  please read the documentation:

Sample

Full example available here.


var utterance = require('bencoding.utterance'),
	speechToText = utterance.createSpeechToText();

speechToText.startSpeechToText({
	promptText:"Say something interesting",
	maxResults: 10
});

speechToText.addEventListener('completed',function(e){

	if(e.success && (e.wordCount > 0)){
		alert("Speech Recognized "
				+ e.wordCount
				+ " matches found: "
				+ JSON.stringify(e.words));
	}else{
		alert("Unable to recognize your speech");
	}

});

The Demo

Using an Android Blur View

One of the most popular effects in mobile today is the “blur”.  Although the blur effect is most commonly associated with iOS, several notable apps such as Etsy’s Android app use this technique.

The Ti.Blur module now provides Android support so that you can use this popular effect in both your Android and iOS Titanium apps.

The initial release of Ti.Blur for Android provides two APIs make applying a Box Blur easy.  The first APIs is an extended Ti.UI.View object called, BasicBlurView.  This view works similar to a Ti.UI.ImageView and applies the blur effect to the image or screenshot provide.  The second API is a called applyBlurTo and allows you to directly apply the Box Blur effect to an image.

The following shows them module’s example app in action.

android-blur

 

BasicBlurView on Android

The basicBlurView is a new view object within the Ti.Blur module.  This view object applies a Box Blur to any image provided to it’s image property. The blurRadius property is used to determine the level of blur that is applied.

This view would typically be used to blur an image, such as background image that you already have available in your app, or by taking a capture of the device’s current screen and providing it to the basicBlurView.

The basicBlurView is also cross-platform providing support for both Android and iOS.


var mod = require('bencoding.blur');

var win = Ti.UI.createWindow({
    backgroundColor:'white', title:"Image Blur Demo"
});
var vwTest = mod.createBasicBlurView({
    width:Ti.UI.FILL, height:Ti.UI.FILL, blurRadius:10,
    image: 'your-image-here.png'
});

win.add(vwTest);

win.open();

Blurring an image without a View object

The Ti.Blur module allows you to blur an image or blob directly without the use of a View object.  This is helpful if you want to cache the image for later, or use one of Titanium’s other built in UI objects.

The following code snippet is from the example app demonstrating how to apply a blur to an existing image packaged in your app.


var mod = require('bencoding.blur');

var win = Ti.UI.createWindow({
    backgroundColor:'white', title:"Image Blur Demo"
});

var imgblurredImage = mod.applyBlurTo({
    image:'42553_m.jpg',
    blurRadius:10
});

var vwTest = Ti.UI.createImageView({
    width:Ti.UI.FILL, height:Ti.UI.FILL,
    image:imgblurredImage
});

win.add(vwTest);

win.open();

Getting Started

Get started using Ti.Blur on either iOS or Android using the below links:

Source:

Modules:

Documentation:

Examples:

Ti.mely Native Timer Modules for Titanium

The Ti.mely project provides Titanium access to iOS and Android native timers.  The native nature of these timers can be advantageous for background or long interval poling.

Using Ti.mely

The usage is straightforward, you simply create a new timer object

var timer = timerMod.createTimer();

Attach a listener to listen for the onIntervalChange event as shown below

    function showUpdate(d){
        var msg = "interval changed - interval set to " + d.interval;
            msg += " interval count = " + d.intervalCount;
        Ti.API.info(msg);
    }

    timer.addEventListener('onIntervalChange',showUpdate);

Initialize the timer by calling the start method.  This method takes the interval in milliseconds and an optional debug flag which will print timer information to your console window.

    timer.start({
        interval:2000,
        debug:true
    });

To stop the timer, simply call the stop method as shown below.

timer.stop();

Native Consideration, ie Side Effects

Each time an interval elapses the onIntervalChange event will be fired.  The firing of this event will cause a trip over the Kroll JavaScript bridge.  For this reason using Ti.mely to implement high speed timers of 500 milliseconds or less could negatively impact app performance.

Get the module

The Ti.mely source code and compiled modules are available on Github(https://github.com/benbahrenburg/ti.mely) under the MIT license.

You can download the compiled modules using the following links

Example app.js

The below sample demonstrates how to use the Ti.mely module.  This app.js is include within the module’s example folder or available for iOS here and Android here.

var timer =  require('ti.mely').createTimer();

var win = Ti.UI.createWindow({
	backgroundColor:'#fff'
});

var how2Label = Ti.UI.createLabel({
	text:"Enter Duration in milliseconds",
	top:20, left:7, right:7, height:20,color:"#000"
});
win.add(how2Label);

var durationText = Ti.UI.createTextField({
	value:1000, top:50, left:7, right:7, height:40, color:"#000"
});
win.add(durationText);

var counterLabel = Ti.UI.createLabel({
	top:100, width:Ti.UI.FILL, height:40,left:7, right:7,color:"#000"
});
win.add(counterLabel);

function showUpdate(d){
	var msg = "interval changed - interval set to " + d.interval;
            msg += " interval count = " + d.intervalCount;
	Ti.API.info(msg);
	counterLabel.text = "Updated " + d.intervalCount  + " times.";
};

var startButton = Ti.UI.createButton({
	title:"Start", top:200, left:7, height:40, width:125
});
win.add(startButton);

startButton.addEventListener('click',function(e){
	counterLabel.text ="Starting Timer";
	timer.addEventListener('onIntervalChange',showUpdate);
	timer.start({
		interval:durationText.value,
		debug:true
	});
});

var stopButton = Ti.UI.createButton({
	title:"Stop", top:200,
	right:7, height:40, width:125
});
win.add(stopButton);

stopButton.addEventListener('click',function(e){
	timer.stop();
	timer.removeEventListener('onIntervalChange',showUpdate);
	counterLabel.text ="Press the Start button to test again";
});

win.open();

Securely: Titanium Security Module

The first release of Securely the Titanium security module is now available on Github.  The goal of this project is to provide the tools and components needed to build secure Titanium apps.  Securely provides a comprehensive set of methods designed to easily handle your most common security requirements.

Features include

  • Secure Properties
  • Key Generators
  • String Encryption
  • File Encryption
  • PDF Protection

Get the module

The source and compiled module are both available on Github under the Apache 2 license.

Learn more

Learn more about this module by visiting the following links on Github:

  •  Documentation : Complete method level documentation with examples
  •  Samples : Example app.js files demonstrating how to use each proxy type

Ti.SQ Squared Calendar Module

The Square TimeSquare project provides a rich and unique full featured Calendar Picker.  The cross-platform nature of this project makes it a perfect candidate for Titanium.

I’m happy to announce, the Ti.SQ modules for iOS and Android which allows you to use this excellent component in your Titanium projects.

The following provides all the details needed to get starting using this module in your projects today.

See it in action

iOS


Android


Get the module

All of the modules code, assets, documentation, and examples are available on github.

Before you start – Please make sure you read the project readme file before starting.  The readme file outlines all API differences and project dependences.

Documentation – Project documentation can be found here.

Examples – The iOS and Android APIs are almost.  A majority of the examples should work cross-platform with only minor updates.  Please make sure you read the documentation regarding the differences between iOS and Android.  The examples can be found for iOS here and Android here.

What to contribute– Pull Requests and other contributions are welcome.  Examples, and documentation are also encouraged.

Show me the Example

The following snippet outlines a basic usage scenario for the Ti.SQ module.

var sq = require('ti.sq');
Ti.API.info("module is => " + sq);

var win = Ti.UI.createWindow({
	backgroundColor:'#fff'
});

var calendarView = sq.createView({
	height:Ti.UI.FILL,
	top:0, bottom:'40dp',
	pagingEnabled:true,
	value:{
		month:6,day:10,year:2013
	},	
	min:{
		month:2,day:15,year:2013
	},
	max:{
		month:10,day:15,year:2013
	}
});
win.add(calendarView);

calendarView.addEventListener('dateChanged',function(d){
truei.API.info(JSON.stringify(d));
	Ti.API.info(JSON.stringify(d.dateValue));
	Ti.API.info(JSON.stringify(d.value));
	Ti.API.info(JSON.stringify(calendarView.value));	
})	

var button = Ti.UI.createButton({
	title:'Click to get selected value',
	height:'40dp', width:Ti.UI.FILL, bottom:0
});	
win.add(button);

button.addEventListener('click',function(d){
	Ti.API.info(JSON.stringify(calendarView.value));
	alert(String.formatDate(calendarView.value,"long"));
})	

win.open();

Using BOOT_COMPLETED in Titanium

It is a common requirement to need to restart your app if the user restarts the device.  Although this requirement is common, it can get tricky quickly.  For example do you want to restart in the foreground or background?  What if you want to send a notification instead?

The Android.Tools project has been updated to handle a majority of these scenarios using the new BootReceiver.  This component allows you to do the following:

  • On BOOT_COMPLETED restart your app in either the foreground or background
  • On BOOT_COMPLETED create a notification with information defined in your project’s tiapp.xml
  • You can also use Titanium Properties to configure the above options from within your Titanium app. 

How does it work?

The BootReceiver is configured to work similar to how a native app would when it receives the BOOT_COMPLETED broadcast.  Since Titanium might not yet be loaded, the module will help bootstrap your app based on the configuration elements in your tiapp.xml.

Warning: This functionality requires you update your tiapp.xml file with a few specific elements. I’ve included samples for each scenario, but please plan on spending alittle time exploring in order to get the configurations for your app working properly.

Finding the tiapp.xml entries

The below steps cover how to create the tiapp.xml entries needed for this module to work.

  1. Before installing the module, you will want to build your project for the simulator.  It doesn’t matter if the app is empty or event runs. The goal is to simply have Titanium generate a AndroidManifest.xml file.  You can find this file in your Project/build/android folder as illustrated below in red.

    AndroidManifest.xml Path

  2. To avoid the 2373 restart bug, you will need to add the following properties into your tiapp.xml file.

    
        <property name="ti.android.bug2373.finishfalseroot" type="bool">true</property>
        <property name="ti.android.bug2373.disableDetection" type="bool">true</property>
        <property name="ti.android.bug2373.restartDelay" type="int">500</property>
        <property name="ti.android.bug2373.finishDelay" type="int">0</property>
        <property name="ti.android.bug2373.skipAlert" type="bool">true</property>
        <property name="ti.android.bug2373.message">Initializing</property>
        <property name="ti.android.bug2373.title">Restart Required</property>
        <property name="ti.android.bug2373.buttonText">Continue</property>
    
    

  3. Using the information from step #1’s AndroidManifest.xml add an android configuration node to your tiapp.xml. 

    tiapp.xml example

    (a) Add the two permission lines highlighted in Blue.

    (b) Add the application node from your AndroidManifest.xml collected in step #1. If you are copying and pasting the example, make sure you change the names to match your project information.

Scenario 1: Restart

The first scenario supported by the module is to restart your Titanium app upon receipt of the BOOT_COMPLETED broadcast.

The following diagram demonstrates how to create a receiver entry in your tiapp.xml to use the BootReceiver module.  The section shown in red illstrates the receiver and intent-filter entries needed to be made in order for your app to subscribe to the BOOT_COMPLETED broadcast.

Scenario 1 Diagram

  • bootType : This meta-data element is required and tells the module which action to take. By using the restart option, the module will restart your application upon receipt of the BOOT_COMPLETED broadcast.
  • sendToBack : This meta-data element is required if using the bootType of restart. If true, your app will be restarted in the background upon receipt of the BOOT_COMPLETED broadcast. If false, your app will be restarted in the foreground and the user will be presented with the first window of your app.

Please see the sample tiapp.xml and app.js for the full example files.

Scenario 2: Notification

The second scenario supported by the module is publish a notification upon receipt of the BOOT_COMPLETED broadcast.

The following diagram demonstrates how to create a receiver entry in your tiapp.xml to use the BootReceiver module.  The section shown in red illustrates the receiver and intent-filter entries needed to be made in order for your app to subscribe to the BOOT_COMPLETED broadcast.

 

Scenario 2 Diagram

Meta-Data Elements

  • bootType : This meta-data element is required and tells the module which action to take. By using the notify option, the module will publish a notification using the title and message properties defined in the tiapp.xml receipt of the BOOT_COMPLETED broadcast.
  • title : This meta-data element is required if using the bootType of notify. The title is used to create the title for the notification that will be published after receipt of the BOOT_COMPLETED broadcast.
  • message : This meta-data element is required if using the bootType of notify. The message is used to create the message body for the notification that will be published after receipt of the BOOT_COMPLETED broadcast.

Please see the sample tiapp.xml and app.js for the full example files.

Scenario 3: Using Properties

Allowing for the app at runtime to how to handle the BOOT_COMPLETED broadcast allows for handling more complex use cases but requires additional setup.  Titanium Properties are mapped to configuration elements in your tiapp.xml.  The value from these specific Titanium properties are then to determine the correct action to be taken upon receiving the BOOT_COMPLETED broadcast.

Scenario 3 Diagram

Meta-Data Elements

  • bootType : This meta-data element is required and tells the module which action to take. By using the propertyBased option, the module will look at the following properties to determine which action to take.
  • enabled_property_to_reference : This android:value element contains a reference to the Titanium Property the module will reference to see if this feature has been enabled. This property must contain a Boolean value and is false by default.
  • bootType_property_to_reference : This android:value element contains a reference to the Titanium Property the module will reference to see what action to perform. Just like the primary bootType element, you can use restart or notify to perform the desired actions. Please note all configuration elements such as title, message, sendToBack will be read from the Titanium Properties mapped in your tiapp.xml file.
  • sendToBack_property_to_reference : This android:value element contains a reference to the Titanium Property the module will reference to see if the app should be restarted in the foreground or background.. This property must contain a Boolean value and is true by default. Please note: This property is only used if the Titanium Property define in bootType_property_to_reference is set to restart.
  • icon_property_to_reference : This android:value element contains a reference to the Titanium Property the module will reference to determine which Android Resource Id to use when creating the icon for the notification created on receipt of the BOOT_COMPLETED broadcast. Please note: This property is only used if the Titanium Property define in bootType_property_to_reference is set to notify.
  • title_property_to_reference : This android:value element contains a reference to the Titanium Property the module will reference to determine which Android Resource Id to use when creating the title for the notification created on receipt of the BOOT_COMPLETED broadcast. Please note: This property is only used if the Titanium Property define in bootType_property_to_reference is set to notify.
  • message_property_to_reference : This android:value element contains a reference to the Titanium Property the module will reference to determine which Android Resource Id to use when creating the message for the notification created on receipt of the BOOT_COMPLETED broadcast. Please note: This property is only used if the Titanium Property define in bootType_property_to_reference is set to notify.

Please see the sample tiapp.xml and app.js for the full example files.

How do I get the module?

The module and source are available on Github at https://github.com/benbahrenburg/benCoding.Android.Tools

Any examples?

Usage examples are available on Github at https://github.com/benbahrenburg/benCoding.Android.Tools/tree/master/example

Enabling Nexus 4 Developer Options

Was lucky enough to get a Nexus 4 the other day and noticed the Developer options were missing.  It seems Google has hidden these options

After a few short searches it seems Google has chosen to hide the developer options by default and use a gesture to unlock. 

To enable developer features:

  1. Go to Settings -> About phone
  2. Scroll to the Build number
  3. Tap 7 times

This adds another row to your ListView with developer options.

The idea of unlocking advantaged OS features is one idea I hope others choose to borrow from Android.

Determine if Intent Receiver Exists on Android using Titanium

One of the challenges in working with Ti.Android.Intent‘s is knowing if the device has an app installed that will be able to handle the request.  The recommended approach until now was to wrap your startActivity statement within a try/catch statement.

With the new Android.Tools module you can now check if a Ti.Android.Intent has a receiver before submitting. This allows you to write more defensive code blocks like the one below:

//Add our tools module
var tools = require('bencoding.android.tools');
var platformTools = tools.createPlatform();

//Check we have external storage access
if(!Ti.Filesystem.isExternalStoragePresent()){
	alert("Access to external storage required");
	return;
}

//Create a Ti.File to our sample file
var pdfSource = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory + 'your_file.pdf');
//Create a temp file so the intent can read the file
var timeStampName = new Date().getTime();
var tempFile = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory,timeStampName +'.pdf');
if(tempFile.exists()){
	tempFile.deleteFile();
}
tempFile.write(pdfSource.read());
pdfSource = null;

//Create our PDF intent
var intent = Ti.Android.createIntent({
	action: Ti.Android.ACTION_VIEW,
	type: "application/pdf",
	data: session.tempFile.nativePath
});

//Check that the device can open the intent
if(platformTools.intentAvailable(intent)){
	//Since the device can open the intent run startActivity
	try {
		Ti.Android.currentActivity.startActivity(intent);
	} catch(e) {
		Ti.API.debug(e);
		alert('Something went wrong');
	}
}else{
	//No PDF reader to we need to alert the user to go get one.
	alert("Please go to the Google Play Store and download a PDF reader");			
}

Android.Tools project

Github Repo:

 https://github.com/benbahrenburg/benCoding.Android.Tools

Documentation:

https://github.com/benbahrenburg/benCoding.Android.Tools/tree/master/documentation

Example:

https://github.com/benbahrenburg/benCoding.Android.Tools/tree/master/example

Titanium Android Module JDT Setup

I’ve just started a project that requires the development of a few Titanium Android modules.  After configuring all of my SDK and NDK paths I was surprised to be greeted with the message that I had to install JDT…

JDT

Since Titanium Studio is Eclipse based the question is what version of the JDT is compatible?  After alittle hunting I found the “Installing the Java Development Tools” guide that provided all of the steps needed to add this dependency.

 

Hopefully this helps someone that is Googling on how to resolve this warning.