simple_eif_phone

Write an Android app in Eiffel, and get a signed APK from one command.

MIT License Android 8.0 or later Design by Contract

Keep frames coming while fingers move

A busy touch screen can fill the queue faster than you drain it. Take events up to a limit, then show a frame.

from until phone.lifecycle.is_destroyed loop
	phone.wait_for_event
	handle
	from
		l_more := True
		l_taken := 1
	until
		not l_more or l_taken >= Events_per_frame or phone.lifecycle.is_destroyed
	loop
		phone.poll_event (0)
		if phone.last_event.is_none then
			l_more := False
		else
			handle
			l_taken := l_taken + 1
		end
	end
	if dirty and not phone.lifecycle.is_destroyed then
		show
	end
end

Track each finger

inspect phone.last_event.kind
when Kind_touch_down then
	start_stroke (phone.last_event)     -- by phone.last_event.pointer_id
when Kind_touch_move then
	continue_stroke (phone.last_event)  -- phone.last_event.x, .y
when Kind_touch_up then
	finish_stroke (phone.last_event)
when Kind_touch_cancel, Kind_focus_lost, Kind_window_lost then
	forget_all_strokes
else
end

Always handle Kind_touch_cancel: Android can take a touch back.

Draw your own pixels

Keep an ARGB32 image in a MANAGED_POINTER, then copy it to the screen in one call.

if phone.screen.has_window then
	phone.screen.begin_frame
	if phone.screen.in_frame then
		phone.screen.present_argb (l_pixels.item, l_width, l_height, l_width * 4)
		phone.screen.end_frame
	end
end

Stay ready for in_frame to be False: Android may refuse a frame.

Save state when paused

Android can end a paused app without warning, so save then.

when Kind_paused then
	save_strokes
save_path: STRING
	do
		Result := phone.storage.internal_path + "/strokes.txt"
	end

When reading the file back, guard the loop. read_line requires file_readable, which is False on an empty file.

from until f.end_of_file or else not f.file_readable loop
	f.read_line
	-- use f.last_string
end

Keep Back for the app

phone.set_back_policy (phone.Back_app)
...
when Kind_key_up then
	if phone.last_event.key_code = Key_back then
		if nothing_to_undo then
			phone.finish
		else
			undo
		end
	end

Fit any screen

l_brush := phone.metrics.dp (6).max (2)        -- 6 dp in pixels
l_top := phone.metrics.inset_top               -- clear of the status bar
l_bottom := phone.metrics.height - phone.metrics.inset_bottom

Rebuild your image on Kind_window_resized and Kind_content_rect_changed. Only redraw everything when the size really changed.

Read a file packed in the APK

phone.assets.read_asset ("fonts/title.bin")
if attached phone.assets.last_asset as al_data then
	use (al_data, phone.assets.last_asset_size)
end

Write a line to the log

phone.log.set_tag ("MyApp")
phone.log.info ("loaded " + strokes.count.out + " strokes")

A tag holds at most 23 characters. Read the lines with eifphone log myapp.