Android List filter - android

I have a List of File object I want to filter according to some rules like typology (audio, video, photo) or capture date/time, or Exif informations (in case of photos). I can do it with some for cicles for example.
There's a smart way to do it? I read somewhere that the solution probably is to use Predicates from Google Guava, but I can't understand how it works. Any suggestion? Thanks

Using Guava Predicates you would do something along the lines of
import java.io.File;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.io.Files;
public class FileFiltering {
public static void main(String[] args) {
List<File> files = getFiles();
Collection<File> audioFiles = Collections2.filter(files,
new AudioPredicate());
Collection<File> videoFiles = Collections2.filter(files,
new VideoPredicate());
}
private static List<File> getFiles() {
// TODO Auto-generated method stub
return null;
}
}
class AudioPredicate implements Predicate<File> {
#Override
public boolean apply(#Nullable File file) {
return Files.getFileExtension(file.getName()).equalsIgnoreCase("mp3");
}
}
class VideoPredicate implements Predicate<File> {
#Override
public boolean apply(#Nullable File file) {
return Files.getFileExtension(file.getName()).equalsIgnoreCase("mkv");
}
}
In the apply method(s) you will need to write code that will return true for the kind of file you want.

Related

Android ArraySet in unit tests is not mocked

When using android.util.ArraySet in code, I cannot test the classes using it in my non-android test classes, because it would throw an exception:
java.lang.RuntimeException: Method add in android.util.ArraySet not mocked. See http://g.co/androidstudio/not-mocked for details.
The link says:
This is to make sure your unit tests only test your code and do not depend on any particular behaviour of the Android platform (that you have not explicitly mocked e.g. using Mockito)
How can I unit test code using ArraySet? I would say somehow mocking (Mockito, PowerMock) it by somehow "replacing it with a HashSet" could be promising:
Code to be tested:
Set<Bird> birds = new ArraySet<>();
birds.add(currentBird);
Test code:
whenNew(ArraySet.class).withAnyArguments().thenAnswer(new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return new HashSet();
}
});
This gives java.lang.ClassCastException: java.util.HashSet cannot be cast to android.util.ArraySet.
A workaround would be to not to return a HashSet but some MyFakeArraySet extends ArraySet (which internally uses a HashSet), but sadly ArraySet is final. :-(
you should not use android sdk classes in your non-android test classes.
but if you want , you can use something like this :
#Test
public void testArraySet() {
final Set<Bird> fakeBirds = new HashSet<>();
ArraySet<Bird> birds = (ArraySet<Bird>) Mockito.mock(ArraySet.class);
when(birds.add(any(Bird.class))).then(new Answer<Boolean>() {
#Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
Bird param = invocation.getArgument(0);
return fakeBirds.add(param);
}
});
when(birds.contains(any(Bird.class))).then(new Answer<Boolean>() {
#Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
Bird param = invocation.getArgument(0);
return fakeBirds.contains(param);
}
});
Bird bird = new Bird();
birds.add(bird);
assert birds.contains(bird);
}
I've found out that the classes in the test folders seem to have precedence. So I do not have to mock anything. I can just place a package android.util into my test folders and an ArraySet class completely specified by me:
package android.util;
import android.support.annotation.NonNull;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class ArraySet<E extends Object> implements Collection<E>, Set<E> {
private final HashSet<E> HASH_SET;
public ArraySet(int capacity) {
Log.e("ArraySet", "WARNING, using fake array set!");
HASH_SET = new HashSet<>(capacity);
}
#Override
public int size() {
return HASH_SET.size();
}
// Do this with all other methods as well: Chain them into HASH_SET.
}

Error in compiling, <identifier> expected.. Would love to know why is this happening and how I can fix it in the future

package edetect.webiscr.cf.e_bookgeneral;
import android.app.ActivityManager;
public class ApplockHandler {
String appg = "com.example.lock";
ActivityManager.killBackgroundProcesses(String appg);
}
The error results to expected
ActivityManager.killBackgroundProcesses(String appg);
I'm pretty new to java and android.. So sorry for my noobishness
Would appreciate any help :)
You need to put killBackgroundProcess into a function, and only pass in appg without the String datatype in front of it. For example:
package edetect.webiscr.cf.e_bookgeneral;
import android.app.ActivityManager;
public class ApplockHandler {
private final String appg = "com.example.lock";
public ApplockHandler() {}
public void killLock() {
ActivityManager.killBackgroundProcesses(appg);
}
}
Call killBackgroundProcesses from any function. Also you need to get an instance of ActivityManager.
public class ApplockHandler {
public ApplockHandler() {}
public void killLock(String appg) {
ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
am.killBackgroundProcesses(appg);
}
}
Now call this killLock method from anywhere by passing the package name.

Class has no public constructor TestCase(String name) or TestCase() while running my Cucumber scenario

I'm using Green Coffee library to run Cucumber scenarios in my instrumentation tests. I followed example provided by repo step-by-step, but here's the error:
junit.framework.AssertionFailedError: Class pi.survey.features.MembersFeatureTest has no public constructor TestCase(String name) or TestCase()
And when I try to add default constructor to the class like provided here, it says
no default constructor available in
'com.mauriciotogneri.greencoffee.GreenCoffeeTest'
Here's my test's source code:
package pi.survey.features;
import android.support.test.rule.ActivityTestRule;
import com.mauriciotogneri.greencoffee.GreenCoffeeConfig;
import com.mauriciotogneri.greencoffee.GreenCoffeeTest;
import com.mauriciotogneri.greencoffee.Scenario;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.IOException;
import pi.survey.MainActivity;
import pi.survey.steps.memberSteps;
#RunWith(Parameterized.class)
public class MembersFeatureTest extends GreenCoffeeTest {
#Rule
public ActivityTestRule<MainActivity> activity = new ActivityTestRule<>(MainActivity.class);
public MembersFeatureTest(Scenario scenario) {
super(scenario);
}
#Parameterized.Parameters
public static Iterable<Scenario> scenarios() throws IOException {
return new GreenCoffeeConfig()
.withFeatureFromAssets("assets/members.feature")
.scenarios();
}
#Test
public void test() {
start(new memberSteps());
}
}
And my members.feature source:
Feature: Inserting info to server
Scenario: Invalid members
When I introduce an invalid members
And I press the login button
Then I see an error message saying 'Invalid members'
Regarding the questions about the constructors. Due to the fact that tests in GreenCoffee require:
#RunWith(Parameterized.class)
The static method annotated with #Parameters must return a list of something (but not necessarily Scenario). The examples in the documentation simply return a list of scenarios, that's why the constructor must take a single Scenario as a parameter.
However, you can create a class that encapsulates the scenario and other objects that you may need to pass to the constructor. For example, given the following class:
public class TestParameters
{
public final String name;
public final Scenario scenario;
public TestParameters(String name, Scenario scenario)
{
this.name = name;
this.scenario = scenario;
}
}
You can write:
public TestConstructor(TestParameters testParameters)
{
super(testParameters.scenario);
}
#Parameters
public static Iterable<TestParameters> parameters() throws IOException
{
List<TestParameters> testParametersList = new ArrayList<>();
List<Scenario> scenarios = new GreenCoffeeConfig()
.withFeatureFromAssets("...")
.scenarios();
for (Scenario scenario : scenarios)
{
testParametersList.add(new TestParameters(scenario.name(), scenario));
}
return testParametersList;
}
In this way you can receive multiple values (encapsulated in an object) in the test constructor.
Solved problem by just fixing the structure.
code details in this commit

Dispatching Events in ANE

Coding an Air Native Extension:
How do you dispatch an event from the android native code and have the actionscript interface part of the ANE be listening for that event and also hear it?
I have looked everywhere and I can't seem to figure this out.
as3 part
package com.yourpackage
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.StatusEvent;
import flash.external.ExtensionContext;
public class EventCaller extends EventDispatcher
{
private var context:ExtensionContext;
public function EventCaller(target:IEventDispatcher=null)
{
super(target);
if(!context)
context = ExtensionContext.createExtensionContext("com.yourpackage", null);
if(context)
context.addEventListener(StatusEvent.STATUS,statusHandle);
}
// listener function
public function statusHandle(event:StatusEvent):void{
trace(event);
// process event data
}
public function requestEvent():void{
context.call("requestEvent");
}
}
}
java part (just function part)
public class RequestEvent implements FREFunction {
#Override
public FREObject call(FREContext context, FREObject[] args) {
// dispatching event
context.dispatchStatusEventAsync("someCode", "someLevel");
Boolean value = true;
return FREObject.newObject(value);
}
}

Unable to retrieve Google Drive files and folders using new Drive API

I am trying to get a list of Files in a Folder from Google Drive from my Android app but have been unsuccessful so far. I'm using google-api-drive-v1-rev4-java-1.6.0-beta and google-api-client-1.9.0. I'm also building my code similar to calendar-android-sample and tasks-android-sample from the samples at http://code.google.com/p/google-api-java-client/wiki/Android.
I cant seem to find how to use files() to get a list of folders or even the id of the folder I want. The tasks-android-sample uses '#default' in the get() method to get a list of tasks. What would I use in the get method to get a list of folders first, search for my folder, get the id, then get a list of files in that folder?
AsyncLoadDocs.java: (Note: I'm using getFields() just to see if the Get object contains any metadata, which at this point doesn't.)
package com.mysite.myapp.docs;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.Drive.Files.Get;
import com.google.api.services.drive.model.File;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ArrayAdapter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Asynchronously load the docs with a progress dialog.
*
* #author ms
*/
class AsyncLoadDocs extends AsyncTask<Void, Void, List<String>> {
private static final String TAG = "AsyncLoadDocs";
private final GDocsSync gDocsSync;
private final ProgressDialog dialog;
private final Drive entry = null;
private com.google.api.services.drive.Drive service;
AsyncLoadDocs(GDocsSync gDocsSync) {
this.gDocsSync = gDocsSync;
service = gDocsSync.driveClient;
dialog = new ProgressDialog(gDocsSync);
}
#Override
protected void onPreExecute() {
dialog.setMessage("Loading docs...");
dialog.show();
}
#Override
protected List<String> doInBackground(Void... arg0) {
try {
List<String> folderNames = new ArrayList<String>();
Get get = service.files().get("#default").setProjection("FULL");
String fields = get.getFields();
Log.d(TAG, "Fields: " + fields);
return folderNames;
} catch (IOException e) {
gDocsSync.handleGoogleException(e);
return Collections.singletonList(e.getMessage());
} finally {
gDocsSync.onRequestCompleted();
}
}
#Override
protected void onPostExecute(List<String> result) {
dialog.dismiss();
}
}
Any help would be appreciated. Both Calendar and Tasks samples successfully retrieve data from Google using my API key, why doesn't this Drive code?
The Drive API grants access only to two classes of files:
Files that a user has created with a given Drive app
Files that a user opens with a given Drive app
For security reasons, there's no method to list all files in a user Drive account:
https://developers.google.com/drive/apps_overview#granting_file-level_access
For more options in the Android environment, check out these other answers:
Android API for Google Drive?
Google Drive\Docs API for Android

Categories

Resources