How to get Oreo sdCard path? - android-sdcard

I want to delete duplicate files from SD Card. So i need to access SD Card files which give me the full path. eg. /storage/0C08-291C/Android/Docs/file-sample_500kB.rtf
I got the SD Card path for all Android version greater than SDK level 22 but not able to get SD Card access on Android 8 Oreo Version 8.0 and Version 8.1 SDK level 26 and 27.
I am using below method to get SD Card root path:
public static String getExternalStoragePath(Context mContext, boolean is_removable) {
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (is_removable == removable) {
return path;
}
}
} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
This method return null on Android Version 8 even if SD card mounted status is true.
I am checking SD Card status by using below line:
boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
And getting the SD Card path as:
String externalSdCard = getExternalStoragePath(mContext, true);
Once i got the externalSdCard i am calling the below method to GRANT URI PERMISSION to SD Card.
public void takeCardUriPermission(String sdCardRootPath) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
File sdCard = new File(sdCardRootPath);
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
StorageVolume storageVolume = storageManager.getStorageVolume(sdCard);
Intent intent = null;
if (storageVolume != null) {
intent = storageVolume.createAccessIntent(null);
}
try {
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
}
To call the takeCardUriPermission(String sdCardRootPath) method i required SD Card root path. and my question is this "How to get root path of SD Card on Android 8 Oreo"

https://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()
Environment.getExternalStorageDirectory()
Note: From Android Q on this method is deprecated.

#blackapps Below is my code to get the sd card root path.
Activity:
String externalSdCard = getExternalStoragePath(mContext, true);
... here externalSdCard, i am getting null for Android 8 Oreo SDK level 26 and 27. Other SDK level >=22 working well.
Method:
public static String getExternalStoragePath(Context mContext, boolean is_removable) {
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (is_removable == removable) {
return path;
}
}
} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}

Related

PackageInstaller does not work on MIUI optimization mode

I created a test application for installing apk files. PackageInstaller was used for this. The app works well. However, for Xiaomi in BroadcastReceiver I get the "INSTALL_FAILED_INTERNAL_ERROR: Permission Denied" error. But if you enable developer mode and disable MIUI optimization, then the application also successfully installs packages. I can't get users of my application to force them to turn off the optimization mode, how can I deal with this? Tested on MIUI 11 version
You can detect whether user has MIUI and optimization mode enabled and display a message which will force user to disable it. Use these utility methods (it's a part of Split APKs Installer source code): https://github.com/Aefyr/SAI/blob/master/app/src/main/java/com/aefyr/sai/utils/MiuiUtils.java
It seems as though MIUI 20.2.20 solves this incompatibility. solru's answer checks for this.
In case the GitHub link stops working:
public static boolean isMiui() {
return !TextUtils.isEmpty(Utils.getSystemProperty("ro.miui.ui.version.name"));
}
public static String getMiuiVersionName() {
String versionName = Utils.getSystemProperty("ro.miui.ui.version.name");
return !TextUtils.isEmpty(versionName) ? versionName : "???";
}
public static int getMiuiVersionCode() {
try {
return Integer.parseInt(Objects.requireNonNull(Utils.getSystemProperty("ro.miui.ui.version.code")));
} catch (Exception e) {
return -1;
}
}
public static String getActualMiuiVersion() {
return Build.VERSION.INCREMENTAL;
}
private static int[] parseVersionIntoParts(String version) {
try {
String[] versionParts = version.split("\\.");
int[] intVersionParts = new int[versionParts.length];
for (int i = 0; i < versionParts.length; i++)
intVersionParts[i] = Integer.parseInt(versionParts[i]);
return intVersionParts;
} catch (Exception e) {
return new int[]{-1};
}
}
/**
* #return 0 if versions are equal, values less than 0 if ver1 is lower than ver2, value more than 0 if ver1 is higher than ver2
*/
private static int compareVersions(String version1, String version2) {
if (version1.equals(version2))
return 0;
int[] version1Parts = parseVersionIntoParts(version1);
int[] version2Parts = parseVersionIntoParts(version2);
for (int i = 0; i < version2Parts.length; i++) {
if (i >= version1Parts.length)
return -1;
if (version1Parts[i] < version2Parts[i])
return -1;
if (version1Parts[i] > version2Parts[i])
return 1;
}
return 1;
}
public static boolean isActualMiuiVersionAtLeast(String targetVer) {
return compareVersions(getActualMiuiVersion(), targetVer) >= 0;
}
#SuppressLint("PrivateApi")
public static boolean isMiuiOptimizationDisabled() {
if ("0".equals(Utils.getSystemProperty("persist.sys.miui_optimization")))
return true;
try {
return (boolean) Class.forName("android.miui.AppOpsUtils")
.getDeclaredMethod("isXOptMode")
.invoke(null);
} catch (Exception e) {
return false;
}
}
public static boolean isFixedMiui() {
return isActualMiuiVersionAtLeast("20.2.20") || isMiuiOptimizationDisabled();
}
Ultimately the functions you're looking for are isMiui and isMiuiFixed.

Detect voice by audio recorder in android studio

Well, I would like to implement a function, such when the application starts, the recorder will start to recording, and when the user keeps silence there is nothing going to happen until the user speaks. Then, it will save the PCM file of user's voice and then stop recording.
Voice Detection in Android Application
Above is the question I have found similar as mine, but the answer of this link can not work. And I don't know how to modify it, since I don't understand the concept of the code.
Please help me~
Well, I solved my problem, here is my solution.
I modified the code came from this url:
Voice Detection in Android Application
private static final String TAG = "MainActivity";
private static int RECORDER_SAMPLERATE = 44100;
private static int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private Button btn, btn_convert, btn_play;
private TextView txv;
boolean isRecording = false;
private File file;
private AudioRecord audioRecord;
int bufferSizeInBytes = 0;
Context context = MainActivity.this;
// path
final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/final.pcm" ;
final String outpath = path.replace(".pcm", ".wav");
public void autoRecording(){
// Get the minimum buffer size required for the successful creation of an AudioRecord object.
bufferSizeInBytes = AudioRecord.getMinBufferSize( RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING
);
// Initialize Audio Recorder.
AudioRecord audioRecorder = new AudioRecord( MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING,
bufferSizeInBytes
);
// Start Recording.
txv.setText("Ing");
audioRecorder.startRecording();
isRecording = true;
// for auto stop
int numberOfReadBytes = 0;
byte audioBuffer[] = new byte[bufferSizeInBytes];
boolean recording = false;
float tempFloatBuffer[] = new float[3];
int tempIndex = 0;
// create file
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/final.pcm");
Log.d(TAG, "recording: file path:" + file.toString());
if (file.exists()){
Log.d(TAG,"file exist, delete file");
file.delete();
}
try {
Log.d(TAG,"file created");
file.createNewFile();
} catch (IOException e) {
Log.d(TAG,"didn't create the file:" + e.getMessage());
throw new IllegalStateException("did not create file:" + file.toString());
}
// initiate media scan and put the new things into the path array to
// make the scanner aware of the location and the files you want to see
MediaScannerConnection.scanFile(context, new String[] {file.toString()}, null, null);
// output stream
OutputStream os = null;
DataOutputStream dos = null;
try {
os = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// While data come from microphone.
while( true )
{
float totalAbsValue = 0.0f;
short sample = 0;
numberOfReadBytes = audioRecorder.read( audioBuffer, 0, bufferSizeInBytes );
// Analyze Sound.
for( int i=0; i<bufferSizeInBytes; i+=2 )
{
sample = (short)( (audioBuffer[i]) | audioBuffer[i + 1] << 8 );
totalAbsValue += (float)Math.abs( sample ) / ((float)numberOfReadBytes/(float)2);
}
// read in file
for (int i = 0; i < numberOfReadBytes; i++) {
try {
dos.writeByte(audioBuffer[i]);
} catch (IOException e) {
e.printStackTrace();
}
}
// Analyze temp buffer.
tempFloatBuffer[tempIndex%3] = totalAbsValue;
float temp = 0.0f;
for( int i=0; i<3; ++i )
temp += tempFloatBuffer[i];
if( (temp >=0 && temp <= 2100) && recording == false ) // the best number for close to device: 3000
{ // the best number for a little bit distance : 2100
Log.i("TAG", "1");
tempIndex++;
continue;
}
if( temp > 2100 && recording == false )
{
Log.i("TAG", "2");
recording = true;
}
if( (temp >= 0 && temp <= 2100) && recording == true )
{
Log.i("TAG", "final run");
//isRecording = false;
txv.setText("Stop Record.");
//*/
tempIndex++;
audioRecorder.stop();
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
The function of this function:
if you call this function, the recorder will start recording, and once you make sound(Notify if there are some noise it will stop too.) it will stop recording and save into file(pcm format).

how to send data to be printed via bluetooth J2ME

can someone please help. i am trying to send data to a thermal printer using bluetooth. i understand how to discover the devices but not able to connect or know how to send the stream of data to be printed. what do I use here ? there is OBEX and RFComm. which one is appropriate. and can you plz share a sample of code to show how to do it, it would be much appreciated.
Below is a sample code that i have found which uses OBEX to search for near by devices and its actually for image transferring. can you plz point out to me the part that are important and how to change this in order to send a stream of Data rather than picture... plz plz help
public class BluetoothImageSender extends MIDlet implements CommandListener{
public Display display;
public Form discoveryForm;
public Form readyToConnectForm;
public Form dataViewForm;
public ImageItem mainImageItem;
public Image mainImage;
public Image bt_logo;
public TextField addressTextField;
public TextField subjectTextField;
public TextField messageTextField;
public Command selectCommand;
public Command exitCommand;
public Command connectCommand;
public List devicesList;
public Thread btUtility;
public String btConnectionURL;
public boolean readData = false;
public long startTime = 0;
public long endTime = 0;
public BluetoothImageSender() {
startTime = System.currentTimeMillis();
display = Display.getDisplay(this);
discoveryForm = new Form("Image Sender");
try{
mainImage = Image.createImage("/btlogo.png");
bt_logo = Image.createImage("/btlogo.png");
} catch (java.io.IOException e){
e.printStackTrace();
}
mainImageItem = new ImageItem("Bluetooth Image Sender", mainImage, Item.LAYOUT_CENTER, "");
discoveryForm.append(mainImageItem);
discoveryForm.append("\nThis application will scan the area for Bluetooth devices and determine if any are offering OBEX services.\n\n");
/// discoveryForm initialization
exitCommand = new Command("Exit", Command.EXIT, 1);
discoveryForm.addCommand(exitCommand);
discoveryForm.setCommandListener(this);
/// devicesList initialization
devicesList = new List("Select a Bluetooth Device", Choice.IMPLICIT, new String[0], new Image[0]);
selectCommand = new Command("Select", Command.ITEM, 1);
devicesList.addCommand(selectCommand);
devicesList.setCommandListener(this);
devicesList.setSelectedFlags(new boolean[0]);
/// readyToConnectForm initialization
readyToConnectForm = new Form("Ready to Connect");
readyToConnectForm.append("The selected Bluetooth device is currently offering a valid OPP service and is ready to connect. Please click on the 'Connect' button to connect and send the data.");
connectCommand = new Command("Connect", Command.ITEM, 1);
readyToConnectForm.addCommand(connectCommand);
readyToConnectForm.setCommandListener(this);
/// dataViewForm initialization
dataViewForm = new Form("File Sending Progress");
dataViewForm.append("Below is the status of the file sending process:\n\n");
dataViewForm.addCommand(exitCommand);
dataViewForm.setCommandListener(this);
}
public void commandAction(Command command, Displayable d) {
if(command == selectCommand) {
btUtility.start();
}
if(command == exitCommand ) {
readData = false;
destroyApp(true);
}
if(command == connectCommand ) {
Thread filePusherThread = new FilePusher();
filePusherThread.start();
display.setCurrent(dataViewForm);
}
}
public void startApp() {
display.setCurrent(discoveryForm);
btUtility = new BTUtility();
}
public void pauseApp() {
}
public void destroyApp(boolean b) {
notifyDestroyed();
}
////////////////
/**
* This is an inner class that is used for finding
* Bluetooth devices in the vicinity.
*/
class BTUtility extends Thread implements DiscoveryListener {
Vector remoteDevices = new Vector();
Vector deviceNames = new Vector();
DiscoveryAgent discoveryAgent;
// obviously, 0x1105 is the UUID for
// the Object Push Profile
UUID[] uuidSet = {new UUID(0x1105) };
// 0x0100 is the attribute for the service name element
// in the service record
int[] attrSet = {0x0100};
public BTUtility() {
try {
LocalDevice localDevice = LocalDevice.getLocalDevice();
discoveryAgent = localDevice.getDiscoveryAgent();
discoveryForm.append(" Searching for Bluetooth devices in the vicinity...\n");
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
} catch(Exception e) {
e.printStackTrace();
}
}
public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass cod) {
try{
discoveryForm.append("found: " + remoteDevice.getFriendlyName(true));
} catch(Exception e){
discoveryForm.append("found: " + remoteDevice.getBluetoothAddress());
} finally{
remoteDevices.addElement(remoteDevice);
}
}
public void inquiryCompleted(int discType) {
if (remoteDevices.size() > 0) {
// the discovery process was a success
// so out them in a List and display it to the user
for (int i=0; i<remoteDevices.size(); i++){
try{
devicesList.append(((RemoteDevice)remoteDevices.elementAt(i)).getFriendlyName(true), bt_logo);
} catch (Exception e){
devicesList.append(((RemoteDevice)remoteDevices.elementAt(i)).getBluetoothAddress(), bt_logo);
}
}
display.setCurrent(devicesList);
} else {
// handle this
}
}
public void run(){
try {
RemoteDevice remoteDevice = (RemoteDevice)remoteDevices.elementAt(devicesList.getSelectedIndex());
discoveryAgent.searchServices(attrSet, uuidSet, remoteDevice , this);
} catch(Exception e) {
e.printStackTrace();
}
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord){
for(int i = 0; i < servRecord.length; i++) {
DataElement serviceNameElement = servRecord[i].getAttributeValue(0x0100);
String _serviceName = (String)serviceNameElement.getValue();
String serviceName = _serviceName.trim();
btConnectionURL = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
System.out.println(btConnectionURL);
}
display.setCurrent(readyToConnectForm);
readyToConnectForm.append("\n\nNote: the connection URL is: " + btConnectionURL);
}
public void serviceSearchCompleted(int transID, int respCode) {
if (respCode == DiscoveryListener.SERVICE_SEARCH_COMPLETED) {
// the service search process was successful
} else {
// the service search process has failed
}
}
}
////////////////
/**
* FilePusher is an inner class that
* now gets the byte[] named file
* to read the bytes of the file, and
* then opens a connection to a remote
* Bluetooth device to send the file.
*/
class FilePusher extends Thread{
FileConnection fileConn = null;
String file_url = "/loginscreen.png";
byte[] file = null;
String file_name = "loginscreen.png";
String mime_type = "image/png";
// this is the connection object to be used for
// bluetooth i/o
Connection connection = null;
public FilePusher(){
}
public void run(){
try{
InputStream is = this.getClass().getResourceAsStream(file_url);
ByteArrayOutputStream os = new ByteArrayOutputStream();
// now read the file in into the byte[]
int singleByte = 0;
while(singleByte != -1){
singleByte = is.read();
os.write(singleByte);
}
System.out.println("file size: " + os.size());
file = new byte[os.size()];
file = os.toByteArray();
dataViewForm.append("File name: " + file_url);
dataViewForm.append("File size: " + file.length + " bytes");
is.close();
os.close();
} catch (Exception e){
e.printStackTrace();
System.out.println("Error processing the file");
}
try{
connection = Connector.open(btConnectionURL);
// connection obtained
// create a session and a headerset objects
ClientSession cs = (ClientSession)connection;
HeaderSet hs = cs.createHeaderSet();
// establish the session
cs.connect(hs);
hs.setHeader(HeaderSet.NAME, file_name);
hs.setHeader(HeaderSet.TYPE, mime_type); // be sure to note that this should be configurable
hs.setHeader(HeaderSet.LENGTH, new Long(file.length));
Operation putOperation = cs.put(hs);
OutputStream outputStream = putOperation.openOutputStream();
outputStream.write(file);
// file push complete
outputStream.close();
putOperation.close();
cs.disconnect(null);
connection.close();
dataViewForm.append("Operation complete. File transferred");
endTime = System.currentTimeMillis();
long diff = (endTime - startTime)/1000;
System.out.println("Time to transfer file: " + diff);
dataViewForm.append("Time to transfer file: " + diff);
} catch (Exception e){
System.out.println("Error sending the file");
System.out.println(e);
e.printStackTrace();
}
}
}
}

text assigned to String attribute does not store properly

I have assigned a text from a txt file to three attributes, but whenever I call any of those attributes with a Get Method to another class, the value displayed is "null".
Furthermore, I have confirmed that these values are displayed in the method leerArchivo (whenever I use a println for m_linea1-2-3).
Please Help.
public class ArchivoCasillas
{
String m_linea1;
String m_linea2;
String m_linea3;
public void crearArchivo()
{
try
{
FileWriter fw = new FileWriter("ReglasDelTablero.txt");
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(fw);
bw.write("<7,0> , <0,0>");
bw.newLine();
bw.write("<4,1> , <7,2> | <2,7> , <5,5> | <1,2> , <7,4> | <0,4> , <2,5>");
bw.newLine();
bw.write("<7,7> , <3,6> | <6,4> , <3,5> | <4,0> , <2,1> | <2,4> , <0,3>");
bw.close();
}
catch(IOException e)
{
System.out.println("error");
}
}
public void leerArchivo()
{
String linea;
int i = 1;
try
{
FileReader fr = new FileReader("ReglasDelTablero.txt");
BufferedReader br = new BufferedReader(fr);
Tablero serpientesEscaleras = new Tablero();
while( (linea = br.readLine() ) != null)
{
switch(i)
{
case 1: m_linea1 = linea;
break;
case 2: m_linea2 = linea;
break;
case 3: m_linea3 = linea;
break;
}
i++;
}
br.close();
}
catch(IOException e)
{
}
}
public String getM_linea1()
{
return m_linea1;
}
}
Problem solved. It was a conceptual problem on my part. I created an Object in another class, but I never called the leerArchivo method with that object, therefore, the value of the attributes was null. Leaving an answer in case it's useful for someone in the future, as I didn't get a reply.

SD Card's Free Size

I want to check the free size available on My Device's SD Card. I know FileConnection API. How can I check the free size of the SD Card ?
The idea is to open the cfcard file connection and call availableSize() on it. to get the proper memory card location read it from the System.getProperty(...). In some devices the aforesaid property may fail hence constructing new path from the memory card name system property.
NOTE: In certain devices the hostname must be 'localhost', hence change the return string in getFilehost() appropriately.
PS: Since this is a code snippet certain form / command references may throw null pointer please resolve it accordingly.
Below code with get you the available size in 'BYTES' of the memory card
String memoryCardPath = System.getProperty("fileconn.dir.memorycard");
addToLogs(memoryCardPath);
if (null == memoryCardPath) {
displayAlert(null);
}
nativeHostname(memoryCardPath);
addToLogs(nativeHostname);
String path = buildPath(memoryCardPath.substring(getFilehost().length()));
addToLogs(path);
long availableSize = getAvailableSize(path);
addToLogs(String.valueOf(availableSize)+" Bytes");
if(availableSize == 0L) {
String memoryCardName = System.getProperty("fileconn.dir.memorycard.name");
addToLogs(memoryCardName);
path = buildPath(memoryCardName + "/");
addToLogs(path);
availableSize = getAvailableSize(path);
addToLogs(String.valueOf(availableSize)+" Bytes");
if(availableSize == 0L) {
displayAlert(null);
return;
}
}
displayAlert(String.valueOf(availableSize));
Supporting methods
public String buildPath(String foldername) {
if(null == foldername) {
foldername = "";
}
addToLogs("[BP]"+getFilehost());
addToLogs("[BP]"+foldername);
return new StringBuffer().append(getFilehost()).append(foldername).toString();
}
String nativeHostname = null;
public void nativeHostname(String url) {
String host = url.substring("file://".length());
addToLogs("[NH]"+host);
int index = host.indexOf('/');
addToLogs("[NH]"+String.valueOf(index));
if(index > 0) {
nativeHostname = host.substring(0, index);
} else {
nativeHostname = "/";
}
addToLogs("[NH]"+nativeHostname);
}
public boolean tryLocalhost = false;
public String getFilehost() {
final StringBuffer buf = new StringBuffer().append("file://");
if (null != nativeHostname && nativeHostname.length() > 0) {
buf.append(nativeHostname);
}
addToLogs("[GFH] "+buf.toString());
return buf.toString();
}
public long getAvailableSize(String path) {
FileConnection fcon = null;
try {
fcon = (FileConnection) Connector.open(path, Connector.READ);
if(null != fcon && fcon.exists()) {
return fcon.availableSize();
} else {
return 0L;
}
} catch (IOException ex) {
ex.printStackTrace();
addToLogs("[GAS]"+"ERROR : "+ex.getMessage());
return 0L;
} finally {
try {
fcon.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void displayAlert(String text) {
Alert alert = new Alert(
null == text ? "Warning" : "Info",
null == text ? "Memory card not available" : text,
null,
null == text ? AlertType.WARNING : AlertType.INFO);
alert.setTimeout(Alert.FOREVER);
Display.getDisplay(this).setCurrent(alert, Display.getDisplay(this).getCurrent());
}
public void addToLogs(String log) {
log = null == log ? "null" : log;
getFormLogs().append(new StringItem("", log+"\n"));
}

Resources