
About a month ago I purchased the
HTC Hero . The main reason for choosing this phone, rather than the iPhone, was the ability to fully develop applications for Windows.
As a sample of the pen, I wrote a small program that turns off the sound for the night. Under the cut description of the development process and a link to the program.
Terms of Reference
The problem is that modern phones can do much more than just make calls. They can receive updates from
Twitter , email and heaps of other places. However, they strive to inform the user about these updates. And everything seems to be nice until night falls. You go to bed, close your eyes, and then "dzin" or "ZHZHZH-ZHZHZH." At some point, just turn off the sound and vibration in order to fall asleep.
Just for this and need a program. It turns off all alerts in a given period of time.
')
Development environment
Eclipse is practically the only full-fledged development tool for Android. For work, I chose
Eclipse Classic 3.5.1 .
You will also need the
Android SDK . It can be found on
the download page . There is also a quick installation guide.
Where to begin
For me, Java and Android development is a completely new occupation. Therefore, the first thing I carefully studied the
lessons that are presented in the
Resources section.
Also in the
References section, you will find a comprehensive reference for both the Andriod SDK and standard java packages. The only thing missing is the use cases. As a result, you first find the class you need, and then use Google to find out how to use it in the context of the application.
User interface

User interface development takes place in the built-in editor and is understandable to anyone who has come across form designers:

Tips for designing interfaces for Android can be found in a special section of the
Dev Guide . There are also recommendations for the design of icons:

I hardly managed to fit my rectangle into the perspective required for the icons. How to do something more complicated, I can not imagine. Nevertheless, there is a
set of templates for Photoshop and Illustrator, which greatly facilitates the creation of icons.
Storing user settings
To work with user settings in Android there is a class
PreferenceManager
. The
getSharedPreferences()
method takes the name of the settings set as the first argument, and the creation mode (closed, open for reading or open for writing) as the second argument. In response, we get an object of the
SharedPreferences
class, which allows you to write and read settings. If there is no such set, it will be created:
SharedPreferences preferences = getSharedPreferences( "goodnight" , MODE_PRIVATE);
Special methods for reading various data types. The first argument is the name of the field, and the second is the default value:
preferences.getBoolean( "isEnabled" , false )
preferences.getInt( "startHour" , 23)
To write, you need to get the
SharedPreferences.Editor
object using the
edit()
method, and at the end call the
commit()
method:
Editor prefEditor =preferences.edit();
prefEditor.putBoolean( "isEnabled" ,isEnabledCheckBox.isChecked());
prefEditor.putInt( "startHour" , startTimePicker.getCurrentHour());
prefEditor.putInt( "startMinute" , startTimePicker.getCurrentMinute());
prefEditor.putInt( "endHour" , endTimePicker.getCurrentHour());
prefEditor.putInt( "endMinute" , endTimePicker.getCurrentMinute());
prefEditor.commit();
Services
In order not to keep the program constantly open and at the same time do something, Android implements full-fledged services that can run in the background. IPhone developers only dream about it.
To create a service, you must create your own class, inherited from
android.app.Service
android.app.Service
and override method
onBind()
:
public class GoodnightService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null ;
}
}
The
onCreate()
and
onDestroy()
methods can also be useful:
@Override
public void onCreate() {
super.onCreate();
Log.i( "GoodnightService" , "Service created" );
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i( "GoodnightService" , "Service destroyed" );
}
There are two types of interaction with services: the transfer of parameters at startup or the use of
Android IDL (AIDL). In the first case, you start the service and after that you can only close it. In the second case, you can create an interface through which it will be possible to manage the service. Because I planned to change the start and end time of the night, then I chose the second option.
To do this, you must create a file with the extension
.aidl and prescribe the interface in it:
interface IGoodnightService {
void UpdateSettings();
}
Now you need to compile the project in order to generate an interface from the
.aidl IDL file. After compiling, you can update the
onBind()
method and create a new
binder
property:
@Override
public IBinder onBind(Intent intent) {
return binder;
}
private final IGoodnightService.Stub binder = new IGoodnightService.Stub() {
@Override
public void UpdateSettings() {
Init();
Update();
}
};
If you do not have a
Stub()
method, then most likely the file with the interface has the extension
.java , and not
.aidl .
You also need to add your service to the
AndroidManifest.xml application manifest:

Client side services
To use the created interface, when you click on the "Apply" button, you need to perform a few simple steps. First, we need an object with the type of our interface:
private IGoodnightService service;
Secondly, you need to create a property like
ServiceConnection
ServiceConnection
that monitors the state of the service and is necessary for associating an interface with it:
private ServiceConnection svcConn= new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder binder) {
service=IGoodnightService.Stub.asInterface(binder);
}
public void onServiceDisconnected(ComponentName className) {
service= null ;
}
};
And finally, you need to associate the service with our application using the
bindService()
method:
bindService( new Intent( this ,GoodnightService. class ), svcConn, BIND_AUTO_CREATE);
Now you can safely refer to the methods described in
IGoodnightService
:
try {
service.UpdateTimers();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Alerts
In order to somehow show the serviceability of the service, I used the notification mechanism. This can be a vibration, beeps or a small icon in the status bar (second from left):

If you open the status bar, you can see the alert in a more expanded form:

Text alerts are of two kinds: reporting new events (for example, a message on
Twitter :-)) or that the program just works.
Alerts of the first type can be removed from the list by clicking on the “Clear Notifications” button. At first I did them every minute so that they would not disappear. Practice has shown that after 5-6 hours everything started to slow down wildly, and the alerts were no longer updated. :-) Then the second method was found.
To create alerts we need
NotificationManager
NotificationManager
, which can be obtained using the method
getSystemService()
getSystemService()
:
final NotificationManager mgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Now you need to create an alert itself (
Notification
Notification
):
Notification note = new Notification(R.drawable.status,
getResources().getString(R. string .startMessage),
System.currentTimeMillis());
note.flags |= Notification.FLAG_ONGOING_EVENT;
PendingIntent i = PendingIntent.getActivity( this , 0,
new Intent( this , Setup. class ), 0);
String interval = String .format( "%d:%02d – %d:%02d" , startHour,
startMinute, endHour, endMinute);
note.setLatestEventInfo( this , interval,
getResources().getString(R. string .notificationMessage), i);
Here,
PendingIntent
is a link to the application that will be launched after clicking on the notification. BUT
Notification.FLAG_ONGOING_EVENT
Notification.FLAG_ONGOING_EVENT
sets the second alert type.
To send an alert, use the method
notify()
notify()
:
mgr.notify(NOTIFY_ME_ID, note);
In order to remove the alert from the status bar, call the method
cancel()
cancel()
:
mgr.cancel(NOTIFY_ME_ID);
Mute
In order to turn off or turn on the sound, you need to get
AudioManager
AudioManager
:
AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
And set the appropriate mode using
setRingerMode()
setRingerMode()
:
manager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Final assembly of the application
In order to assemble an application into a working apk-container, you need to select a project, run the export wizard located in
Android Tools from the context menu and do everything that it asks:


Read more about this in the
Publishing section.
Micro conclusion
Writing Android apps is not as easy as Chrome extensions. Nevertheless, there is nothing supernatural in this. :-) The main thing to start.
Link to the application
Bonus for those who read:
http://x.product-studio.ru/Goodnight.apkI will be glad to hear criticism, suggestions and questions.