How can I get FilePicker working properly on certain BlackBerry handsets? - blackberry

I'm implementing a Filepicker in my app to allow users to choose photos from their phones. The code I'm using is as follows:
Calling the Filepicker:
try
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
FilePicker fp = FilePicker.getInstance();
fileListener = new FilePickListener();
fp.setListener(fileListener);
fp.show();
}
});
}
catch (Exception e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Please check your data card..");
}
});
}
And the method to get the filename in my FilePickListener:
public void selectionDone(String str)
{
this.currFileName = str;
int index = str.lastIndexOf('/');
Dialog.alert("Filename: "+str.substring(index+1).trim());
}
This works perfectly in most handsets that I've tried it on (which have been a mix of handsets with some running OS5 and some running OS6). But on some, like the 8900 (running OS v5.0.0.411) it doesn't work properly. The Filepicker gets called and appears, but when any file gets selected, the selectionDone method doesn't get called. I've tested it on two separate 8900s and both have the same problem.
Does anyone have an idea why it works on certain handsets and not other?

You are a victim of a known RIM issue: FilePicker throws ControlledAccessException.
The issue is marked as "Fixed". However there is no info in which OS version they fixed it. (Is it so difficult to tell such a useful info?)
But from the comments to the issue:
We experience the very same issue with OS 5.0.0.321 on a Bold 9700. However, the issue does NOT appear on OS 5.0.0.464
so my guess would be they fixed it in OS 5.0.0.464. But that's not the end - in OS 6 FilePicker appears broken in early versions of OS 6 again. The conclusion - just don't use it. Use a custom file browser screen to pick a file. There is a sample in SDK 4.7.0 named FileExplorerDemo, check it for implementation details.

This is a known issue. FilePicker does not open on some devices and return an error, like the 8900 device. You can catch this error on some devices by adding the catch (Error e) { }
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
FilePicker fp = FilePicker.getInstance();
fileListener = new FilePickListener();
fp.setListener(fileListener);
fp.show();
}
});
}
catch (Exception e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Please check your data card..");
}
});
}
catch (Error e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("This device does not support File Picker");
}
});
}

Related

How do you send message using NFC with Xamarin.Android?

I am developing and app to demostrate how NFC works. My goal is to make and app that will work very similary to Android Beam. I am using Xamarin.Android. The goal is to type message to one device, press button and it should be send to another device with the same app where it should be shown. I have tried almost everything even the documentation but it seems like it doesnt work. Does anyone have any experience with this technology? Is this technology even available nowadays?
There is some of my code to get you an idea about what i am trying to do:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
mNfcAdapter = NfcAdapter.GetDefaultAdapter(this);
myButton.Click += (e, o) => {
mNfcAdapter.SetNdefPushMessageCallback(this, this);
mNfcAdapter.SetOnNdefPushCompleteCallback(this, this);
};
}
public NdefMessage CreateNdefMessage(NfcEvent e)
{
DateTime time = DateTime.Now;
var text = (time.ToString("HH:mm:ss") + message2);
NdefMessage msg = new NdefMessage(
new NdefRecord[] { CreateMimeRecord (
text, Encoding.UTF8.GetBytes (text))});
return msg;
}
private NdefRecord CreateMimeRecord(string mimeType, byte[] payload)
{
byte[] mimeBytes = Encoding.UTF8.GetBytes(mimeType);
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TnfMimeMedia, mimeBytes, new byte[0], payload);
return mimeRecord;
}
public void OnNdefPushComplete(NfcEvent e)
{
Toast.MakeText(this.ApplicationContext, "Message sent", ToastLength.Long).Show();
}
protected override void OnResume()
{
base.OnResume();
if (NfcAdapter.ActionNdefDiscovered == Intent.Action)
{
ProcessIntent(Intent);
}
}
protected override void OnNewIntent(Intent intent)
{
Intent = intent;
}
void ProcessIntent(Intent intent)
{
IParcelable[] rawMsgs = intent.GetParcelableArrayExtra(
NfcAdapter.ExtraNdefMessages);
NdefMessage msg = (NdefMessage)rawMsgs[0];
var textViewMsg = FindViewById<TextView>(Resource.Id.textViewMsg);
textViewMsg.Text = Encoding.UTF8.GetString(msg.GetRecords()[0].GetPayload());
}
Thank you all :)
OnNdefPushComplete and the whole Android Beam was deprecated and removed from Android 10
https://developer.android.com/reference/android/nfc/NfcAdapter.OnNdefPushCompleteCallback
If you want to do Device to Device NFC going forward then it should be possible with one phone doing Host Card Emulation (HCE) and the other using enableReaderMode
But Google recommend using Bluetooth or Wifi Direct as a more reliable replacement for Android Beam. One of the replacement methods Google provided was Android Nearby https://developers.google.com/nearby

Read data from DHT11 using Android Things and i.MX7D

since a couple of days I'm struggling with a problem in reading temperature/humidity data from sensor (DHT11) using Android Things kit (i.MX7D). I've googled many examples and all of them were made using Arduino, Raspberry Pi or STM's (so C/C++), but none for i.MX7D and Java.
My problem is that I cannot read real values of temperature/humidity, because all I get from the sensor is only a boolean value indicating HIGH/LOW state. I haven't found any library for this sensor that would somehow help to convert it to real degrees/percent values.
Do you know if it's even possible to obtain these real values using the hardware that I have? If it is, could you please give me a hint or show some code how to do that, so that I can finally make some progress? I will much appreciate all kind of help.
Here is my piece of code:
import android.app.Activity;
import android.os.Bundle;
import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.GpioCallback;
import com.google.android.things.pio.PeripheralManager;
public class MainActivity extends Activity {
private Gpio gpio;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PeripheralManager manager = PeripheralManager.getInstance();
try {
gpio = manager.openGpio("GPIO2_IO05");
configureInput(gpio);
configureOutput(gpio);
} catch (IOException e) {
e.printStackTrace();
}
}
private GpioCallback gpioCallback = new GpioCallback() {
#Override
public boolean onGpioEdge(Gpio gpio) {
try {
if (gpio.getValue()) {
System.out.println("high");
} else {
System.out.println("low");
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
#Override
public void onGpioError(Gpio gpio, int error) {
System.out.println(gpio + ": Error event " + error);
}
};
public void configureInput(Gpio gpio) throws IOException {
gpio.setDirection(Gpio.DIRECTION_IN);
gpio.setActiveType(Gpio.ACTIVE_HIGH);
gpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
gpio.registerGpioCallback(gpioCallback);
}
public void configureOutput(Gpio gpio) throws IOException {
gpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_HIGH);
gpio.setActiveType(Gpio.ACTIVE_LOW);
gpio.setValue(true);
}
}
It's not possible to read from that sensor from Android things. It uses a one wire protocol similar to I2C but the speed required for the GPIO port to be able to read it is too fast for Android things.
As suggested, you can read it using an Arduino and then connect the Arduino as I2C slave, of you can use a different temperature and humidity sensor, like the BME280 which communicate via I2C and it's still reasonably cheap

LWUIT ConnectionRequest: Bad Request on Blackberry

My lwuit application is working fine on Blackberry Simulator while on device the application installs successfully, starts normally, but where am having issues is on network connection. Trying to access network I get 400 Bad Request message. I don't no what am doing wrong, my network connection code is as below:
public ConnectionRequest prepareConnection(String page, String progressMsg, final int request)
{
final ConnectionRequest conR = new ConnectionRequest()
{
public void readResponse(InputStream input) throws IOException {
StringBuffer sb = new StringBuffer();
int ch;
while((ch=input.read()) != -1)
sb.append((char)ch);
httpResponse(sb.toString().trim(), request);
}
};
conR.setUrl(NetworkHandler.getURL()+page);
conR.setDuplicateSupported(true);
Progress progress = new Progress(progressMsg, conR)
{
public void actionCommand(Command command)
{
if(command.getCommandName().equals("Cancel"))
conR.kill();
}
};
conR.setDisposeOnCompletion(progress);
return conR;
}
private void login(String code)
{
Container container = Display.getInstance().getCurrent();
if(!validateLogin(container))
{
showDialogMessage("Alert", "Please enter your user name and password!");
return;
}
NetworkManager.getInstance().start();
ConnectionRequest conR = prepareConnection(NetworkHandler.LOGIN_PAGE, "Authenticating...", RequestType.LOGIN);
Dialog dialog = conR.getDisposeOnCompletion();
conR.setPost(true);
conR.addArgument("u", getFieldValue(findTxtUserName(container)));
conR.addArgument("p", getFieldValue(findTxtPassword(container)));
conR.addArgument("c", code);
NetworkManager.getInstance().addToQueue(conR);
dialog.show();
}
public void onLoginForm_BtnLoginAction(Component c, ActionEvent event) {
login("");
}
Please I want you guys to help me out.
Thanks in Advance.
The login me
This usually indicates a problem in APN configuration on the device. Normally Blackberry app's workaround incorrect APN configurations automatically which is a pretty difficult thing to do. CodenameOne does that seamlessly but LWUIT does not.

How to silence an incoming call

I am trying to silence an incoming call and prevent the BlackBerry device from ringing. I tried Alert.setVolume(0) and some EventInjector keys but this didn't work.
So how to silence an incoming call?
I was puzzled by your question and decided to take up the challenge. I tried different thing including
Playing a "silence" audio file hoping to overlap the device's ringing or occupy the media player
Hacking the phone screen via UiApplication.getUiApplication().getActiveScreen()
Injecting keyboard events
Eventually, injecting VOLUME UP key (VOLUME DOWN key works as well) event worked for me and muted the device ringing on incoming call. The drawback with this approach is that sometimes the device did ring for a fraction of second before muting.
import net.rim.blackberry.api.phone.AbstractPhoneListener;
import net.rim.blackberry.api.phone.Phone;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.EventInjector;
import net.rim.device.api.ui.Keypad;
class Muter extends AbstractPhoneListener {
public void callIncoming(int callId) {
Thread muterThread = new Thread(new Runnable() {
public void run() {
EventInjector.invokeEvent(new EventInjector.KeyCodeEvent(EventInjector.KeyCodeEvent.KEY_DOWN, (char) Keypad.KEY_VOLUME_UP, 0));
EventInjector.invokeEvent(new EventInjector.KeyCodeEvent(EventInjector.KeyCodeEvent.KEY_UP, (char) Keypad.KEY_VOLUME_UP, 0));
}
});
muterThread.setPriority(Thread.MAX_PRIORITY);
muterThread.start();
}
}
public class MuterApp extends Application {
public static void main(String[] args){
Phone.addPhoneListener(new Muter());
new MyApp().enterEventDispatcher();
}
}
The following also works (replace Muter thread in callIncoming() method with the following code).
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
EventInjector.invokeEvent(new EventInjector.KeyCodeEvent(EventInjector.KeyCodeEvent.KEY_DOWN, (char) Keypad.KEY_VOLUME_UP, 0));
EventInjector.invokeEvent(new EventInjector.KeyCodeEvent(EventInjector.KeyCodeEvent.KEY_UP, (char) Keypad.KEY_VOLUME_UP, 0));
}
});
You won't be able to disable the sound programmatically (found a couple other sources that said the same thing). The best workaround people have seemed to come up with was to use the EventInjector to change the phone's sound profile to silent.
Some Blackberry phones have a mute key. You may try the following idea:
public void callIncoming(int callId) {
if (KeyPad.hasMuteKey()) {
/* Inject KEY_SPEAKERPHONE event */
}
else {
/* Inject KEY_VOLUME_DOWN event N times, so that you get the mute effect */
}
}
i am quite new to all this...but i thought i might as well put in my 2 cents worth...
i have been trying to find ways to programatically change the profile settings...
i have found that, while we cannot(yet) change the profile settings, we can change the setting that we are using( change the profile thats in use, i think)- this is something i came across searching for info-though i should give credit to alishaik786 for the code.
public final class LoadingScreen extends MainScreen implements FieldChangeListener
{
public LoadingScreen()
{
createGUI();
}
private void createGUI()
{
try
{
ApplicationManager.getApplicationManager().launch("net_rim_bb_profiles_app");
}
catch (Exception e)
{
//Exception
}
}
public void fieldChanged(Field field, int context)
{
}
}

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.

Resources