How to clear cache on a specific activity? - java

I built an android application on the android studio to get the feedback of customers, and at the beginning of each activity, I put a voice over.. When the customer finishes the task, the application returns to the first screen (activity 1).
I want to clear the cache of the application when it arrives at the last activity to avoid cache problems (lack of sound..etc)
Thanks a lot

to delete cache of your own application then simply delete your cache directory
public static void deleteCache(Context context) {
try {
File dir = context.getCacheDir();
deleteDir(dir);
} catch (Exception e) { e.printStackTrace();}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
return dir.delete();
} else if(dir!= null && dir.isFile()) {
return dir.delete();
} else {
return false;
}
}
and it won't clear your shared preference.
Thank you....

Related

mainactivity.java changed to a folder containing AppErrorResult

I am an Android beginner and I was working on my first project, which is a calculator for fractions. The app had an error which I was unable to fix and so I got frustrated and I quit (I didn't delete or do anything with the files tho). Around 3-4 days later (today) I suddenly got the solution. I opened up Android Studio, just to see that my mainactivity's icon is changed and it has become a kind of folder, which contains the file AppErrorResult. Here's a screenshot:
Here's AppErrorResult:
package com.android.server.am;
final class AppErrorResult {
public void set(int res) {
synchronized (this) {
mHasResult = true;
mResult = res;
notifyAll();
}
}
public int get() {
synchronized (this) {
while (!mHasResult) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mResult;
}
boolean mHasResult = false;
int mResult;
}

BluetoothGatt.writeCharacteristic return false half the time

Actually I make an update through Bluetooth. In first time I erase the memory bank and then I write an hexa File on it.
But half the time an update will don't work correctly, for every data I transfer the first writeCharacteristic will return false.
It happen on an entire update half the time.
I try in debug mode but the method never return false in that case, of course it's probably a delay problem, but I can't increase the time.
This is my code for send my data :
public void sendTX(final byte[] sMessage) {
BluetoothGattService service = mBluetoothGatt.getService(UUID_SERVICE_SERIAL);
if (service != null && sMessage != null) {
Log.d(TAG,"sMessage : " + sMessage);
final BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID_TX);
if (characteristic != null) {
Thread thread = new Thread() {
public void run() {
if (sMessage.length > 20) {
for (int i = 0; i < sMessage.length; i += 20) {
byte[] byteArraySplit = Arrays.copyOfRange(sMessage, i, i + 20 < sMessage.length ? i + 20 : sMessage.length);
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
characteristic.setValue(byteArraySplit);
while(!mBluetoothGatt.writeCharacteristic(characteristic)) {
try {
TimeUnit.MILLISECONDS.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} else {
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
characteristic.setValue(sMessage);
while(!mBluetoothGatt.writeCharacteristic(characteristic)){
try {
TimeUnit.MILLISECONDS.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
thread.start();
} else {
Log.d(TAG, "UUID TX null");
}
} else {
Log.d(TAG, "Service BLE null");
}
}
And this is the code of the native writeCharacteristic method :
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
&& (characteristic.getProperties() &
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;
if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;
BluetoothGattService service = characteristic.getService();
if (service == null) return false;
BluetoothDevice device = service.getDevice();
if (device == null) return false;
synchronized(mDeviceBusy) {
if (mDeviceBusy) return false;
mDeviceBusy = true;
}
try {
mService.writeCharacteristic(mClientIf, device.getAddress(),
characteristic.getInstanceId(), characteristic.getWriteType(),
AUTHENTICATION_NONE, characteristic.getValue());
} catch (RemoteException e) {
Log.e(TAG,"",e);
mDeviceBusy = false;
return false;
}
return true;
}
Never use timeouts to try to workaround this issue. The proper way is to wait for the callback and then perform the next request. See Android BLE BluetoothGatt.writeDescriptor() return sometimes false.

Programmatically retrieve permissions from manifest.xml in android

I have to programmatically retrieve permissions from the manifest.xml of an android application and I don't know how to do it.
I read the post here but I am not entirely satisfied by the answers.
I guess there should be a class in the android API which would allow to retrieve information from the manifest.
Thank you.
You can get an application's requested permissions (they may not be granted) using PackageManager:
PackageInfo info = getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] permissions = info.requestedPermissions;//This array contains the requested permissions.
I have used this in a utility method to check if the expected permission is declared:
//for example, permission can be "android.permission.WRITE_EXTERNAL_STORAGE"
public boolean hasPermission(String permission)
{
try {
PackageInfo info = getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
if (info.requestedPermissions != null) {
for (String p : info.requestedPermissions) {
if (p.equals(permission)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
Here's a useful utility method that does just that (in both Java & Kotlin).
Java
public static String[] retrievePermissions(Context context) {
final var pkgName = context.getPackageName();
try {
return context
.getPackageManager()
.getPackageInfo(pkgName, PackageManager.GET_PERMISSIONS)
.requestedPermissions;
} catch (PackageManager.NameNotFoundException e) {
return new String[0];
// Better to throw a custom exception since this should never happen unless the API has changed somehow.
}
}
Kotlin
fun retrievePermissions(context: Context): Array<String> {
val pkgName = context.getPackageName()
try {
return context
.packageManager
.getPackageInfo(pkgName, PackageManager.GET_PERMISSIONS)
.requestedPermissions
} catch (e: PackageManager.NameNotFoundException) {
return emptyArray<String>()
// Better to throw a custom exception since this should never happen unless the API has changed somehow.
}
}
You can get a working class from this gist.
Use this:
public static String getListOfPermissions(final Context context)
{
String _permissions = "";
try
{
final AssetManager _am = context.createPackageContext(context.getPackageName(), 0).getAssets();
final XmlResourceParser _xmlParser = _am.openXmlResourceParser(0, "AndroidManifest.xml");
int _eventType = _xmlParser.getEventType();
while (_eventType != XmlPullParser.END_DOCUMENT)
{
if ((_eventType == XmlPullParser.START_TAG) && "uses-permission".equals(_xmlParser.getName()))
{
for (byte i = 0; i < _xmlParser.getAttributeCount(); i ++)
{
if (_xmlParser.getAttributeName(i).equals("name"))
{
_permissions += _xmlParser.getAttributeValue(i) + "\n";
}
}
}
_eventType = _xmlParser.nextToken();
}
_xmlParser.close(); // Pervents memory leak.
}
catch (final XmlPullParserException exception)
{
exception.printStackTrace();
}
catch (final PackageManager.NameNotFoundException exception)
{
exception.printStackTrace();
}
catch (final IOException exception)
{
exception.printStackTrace();
}
return _permissions;
}
// Test: Log.wtf("test", getListOfPermissions(getApplicationContext()));
If anyone is looking for a short Kotlin Version
fun Manifest.getDeclaredPermissions(context: Context): Array<String> {
return context.packageManager.getPackageInfo(context.packageName, PackageManager.GET_PERMISSIONS).requestedPermissions
}
I have a simple C# code, "using System.Xml"
private void ShowPermissions()
{
XmlDocument doc = new XmlDocument();
doc.Load("c:\\manifest.xml");
XmlNodeList nodeList = doc.GetElementsByTagName("uses-permission");
foreach(XmlNode node in nodeList)
{
XmlAttributeCollection Attr = node.Attributes;
string Permission=Attr["android:permission"].Value;
MessageBox.Show(Permission);
}
}

Emma instrumenting classes incorrectly

From working with EMMA I have noticed that it fails to instrument correctly causing the class to become mangled. Below is a simple example highlighting this issue.
public void showProblem() {
try {
for (int i = 0; i > 10; i++) {
System.out.println(i);
}
} catch (final Throwable e) {
System.err.println(e);
}
}
Instrumented class
public void showProblem()
{
boolean[][] tmp3_0 = $VRc; if (tmp3_0 == null) tmp3_0; boolean[] arrayOfBoolean = $VRi()[1]; int i = 0; arrayOfBoolean[0] = true; tmpTernaryOp = tmp3_0;
try
{
do
{
Throwable e;
System.out.println(e);
e++; arrayOfBoolean[1] = true; arrayOfBoolean[2] = true; } while (e > 10); arrayOfBoolean[3] = true;
}
catch (Throwable localThrowable1)
{
System.err.println(localThrowable1); arrayOfBoolean[4] = true;
}
arrayOfBoolean[5] = true;
}
Notice that it is attempting to increment e of type Throwable and using this within the while loop.
I have found that by moving the try catch logic within the for loop it resolves this. As highlighted in the below code.
public void showProblem() {
for (int i = 0; i > 10; i++) {
try {
System.out.println(i);
} catch (final Throwable e) {
System.err.println(e);
}
}
}
Instrumented class
public void showProblem()
{
boolean[][] tmp3_0 = $VRc; if (tmp3_0 == null) tmp3_0; boolean[] arrayOfBoolean = $VRi()[1]; int i = 0;
Throwable e;
arrayOfBoolean[0] = true; tmpTernaryOp = tmp3_0;
do {
try { System.out.println(i); arrayOfBoolean[1] = true;
} catch (Throwable localThrowable1) {
System.err.println(localThrowable1); arrayOfBoolean[2] = true;
}
i++; arrayOfBoolean[3] = true; arrayOfBoolean[4] = true; } while (i > 10);
arrayOfBoolean[5] = true;
}
Has anyone else experienced these issues?
Setup
Windows 7 64
Java 1.6.0_24 64-bit
Emma v2.0, build 5312
Solution
So it turned out that the problem was to do with the debug information that eclipse was building into the classes. This was observed when using the Android generated ant scripts to execute javac and similarly caused the problem. Disabling this enabled EMMA to successfully process the class files.
I hope this information will help others.
I have tested under Windows XP with Java JRE 1.6.0_35 and EMMA 2.0.5312 without any problems. For me the decompiled code (using JAD) looks like this:
public void showProblem()
{
boolean aflag[] = ($VRc != null ? $VRc : $VRi())[2];
try
{
int i = 0;
aflag[0] = true;
do
{
aflag[2] = true;
if (i > 10)
{
System.out.println(i);
i++;
aflag[1] = true;
} else
{
break;
}
} while (true);
aflag[3] = true;
}
catch (Throwable throwable)
{
System.err.println(throwable);
aflag[4] = true;
}
aflag[5] = true;
}
P.S.: I think in your code sample you actually wanted to use i < 10 in the for loop, not i > 10, didn't you? ;-) Anyway, I used your code just as to make sure to reproduce your situation.

Refactoring else-if operators with different extensions? [duplicate]

This question already has answers here:
Modifying if-else to strategy pattern
(2 answers)
Closed 9 years ago.
I want to know how we better way refctoring this part of code with else-if operators. When is performed eguals check with different extentions?
Code:
private void findFiles(String path) {
try {
File root = new File(path);
File[] list = root.listFiles();
for (File currentFile : list) {
if (currentFile.isDirectory()) {
findFiles(currentFile.getAbsolutePath());
} else {
if (currentFile.getName().toLowerCase().endsWith((".txt"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".pdf"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".doc"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".docx"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".html"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".htm"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".xml"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".djvu"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".djv"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".rar"))) {
queue.put(currentFile);
} else if (currentFile.getName().toLowerCase()
.endsWith((".rtf"))) {
queue.put(currentFile);
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Questions:
How better way to refactoring code? Make it simpler for
understanding.
Can we use some another way to check extentions
variants?
Thanks,
Nazar.
You can replace your whole list of checking extensions with this:
// outside the loop (or even method):
Set<String> extensions = new HashSet<>(Arrays.asList(".txt", ".pdf", ".doc",
".docx", ".html", ".htm", ".xml", ".djvu", ".rar", ".rtf"));
// in the loop:
String fileName = currentFile.getName().toLowerCase();
if (extensions.contains(fileName.substring(fileName.lastIndexOf(".")))) {
queue.put(currentFile);
}
You could use a regex:
String s = currentFile.getName().toLowerCase();
if (s.matches("^.+?\\.(txt|pdf|doc|docx|html|htm|xml|djvu|rar|rtf)$")) {
queue.put(currentFile);
}
That assumes that the action to be taken is the same for all extensions.
In details:
^ beginning of string
.+ one or more characters
? non greedy -> don't consume characters that match the rest of the regex
\\. a period
(pdf|doc) match pdf or doc
$ the end of the string
The best solution would be to refactor this to the STRATEGY Pattern, as seen here:
I would create a getExtension() method, which returns the extension of the file, and a final set of accepted extensions:
private static final Set<String> ACCEPTED_EXTENSIONS =
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(".txt", ".doc", ...));
private String getExtension(File f) {
// TODO return the extension of the file
}
The code would then be redueced to:
private void findFiles(String path) {
try {
File root = new File(path);
File[] list = root.listFiles();
for (File currentFile : list) {
if (currentFile.isDirectory()) {
findFiles(currentFile.getAbsolutePath());
}
else if (ACCEPTED_EXTENSIONS.contains(getExtension(currentFile))) {
queue.put(currentFile);
}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
Or even better, I would create a FileFilter which only accepts directories and files with one of the accepted extensions (using the same set and getExtension() method), and would use root.listFiles(fileFilter).
Create a method
public boolean isPermissibleFileType(String fileName){
String[] fileTypes = {".pdf",".doc",".docx",".html",".htm",".xml",".djvu",".djv",".rar",".rtf"};
return Arrays.asList(fileTypes).contains(fileName.substring(fileName.lastIndexOf('.')).toLowerCase());
}
Use Method in Loop
private void findFiles(String path) {
try {
File root = new File(path);
File[] list = root.listFiles();
for (File currentFile : list) {
if (currentFile.isDirectory()) {
findFiles(currentFile.getAbsolutePath());
} else {
if(isPermissibleFileType(currentFile.getName()){
queue.put(currentFile);
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You can extract the extension checks into some helper method using class FileNameFilter. And then for recursion you can use your original finder method.

Categories

Resources