I'd like to describe one trick I learned at supportforums.blackberry.com
There is a native dialer Phone Application in BlackBerry.
The trick is to programmatically run menu items of dialer after incoming call, call fail or any other call event.
There is a PhoneListener interface, which gives an ability to listen to the status of incoming and outgoing phone calls.
See Listen for and handle phone events
A quote from supportforums.blackberry.com - Re: How to exit an Ui application (by simon_hain):
Listeners are hard referenced by the application they are added to. Figuratively speaking, they become part of the rim application.
If you add a listener to the phone application this listener is executed in the context of the phone app.
You can check this by using Ui.getUiEngine().getActiveScreen() in a listener method. The returned screen is the call screen of the phone application.
I use this to execute commands on phone calls:
- on callInitiated or callConnected i store a reference to the phone screen.
- i call phoneScreen.getMenu(0)
now i want to execute a command:
- i change the locale to "en"
- i iterate through the menu using menu.getSize() and menu.getItem(i)
- i check if menuItem.toString equals my command
- i call menuItem.run()
- and change the locale back (if it was changed)
you can use this to:
mute
unmute
activate speakerphone
view speeddiallist
end the call (only prior to 4.5/4.6, not sure which one)
and many more. just print the available menu items :)
A sample code for this trick, on incoming call print all menu to console, on answer call mute phone on end call - unmute phone:
public class UseScreenMenu extends Application implements PhoneListener {
String MENU_ITEM_MUTE = "Mute";
String MENU_ITEM_UNMUTE = "Unmute";
public UseScreenMenu() {
Phone.addPhoneListener(this);
}
public static void main(String[] args) {
UseScreenMenu app = new UseScreenMenu();
app.enterEventDispatcher();
}
public void callIncoming(int callId) {
printMenu();
}
public void callAnswered(int callId) {
runMenuItem(MENU_ITEM_MUTE);
}
public void callEndedByUser(int callId) {
runMenuItem(MENU_ITEM_UNMUTE);
}
private void printMenu() {
Screen screen = Ui.getUiEngine().getActiveScreen();
Menu menu = screen.getMenu(0);
System.out.println("Menu of BB Dialler - Begin");
for (int i = 0, cnt = menu.getSize(); i < cnt; i++)
System.out.println("Menu of BB Dialler - "
+menu.getItem(i).toString());
System.out.println("Menu of BB Dialler - End");
}
private void runMenuItem(String menuItemText) {
Screen screen = Ui.getUiEngine().getActiveScreen();
Menu menu = screen.getMenu(0);
for (int i = 0, cnt = menu.getSize(); i < cnt; i++)
if(menu.getItem(i).toString().equalsIgnoreCase(menuItemText))
menu.getItem(i).run();
}
public void callAdded(int callId) {}
public void callConferenceCallEstablished(int callId) {}
public void callConnected(int callId) {}
public void callDirectConnectConnected(int callId) {}
public void callDirectConnectDisconnected(int callId) {}
public void callDisconnected(int callId) {}
public void callFailed(int callId, int reason) {}
public void callHeld(int callId) {}
public void callInitiated(int callid) {}
public void callRemoved(int callId) {}
public void callResumed(int callId) {}
public void callWaiting(int callid) {}
public void conferenceCallDisconnected(int callId) {}
}
Related
I have a bitmap field in my blackberry5 app with fieldChanged listener attached to it which works absolutely fine
now my problem is that I also have an associated menu for the same purpose (I can not remove it's the requirement) and on click the menu I get a JVM 104 IllegalStateException
here is my menu class
public class TabMenu extends MenuItem{
MainScreen menuScreen;
Field button;
public TabMenu(String menuLabel,MainScreen menuScreen,Field button)
{
super(menuLabel, 1, 0);
this.menuScreen = menuScreen;
this.button = button;
}//end constructor
public void run()
{
FieldChangeListener listener = (FieldChangeListener)this.menuScreen;
listener.fieldChanged(this.button, this.button.getIndex());
this.button.setFocus();
}
}
and here is menu and fieldchnaged code
protected void makeMenu(Menu menu, int instance) {
menu.add(new RefreshMenu());
menu.addSeparator();
menu.add(new TabMenu("Go >", this, goTab));
menu.addSeparator();
}
public void fieldChanged(Field field, int context) {
if (field == goTab) {
Dialog.alert("goinf")
}
}
Try changing your TabMenu#run() method to the following:
public void run() {
this.button.fieldChangedNotify(this.button.getIndex());
this.button.setFocus();
}
I've tried this piece of code in my UiApplication class, but I get an illegalstatexception.
Ui.getUiEngineInstance().setAcceptableDirections(Display.DIRECTION_PORTRAIT);
I dont want my app to change its orientation. I want it to stay in portrait mode.
EDIT:
How it is used:
public class HelloWorld extends UiApplication {
public static void main(String[] args){
Ui.getUiEngineInstance().setAcceptableDirections(Display.DIRECTION_PORTRAIT);
HelloWorld theapp = new HelloWorld();
theapp.enterEventDispatcher();
}
public HelloWorld(){
pushScreen(new FeaturedScreen());
}
}
DemoClass()
{
int direction = Display.DIRECTION_PORTRAIT;
Ui.getUiEngineInstance().setAcceptableDirections(direction);
pushScreen(new AppScreen(this));
}
public static void main(String[] args) {
DemoClass app1 = new DemoClass();
app1.enterEventDispatcher();
}
public class HelloWorld extends UiApplication {
public static void main(String[] args){
UiEngineInstance ui = Ui.getUiEngineInstance();//I have added this new line in your code
ui.setAcceptableDirections(Display.DIRECTION_NORTH);
HelloWorld theapp = new HelloWorld();
theapp.enterEventDispatcher();
}
public HelloWorld(){
pushScreen(new FeaturedScreen());
}
}
I wrote an app which has 2 screens. The first screen is triggered by the main class. The second screen is opened by clicking a button in the first screen.
public class MyApp extends UiApplication{
public static void main(String[] args){
MyApp theApp = new MyApp();
theApp.enterEventDispatcher();
}
public MyApp(){
// Push a screen onto the UI stack for rendering.
pushScreen(new MyScreen());
}
}
public class MyScreen extends MainScreen implements FieldChangeListener
{
BasicEditField mEdit = null;
ButtonField mButton = null;
public MyScreen()
{
super();
mEdit = new BasicEditField("input: ", "some text");
add(mEdit);
mButton = new ButtonField("Go second screen");
mButton.setChangeListener(this);
add(mButton);
}
public void fieldChanged(Field field, int context)
{
if(mButton == field)
{
MyScreen2 scr = new MyScreen2();
scr.setTextValue(mEdit.getText());
UiApplication.getUiApplication().pushScreen(scr);
UiApplication.getUiApplication().popScreen(this);
}
}
}
public final class MyScreen2 extends MainScreen
{
String mTextValue = null;
LabelField mLabel = null;
public void setTextValue(String textValue)
{
mTextValue = textValue;
mLabel.setText(mTextValue);
}
public MyScreen2()
{
super();
mLabel = new LabelField();
add(mLabel);
}
}
It works on the 9700 simulator, but doesn't work on the smartphone. I wonder what is wrong? I wonder if the smartphone blocks loading app from my computer?
I tried signing .cod but nothing changes.
Any idea?
you need signing key to run your application on real device ... It cost near about 20 dollars
go here
you can find all the details from here
I think it might help you
cheers
I want to add mymenuitem on smssending menulist,
How could I do that?
You just override the makeMenu method and add whatever you want.
protected void makeMenu(Menu menu, int instance) {
menu.add(getExitItem(0,0));
}
public MenuItem getExitItem(int ordinal, int priority) {
return new MenuItem("Close", ordinal, priority) {
public void run() {
System.exit(0);
}
};
}
we are looking for a way to do the following:
user with BB enters a number (or selects a contact and clicks 'send')
our app in the background detects the call event
our app does something (e.g. blocks the call / makes a call to a different number, etc)
can this be done at all? can it be done transparently to the user (i.e. no dialogs or user involvement)?
which APIs should I look at?
Thanks
Outgoing call interception
call interception http://img200.imageshack.us/img200/6927/callinit.png
create extention of Application for background service
implement PhoneListener
use callInitiated
should be signed before use on device
should be tested against known issue
Code example:
import net.rim.blackberry.api.phone.Phone;
import net.rim.blackberry.api.phone.PhoneListener;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.component.Dialog;
public class CatchCall extends Application implements PhoneListener {
public CatchCall() {
Phone.addPhoneListener(this);
}
public static void main(String[] args) {
new CatchCall().enterEventDispatcher();
}
public void callAdded(int callId) {
}
public void callAnswered(int callId) {
}
public void callConferenceCallEstablished(int callId) {
}
public void callConnected(int callId) {
}
public void callDirectConnectConnected(int callId) {
}
public void callDirectConnectDisconnected(int callId) {
}
public void callDisconnected(int callId) {
}
public void callEndedByUser(int callId) {
}
public void callFailed(int callId, int reason) {
}
public void callHeld(int callId) {
}
public void callIncoming(int callId) {
}
public void callInitiated(int callid) {
Dialog.inform("call initiated");
}
public void callRemoved(int callId) {
}
public void callResumed(int callId) {
}
public void callWaiting(int callid) {
}
public void conferenceCallDisconnected(int callId) {
}
}
Cancel call
You can use event injection to fire Close button press event:
public void dropCall()
{
KeyEvent inject = new KeyEvent(KeyEvent.KEY_DOWN, Characters.ESCAPE, 0);
inject.post();
}
Don't forget to set permissions for device release: Options => Advanced Options => Applications => [Your Application] =>Edit Default permissions =>Interactions =>key stroke Injection
See also
BlackBerry - Simulate a KeyPress event