Blackberry: PhoneLogs.deleteCall() does not work - blackberry

On Blackberry 6.0, I have used the following code to delete all the call logs:
PhoneLogs logs = PhoneLogs.getInstance();
int lenNormal = logs.numberOfCalls(PhoneLogs.FOLDER_NORMAL_CALLS);
for (int i = 0; i < lenNormal; i++) {
logs.deleteCall(i, PhoneLogs.FOLDER_NORMAL_CALLS);
}
int lenMissed = logs.numberOfCalls(PhoneLogs.FOLDER_MISSED_CALLS);
for (int i = 0; i < lenMissed; i++) {
logs.deleteCall(i, PhoneLogs.FOLDER_MISSED_CALLS);
}
int total = lenNormal + lenMissed;
Dialog.alert("Deleted: " + total);
The dialog box says it has deleted N number of call logs but I still see the call logs in the phone. The program runs smoothly without any exception.
Googling say that: (1) Restart the phone, (2) Introduce some delay if you are deleting inside PhoneLogListener. I have tried those options too. But no luck!
Thanks in advance for any help.

It is a known bug that call log entry can not be deleted using: PhoneLogs.deleteCall(). See it here: http://supportforums.blackberry.com/t5/Java-Development/Unable-to-delete-phone-logs/m-p/1587315
As a hackish solution, you can use input simulation though. For example:
private void deleteLatestCallLog() {
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
Invoke.invokeApplication(Invoke.APP_TYPE_PHONE,
new PhoneArguments());
}
});
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
injectKeyEvent(Keypad.KEY_BACKSPACE);
}
});
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
injectKeyEvent(Keypad.KEY_ENTER);
}
});
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
injectKeyEvent(Keypad.KEY_ESCAPE);
}
});
}
But this method has a few bugs. It should not be used at all in my opinion :-)

Related

Invalidate picturescrollfield

I am loading images in PictureScrollField from the server and want that until images are loaded from server, the PictureScrollField shows a blank image and when the image loads in image array, it repaints (redraw) the PictureScrollField like a ListField.
I read from BlackBerry documentation that every field can be invalidated (that is, we can repaint it) but when I use the PictureScrollField.invalidate() method in my program, I get an error :
The method invalidate from the type Field is not visible
The program I use is listed below
public final class GetMoreImage extends MainScreen {
public static PictureScrollField psf;
int size;
int length;
String text=null;
EncodedImage[] encodedImage;
VerticalFieldManager vmanger;
private LoadImages loadImages;
public GetMoreImage(int index) {
super(NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR);
this.size=index;
try {
length=ListHome.object[size].getJSONArray("UrlArray").length();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ScrollEntry[] entries = new ScrollEntry[length];
for (int i = 0; i < length; i++) {
if(encodedImage != null && encodedImage.length > i && encodedImage[i] != null) {
EncodedImage encodedImg =ListHome.sizeImage(JPEGEncodedImage.encode(Bitmap.getBitmapResource("icon.png"),80),640,380);
Bitmap bmp=encodedImg.getBitmap();
entries[i] = new ScrollEntry(bmp, "hello", "");
}
else {
try {
text=ListHome.object[size].getJSONArray("UrlArray").getString(i).toString();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EncodedImage encodedImg =ListHome.sizeImage(JPEGEncodedImage.encode(connectServerForImage(text),80),640,380);
Bitmap bmp=encodedImg.getBitmap();
entries[i] = new ScrollEntry(bmp, "hello", "");
}
}
psf = new PictureScrollField();
psf.setData(entries, 0);
psf.setHighlightStyle(HighlightStyle.ILLUMINATE_WITH_SHRINK_LENS);
add(psf);
loadImages = new LoadImages(80, 80);
loadImages.start();
}
private class LoadImages extends Thread {
int widthL;
int heightL;
LoadImages(int width, int height) {
this.widthL = width;
this.heightL = height;
}
public void run() {
encodedImage=new EncodedImage[length];
if (ListHome.object[size] != null) {
for (int i = 0; i < length; i++) {
try {
String text=ListHome.object[size].getJSONArray("UrlArray").getString(i).toString();
EncodedImage encodedImg = JPEGEncodedImage.encode(connectServerForImage(text), 80);//Get Image from Server
encodedImage[i] = ListHome.sizeImage(encodedImg, Display.getWidth(), Display.getHeight()-100);
psf.invalidate();//This Line generate error
} catch (Exception e)
{
e.printStackTrace();
}
}
} else {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("No Data Found");
}
});
}
}
}
}
Any help will be appreciated.
Thanks
The reason you get a compile error on this line:
psf.invalidate();//This Line generate error
is because the PictureScrollField#invalidate() method is protected, not public. So, code not in PictureScrollField or a class that extends PictureScrollField cannot use it directly.
However, you don't need to use invalidate(). invalidate() is a low-level method that instructs a field to repaint. However, PictureScrollField has a higher-level method that is designed to allow you to change images, and have the field (re)draw them: PictureScrollField#setData().
Because that method is changing the user interface (UI), it should be run on the UI/main thread. This will not automatically happen if you make the call inside the run() method you are using to download the images. So, you'll need something like this inside your LoadImages class:
public void run() {
encodedImage=new EncodedImage[length];
if (ListHome.object[size] != null) {
for (int i = 0; i < length; i++) {
try {
String text=ListHome.object[size].getJSONArray("UrlArray").getString(i).toString();
EncodedImage encodedImg = JPEGEncodedImage.encode(connectServerForImage(text), 80);//Get Image from Server
encodedImage[i] = ListHome.sizeImage(encodedImg, Display.getWidth(), Display.getHeight()-100);
//psf.invalidate();//This Line generate error
entries[i] = new ScrollEntry(encodedImage[i].getBitmap(), "label", "callout");
// we must update the scroll entries on the UI/main thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
// setting the field to index 'i' will scroll to the image
// that was just downloaded
psf.setData(entries, i);
});
} catch (Exception e)
{
e.printStackTrace();
}
}
}
In order to make this work, you must change the local entries variable to a member variable in your GetMoreImage class:
public final class GetMoreImage extends MainScreen {
public static PictureScrollField psf;
private ScrollEntry[] entries;
but, you can still instantiate it (entries = new ScrollEntry[length];) in your screen's constructor, or whenever you know the correct length.

How to close streaming player screen when sp.realize() method executing

I have read the knowledgebase article "Streaming media - Start to finish" It is working fine. When I click the open video, the player screen is open. When I click the back button before the player is realized, it does not come to back to the right screen.
when sp.realize(); method executing user can't come to back screen.
after loading player. it close.
How to go back a screen if sp.realize() method is still executing?
new Thread(new Runnable()
{
public void run()
{
try
{
if(sp==null)
{
sp = new StreamingPlayer(url, contentType);
sp.setBufferCapacity(bufferCapacity);
sp.setInitialBuffer(initBuffer);
sp.setRestartThreshold(restartThreshold);
sp.setBufferLeakSize(bufferLeakSize);
sp.setConnectionTimeout(connectionTimeout);
sp.setLogLevel(logLevel);
sp.enableLogging(eventLogEnabled, sdLogEnabled);
sp.addStreamingPlayerListener(playerScreen);
sp.realize();
volC = (VolumeControl)sp.getControl("VolumeControl");
if(contentType.toLowerCase().indexOf("video")!=-1)
{
vidC = (VideoControl)sp.getControl("VideoControl");
videoField = (Field)vidC.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field");
vidC.setDisplaySize(Display.getWidth(), Display.getHeight()-timeSeeker.getHeight()-byteSeeker.getHeight());
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
replace(getField(0), videoField);
}
});
vidC.setVisible(true);
}
if(contentType.toLowerCase().indexOf("audio")!=-1)
{
audioIcon = true;
if(!(getField(0)==albumArt))
{
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run()
{
replace(videoField, (Field)albumArt);
}
});
}
}
sp.start();
}
else
{
sp.stop();
sp.close();
sp = null;
run();
}
} catch(Throwable t)
{
//log(t.toString());
}
}
}).start();
I'm not sure exactly what you mean by this. However, have you tried running the audio stuff in a separate thread? That should reduce the likelihood of it interfering with anything else.

Loading Screen in BlackBerry

Suppose this is my NeteorkingMainScreen class which will display the text retrived from web.
public NetworkingMainScreen() {
setTitle("Networking");
urlField = new EditField("URL:", "");
textOutputField = new RichTextField();
add(urlField);
add(textOutputField);
}
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(new MenuItem("Get", 10, 10) {
public void run() {
getURL();
}
});
private void getURL() {
HttpRequestDispatcher dispatcher = new HttpRequestDispatcher(urlField.getText(),"GET", this);
dispatcher.start();
}
//*********************************************************************************
//HttpRequestDispatcher class performs the downloading of contents of webpage.
public class HttpRequestDispatcher extends Thread {
private String url;
private String method; // GET or POST
private NetworkingMainScreen screen;
public HttpRequestDispatcher(String url, String method, NetworkingMainScreen screen){
this.url = url;
this.method = method;
this.screen = screen;
}
public void run() {
try{
HttpConnection connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(method);
int responseCode = connection.getResponseCode();
if (responseCode != HttpConnection.HTTP_OK){
screen.requestFailed("Unexpected response code: " + responseCode);
connection.close();
return;
}
String contentType = connection.getHeaderField("Content-type");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream responseData = connection.openInputStream();
byte[] buffer = new byte[10000];
int bytesRead = responseData.read(buffer);
while(bytesRead > 0) {
baos.write(buffer, 0, bytesRead);
bytesRead = responseData.read(buffer);
}
baos.close();
connection.close();
screen.requestSucceeded(baos.toByteArray(), contentType);
}
catch (IOException ex) {
screen.requestFailed(ex.toString());
}
}
}
//***************************************************************************
//WaitScreen displays animation till the downloading is completed.
class WaitScreen extends FullScreen
{
}
Now I m getting confused...
When to start the WaitScreen class. Suppose i start by creating an object of WaitScreen and pushing the screen object.
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(new MenuItem("Get", 10, 10) {
public void run()
UiApplication.getUiApplication.pushScreen(new WaitScreen());
getURL();
}
});
How would my code know that it should displaying the animated Screen and display the contents of the webpages ie i mean how my code will knows downloading data has been completed. ie when i will call popScreen()?
I interface is to be used how can use the interface and what help we will get by using the interface.? Plz help
This is rather simple.
Your HttpRequestDispatcher should have a handle to the WaitScreen instance to be able to show it on start and close it upon completion.
So inside of the HttpRequestDispatcher you could (1) create the WaitScreen. (2) Push it. (3) Do the stuff the HttpRequestDispatcher should do. (4) Pop the the WaitScreen. Smth like that:
final WaitScreen waitScreen = new WaitScreen();
// just to reduce code duplication
final UiApplication app = UiApplication.getUiApplication();
// we are on the non-UI thread, so need
// to use UiApplication.invokeLater(Runnable action),
// it safely runs the passed action on the UI thread
app.invokeLater(new Runnable() {
public void run() {
app.pushScreen(waitScreen);
}
});
try {
// main networking actions go here
} catch (..) {
// error handling goes here
} finally {
// make sure we close the waitScreen
app.invokeLater(new Runnable() {
public void run() {
app.popScreen(waitScreen);
}
});
}
Here, Try this. All you have to do is put your code into the "run" function.
If you want help with the HttpRequest stuff or have trouble with the classes there, let me know. I have a web library with thread classes set up to use the classes within that post.

Blackberry - How to get the background application process id

In my blackberry simulator i m running two application at the background now i want to retrive which are the application running in the background.I don't how to do. Is it possible to show which are the application running in the background.
List and switch visible application
To list all visible applications use ApplicationManager.getVisibleApplications()
To bring some application foreground use ApplicationManager.requestForeground(processId)
alt text http://img195.imageshack.us/img195/7003/applist.png link text http://img32.imageshack.us/img32/9273/applistmenu.png
Code:
class Scr extends MainScreen {
ApplicationDescriptor[] mAppDes;
public Scr() {
listApplications();
}
void listApplications() {
ApplicationManager appMan =
ApplicationManager.getApplicationManager();
mAppDes = appMan.getVisibleApplications();
add(new LabelField("Visible Applications:"));
for (int i = 0; i < mAppDes.length; i++) {
boolean isFG = appMan.getProcessId(mAppDes[i]) == appMan
.getForegroundProcessId();
String text = (isFG ? "[F]:" : "[B]") + mAppDes[i].getName();
add(new LabelField(text));
}
}
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(refreshApps);
makeAppMenuItems(menu);
}
MenuItem refreshApps = new MenuItem("Refresh", 0, 0) {
public void run() {
deleteAll();
listApplications();
}
};
class AppMenuItem extends MenuItem {
ApplicationDescriptor mAppDes;
public AppMenuItem(ApplicationDescriptor appDes) {
super(appDes.getName(), 100000, 100000);
mAppDes = appDes;
}
public void run() {
ApplicationManager appMan = ApplicationManager
.getApplicationManager();
int processId = appMan.getProcessId(mAppDes);
appMan.requestForeground(processId);
}
}
void makeAppMenuItems(Menu menu) {
for (int i = 0, cnt = mAppDes.length; i < cnt; i++)
menu.add(new AppMenuItem(mAppDes[i]));
}
}
Take a look at the API Reference for the RuntimeStore.
And a Knowledge Base entry how to switch an App to the Background/Foreground.
Good Luck!
Not really an answer, but the system won't let me comment.
Do you really need to know what the running background applications are, or just if your applications are running in the background. If the latter I imagine you can build something using the runtime store

BlackBerry - Simulate a KeyPress event

I have a BlackBerry application that needs to take pictures from the camera and send them to a server. In order to do this i invoke the native camera application and listen to the filesystem. Once an image is captured and saved as a new jpeg file i get notified, resume foreground control and go about my business. The problem starts occurring after the first time this cycle is completed because now when i decide to call the camera application again it is already opened, and now the user is seeing a thumbnail of the last picture that was taken and several buttons allowing him to manipulate/manage it. naturally what i want the user to see is a preview of what the camera is "seeing" before he snaps another photo as he did before.
I have thought of various ways to solve this including killing the camera app each time (I understand this cannot be done programatically?), sending CameraArguments when invoking the app (which appears to be useless), and now i was thinking a solution could be as simple generating a "Back" key event before switching back to my app which would theoretically dismiss the annoying edit screen. Could this really be done? and if not is there any other possible solution you may think of?
A kind of hack...
start Camera App
in TimerTask check if Camera App started and if it need to be closed (some flag)
if yes, invoke it(so it will became active) and push ESC keypress event injection to close it
Take a look at this:
class Scr extends MainScreen {
boolean killCameraApp = false;
final String mCameraModuleName = "net_rim_bb_camera";
final CameraArguments args = new CameraArguments();
public Scr() {
super();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (isCameraRunning() && killCameraApp) {
getApplication().invokeAndWait(callCamera);
getApplication().invokeAndWait(killCamera);
}
}
}, 0, 100);
}
Runnable callCamera = new Runnable() {
public void run() {
callCamera();
}
};
Runnable killCamera = new Runnable() {
public void run() {
injectKey(Characters.ESCAPE);
killCameraApp = false;
}
};
private boolean isCameraRunning() {
boolean result = false;
ApplicationManager appMan =
ApplicationManager.getApplicationManager();
ApplicationDescriptor[] appDes = appMan.getVisibleApplications();
for (int i = 0; i < appDes.length; i++) {
result = mCameraModuleName.equalsIgnoreCase(appDes[i]
.getModuleName());
if (result)
break;
}
return result;
}
private void callCamera() {
Invoke.invokeApplication(Invoke.APP_TYPE_CAMERA,
new CameraArguments());
}
private void injectKey(char key) {
KeyEvent inject = new KeyEvent(KeyEvent.KEY_DOWN, key, 0);
inject.post();
}
protected void makeMenu(Menu menu, int instance) {
menu.add(new MenuItem("start camera", 0, 0) {
public void run() {
callCamera();
killCameraApp = false;
}
});
menu.add(new MenuItem("kill app", 0, 0) {
public void run() {
killCameraApp = true;
}
});
super.makeMenu(menu, instance);
}
}
EDIT: Don't forget to set permissions for device release:
Options => Advanced Options => Applications => [Your Application] =>Edit Default permissions =>Interactions =>key stroke Injection

Resources