Tutorial: Detect and display the connected WIFI network
We want to detect and display the currently connected WIFI network. On the way we will learn how to change the app name and icon.
- You should have completed the Getting started with Ruboto tutorial.
- A connected Android device with WIFI capability.
This tutorial has been tested with the following setups
Platform | JDK | ant | Ruby | ruboto | jruby-jars | Device | API level | Tester |
---|---|---|---|---|---|---|---|---|
OS X 10.8.3 | 1.7.0_21 | 1.8.4 | MRI 2.0.0 | 0.13.0 | RubotoCore | Samsung Glxy S3 | android-16 | donv |
OS X 10.7.4 | 1.6.0_33 | 1.8.4 | MRI 1.8.7 | 0.7.0.rc.1 | ASUS TF101 | android-15 | donv | |
OS X 10.8.0 | 1.6.0_33 | 1.8.2 | MRI 1.8.7 | 0.7.1.rc.0 | HTC Desire HD | android-10 | donv |
Connect your device
Generate the application
ruboto gen app --package org.ruboto.examples.wifi_detector
Install the apk into your device
cd wifi_detector
rake install
You should see an application called "Wifi Detector" in your application list on the device. Try starting it. You should eventually get "What hath Matz wrought?" and a button. Clicking the button displays a short notification (toast) "Flipped a bit via butterfly".
Edit the application name in res/values/strings.xml
Change "Wifi Detector" to "My Wifi Detector".
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name='app_name'>
My Wifi Detector
</string>
</resources>
Edit the file src/wifi_detector_activity.rb
Change the line
set_title 'Domo arigato, Mr Ruboto!'
to
set_title 'My WIFI Detector'
Download these images and place in res/drawable-hdpi , res/drawable-mdpi , and res/drawable-ldpi .
=> res/drawable-hdpi/ic_launcher.png
=> res/drawable-mdpi/ic_launcher.png
=> res/drawable-ldpi/ic_launcher.png
Build and install the app and verify that the application name, screen title, and application icons have changed.
rake install start
Add the following permissions to AndroidManifest.xml
just below the uses-sdk
tag.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Edit the file src/wifi_detector_activity.rb
to
require 'ruboto/widget'
require 'ruboto/util/toast'
ruboto_import_widgets :Button, :LinearLayout, :TextView
class WifiDetectorActivity
def onCreate(bundle)
super
set_title 'My WIFI Detector'
self.content_view = linear_layout :orientation => :vertical, :gravity => android.view.Gravity::CENTER do
button :text => 'Show WIFI state', :layout => {:width => :wrap_content}, :on_click_listener => proc{show_wifi_state}
end
end
private
def show_wifi_state
wifi_service = getSystemService(android.content.Context::WIFI_SERVICE)
ssid = wifi_service.connection_info.getSSID
if ssid
toast "Connected to #{ssid}"
else
toast 'Not connected to any WIFI network'
end
end
end
Build and install the app and verify that WIFI connection state is displayed correctly when you press the button.
rake update_scripts:restart
Generate the broadcast receiver
ruboto gen class BroadcastReceiver --name WifiReceiver
Change the generated file src/wifi_receiver.rb
to
import android.app.Notification
import android.app.PendingIntent
import android.content.Intent
import android.content.Context
import android.net.wifi.WifiManager
import android.view.View
import android.widget.Toast
import android.util.Log
class WifiReceiver
HELLO_ID = 1
def onReceive(context, intent)
Log.v 'WifiDetector', 'Woohoo! Network event!'
if intent.action == WifiManager::NETWORK_STATE_CHANGED_ACTION
wifi_service = context.getSystemService(Context::WIFI_SERVICE)
if (ssid = wifi_service.connection_info.getSSID)
if ssid != @ssid
Toast.makeText(context, "Connected to #{ssid}", 5000).show
@notification_manager = context.getSystemService(Context::NOTIFICATION_SERVICE)
icon = $package.R::drawable::ic_launcher
tickerText = 'In the right place!'
notify_when = java.lang.System.currentTimeMillis
notification = Notification.new(icon, tickerText, notify_when)
contentTitle = 'You are in the right place!'
contentText = "You are connected to #{ssid}."
notificationIntent = Intent.new(context, $package.WifiDetectorActivity.java_class)
contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0)
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent)
@notification_manager.notify(HELLO_ID, notification)
@ssid = ssid
end
else
remove_notification(context)
end
elsif intent.action == WifiManager::WIFI_STATE_CHANGED_ACTION
info = intent.getIntExtra(WifiManager::EXTRA_NETWORK_INFO, WifiManager::WIFI_STATE_DISABLED)
Log.d('WifiDetector', "WIFI state change: #{info}")
remove_notification(context) if info == WifiManager::WIFI_STATE_DISABLED
end
end
private
def remove_notification(context)
return unless @notification_manager
return unless @ssid
Log.v 'WifiDetector', 'Removing notification.'
@ssid = nil
Toast.makeText(context, 'Not connected to any WIFI network', 5000).show
@notification_manager.cancel(HELLO_ID)
end
end
Insert the following code into src/wifi_detector_activity.rb
inside the WifiDetectorActivity
class, just before the private
line.
def onResume
super
@receiver = $package.WifiReceiver.new
filter = android.content.IntentFilter.new(android.net.wifi.WifiManager::NETWORK_STATE_CHANGED_ACTION)
registerReceiver(@receiver, filter)
end
def onPause
super
unregisterReceiver(@receiver)
@receiver = nil
end
Rebuild and install, and restart the application.
rake update_scripts:restart
You should now see a toast whenever your application is running and the WIFI connection state changes.
Generate a service
ruboto gen class Service --name WifiDetectorService
This will generate the files src/org/ruboto/examples/wifi_detector/WifiDetectorService.java
and src/wifi_detector_service.rb
The former will run the latter on service lifecycle events.
Change the content of src/wifi_detector_service.rb
to this
import android.util.Log
class WifiDetectorService
def onStartCommand(intent, flags, startId)
Log.i('WifiDetector', 'Service command started')
super
@receiver = $package.WifiReceiver.new
registerReceiver(@receiver, android.content.IntentFilter.new(android.net.wifi.WifiManager::WIFI_STATE_CHANGED_ACTION))
registerReceiver(@receiver, android.content.IntentFilter.new(android.net.wifi.WifiManager::NETWORK_STATE_CHANGED_ACTION))
android.app.Service::START_STICKY
end
def onDestroy
Log.i('WifiDetector', 'Service destroyed')
super
unregisterReceiver(@receiver)
@receiver = nil
end
end
Start the service by adding the following line to the end of the on_create
method in src/wifi_detector_activity.rb
startService(android.content.Intent.new(application_context, $package.WifiDetectorService.java_class))
Rebuild, install, and restart the application
rake update_scripts:restart
You should now see a toast whenever the WIFI connection state changes, regardless of if your application is showing.
Generate another broadcast receiver
ruboto gen class BroadcastReceiver --name BootReceiver
Change the generated file src/boot_receiver.rb
to
require 'ruboto/base'
import android.util.Log
class BootReceiver
def onReceive(context, intent)
Log.v 'WifiDetector', 'Boot detected!'
$package_name = context.package_name
$package = eval("Java::#{$package_name}")
context.startService(android.content.Intent.new(context, $package.WifiDetectorService.java_class))
end
end
Now edit AndroidManifest.xml
, and add an intent filter to the newly generated BootReceiver entry
<receiver android:name="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
Finally add the permission to receive the broadcast after boot in the AndroidManifest.xml
file:
<uses-permission android:name='android.permission.RECEIVE_BOOT_COMPLETED'/>
Rebuild, install, and restart the application
rake update_scripts:restart
The WIFI detector will now be started automatically whenever you start your device.
- Ensure only one instance of the main activity is active at any time