Google Glass and SpeechRecognizer class - google-glass

I've been trying to use SpeechRecognizer class on an activity on Google Glass
I run this code on a Motorola Razor and it works well.
I have not been successful doing this on Glass
"no selected voice recognition service" is
the error I get back when
sr.startListening(intent) is called;
I am aware of the activityForResult methods of voice recognition, However I'm looking for something that will run within my Activity, Thanks.
public class MainActivity extends Activity {
SpeechRecognizer sr;
TextView mText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sr = SpeechRecognizer.createSpeechRecognizer(this);
sr.setRecognitionListener(new listener());
mText = (TextView) findViewById(R.id.resultsText);
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,this.getPackageName());
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,5);
sr.startListening(intent);
}
class listener implements RecognitionListener
{
private static final String TAG = "Speech";
public void onReadyForSpeech(Bundle params)
{
Log.d(TAG, "onReadyForSpeech");
}
public void onBeginningOfSpeech()
{
Log.d(TAG, "onBeginningOfSpeech");
}
public void onRmsChanged(float rmsdB)
{
Log.d(TAG, "onRmsChanged");
}
public void onBufferReceived(byte[] buffer)
{
Log.d(TAG, "onBufferReceived");
}
public void onEndOfSpeech()
{
Log.d(TAG, "onEndofSpeech");
}
public void onError(int error)
{
Log.d(TAG, "error " + error);
mText.setText("error " + error);
}
public void onResults(Bundle results)
{
String str = new String();
Log.d(TAG, "onResults " + results);
ArrayList data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
for (int i = 0; i < data.size(); i++)
{
Log.d(TAG, "result " + data.get(i));
str += data.get(i);
}
mText.setText("results: "+String.valueOf(data.size()));
}
public void onPartialResults(Bundle partialResults)
{
Log.d(TAG, "onPartialResults");
}
public void onEvent(int eventType, Bundle params)
{
Log.d(TAG, "onEvent " + eventType);
}
}
}

This use case of SpeechRecognizer is not yet supported; right now, you can only launch an activity using RecognizerIntent to transcribe speech.
Please feel free to follow issue 245, which covers this, on our issue tracker so that you can stay updated as the GDK evolves!

If you are still have this problem, you should use RecognizerIntent.ACTION_RECOGNIZE_SPEECH.
Example implementation is
private static final int SPEECH_REQUEST = 0;
// will show the microphone and lets user speak to capture speech
private void displaySpeechRecognizer() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
startActivityForResult(intent, SPEECH_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
List<String> results = data.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS);
// the first string in the results list is considered the best match.
String spokenText = results.get(0);
// Do something with spokenText.
}
super.onActivityResult(requestCode, resultCode, data);
}
You can read more at : https://developers.google.com/glass/develop/gdk/voice?hl=en#starting_speech_recognition and http://developer.android.com/reference/android/speech/RecognizerIntent.html#ACTION_RECOGNIZE_SPEECH

Related

On using swipe refresh in recyclerview my adapter is not getting data when it is refreshing

My Latest fragment
public class Latest extends Fragment {
private RecyclerView recyclerLatest;
private SwipeRefreshLayout swipeRecycler;
private RecyclerView.LayoutManager mLayoutManager;
private List<LatestAdDetails> latestAdDetailsList = new ArrayList<>();
private LatestAdapter latestAdapter;
private LatestAdDetails latestAdDetails,latestAdDetails1;
private JSONObject jsonobject;
private Context context;
private String x;
public Latest() {
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View mainView=inflater.inflate(R.layout.latest_fragment,container,false);
recyclerLatest = (RecyclerView) mainView.findViewById(R.id.recycler_latest);
swipeRecycler= (SwipeRefreshLayout)mainView.findViewById(R.id.swipe_recycler_latest);
mLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerLatest.setLayoutManager(mLayoutManager);
recyclerLatest.setHasFixedSize(true);
context = getContext();
// url for latest add obtaining
UrlConstants.latest_ad_obtained= UrlConstants.latest_ad+ AppController.getString(getActivity().getApplicationContext(),"country_id")+"/"+AppController.getString(getActivity().getApplicationContext(),"city_id");
latestAdapter = new LatestAdapter(latestAdDetailsList);
recyclerLatest.setAdapter(latestAdapter);
latestAdd();
swipeRecycler.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh(){refreshLatestAd();
}
});
return mainView;
}
private void refreshLatestAd() {
UrlConstants.latset_ad_refresh_obtained=UrlConstants.latest_ad_refresh+
AppController.getString(getActivity().getApplicationContext(),"country_id")+"/"+
AppController.getString(getActivity().getApplicationContext(),"city_id")+"/"+
AppController.getString(getActivity().getApplicationContext(),"refresh_ad")+"/"+0;
LatestRefreshHandler latestRefreshHandler = new LatestRefreshHandler("latestRefreshADD");
latestRefreshHandler.executeAsStringRequest(new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("response", response);
JSONArray jsonarray = null;
try {
jsonarray = new JSONArray(response);
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < jsonarray.length(); i++) {
try {
jsonobject = jsonarray.getJSONObject(i);
if (jsonobject.getString("default_photo").isEmpty()) {
x = UrlConstants.default_photo;
} else {
x = jsonobject.getString("default_photo");
}
Log.e("x", x);
latestAdapter.clear();
int Ad_id_refresh = jsonarray.getJSONObject(jsonarray.length()).getInt("id");
AppController.setString(context,"refresh_ad", String.valueOf(Ad_id_refresh));
latestAdDetails = new LatestAdDetails(
jsonobject.getInt("id"),
jsonobject.getInt("cityid"),
jsonobject.getInt("price"),
jsonobject.getInt("type"),
jsonobject.getInt("comments"),
jsonobject.getInt("categoryid"),
jsonobject.getInt("MainCategoryID"),
jsonobject.getInt("created"),
jsonobject.getInt("views"),
jsonobject.getString("title"),
jsonobject.getString("default_photo"),
jsonobject.getString("CityName"),
jsonobject.getString("CategoryName"),
jsonobject.getString("storeid"),
jsonobject.getString("currency"),
jsonobject.getString("description"),
jsonobject.getDouble("Latitude"),
jsonobject.getDouble("Longitude")
);
latestAdDetailsList.add(latestAdDetails);
} catch (JSONException e) {
e.printStackTrace();
}
}
latestAdapter.addAll(latestAdDetailsList);
latestAdapter.notifyDataSetChanged();
recyclerLatest.setAdapter(latestAdapter);
swipeRecycler.setRefreshing(false);
}
}, new BaseRequest.ErrorResponseCallback() {
#Override
public void onError(Exception exception) {
}
});
}
private void latestAdd() {
LatestRequestHandler latestHandler = new LatestRequestHandler("latestADD");
latestHandler.executeAsStringRequest(new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("response", response);
JSONArray jsonarray = null;
try {
jsonarray = new JSONArray(response);
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < jsonarray.length(); i++) {
try {
jsonobject = jsonarray.getJSONObject(i);
if (jsonobject.getString("default_photo").isEmpty()) {
x = UrlConstants.default_photo;
} else {
x = jsonobject.getString("default_photo");
}
Log.e("x", x);
int Ad_id_refresh = jsonarray.getJSONObject(1).getInt("id");
AppController.setString(context,"refresh_ad", String.valueOf(Ad_id_refresh));
latestAdDetails = new LatestAdDetails(
jsonobject.getInt("id"),
jsonobject.getInt("cityid"),
jsonobject.getInt("price"),
jsonobject.getInt("type"),
jsonobject.getInt("comments"),
jsonobject.getInt("categoryid"),
jsonobject.getInt("MainCategoryID"),
jsonobject.getInt("created"),
jsonobject.getInt("views"),
jsonobject.getString("title"),
jsonobject.getString("default_photo"),
jsonobject.getString("CityName"),
jsonobject.getString("CategoryName"),
jsonobject.getString("storeid"),
jsonobject.getString("currency"),
jsonobject.getString("description"),
jsonobject.getDouble("Latitude"),
jsonobject.getDouble("Longitude")
);
latestAdDetailsList.add(latestAdDetails);
} catch (JSONException e) {
e.printStackTrace();
}
}
latestAdapter.notifyDataSetChanged();
}
}, new BaseRequest.ErrorResponseCallback() {
#Override
public void onError(Exception exception) {
}
});
}}
my Adapter class
public class LatestAdapter extends RecyclerView.Adapter<LatestAdapter.MyViewHolder> {
private ImageLoader imageLoader;
private Context context;
private String text;
private List<LatestAdDetails> latestAddDetailsList;
public LatestAdapter(List<LatestAdDetails> latestAddDetailsList) {
this.latestAddDetailsList = latestAddDetailsList;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView txtTitle, txtDescription, txtCityName, txtPrice, txtCategory, txtHour, txtPhotoNo;
private NetworkImageView imgPhoto;
public MyViewHolder(View itemView) {
super(itemView);
txtTitle = (TextView) itemView.findViewById(R.id.txt_title_fad);
txtDescription = (TextView) itemView.findViewById(R.id.description_fad);
txtCityName = (TextView) itemView.findViewById(R.id.city_name_fad);
txtPrice = (TextView) itemView.findViewById(R.id.price_fad);
txtCategory = (TextView) itemView.findViewById(R.id.category_fad);
txtHour = (TextView) itemView.findViewById(R.id.hours_fad);
txtPhotoNo = (TextView) itemView.findViewById(R.id.txt_photo_no_fad);
imgPhoto = (NetworkImageView) itemView.findViewById(R.id.img_photo_lod_fad);
}
}
public void clear() {
latestAddDetailsList.clear();
notifyDataSetChanged();
}// Add a list of items
public void addAll(List<LatestAdDetails> list) {
latestAddDetailsList.addAll(list);
notifyDataSetChanged();
}
#Override
public LatestAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.featured_ad_adapter_layout, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(LatestAdapter.MyViewHolder holder, int position) {
LatestAdDetails latestAddDetails = latestAddDetailsList.get(position);
holder.txtTitle.setText(translate(latestAddDetails.getTitle()));
holder.txtDescription.setText(translate(latestAddDetails.getDescription()));
holder.txtCityName.setText(translate(latestAddDetails.getCityName()));
holder.txtPrice.setText(Integer.toString(latestAddDetails.getPrice()));
holder.txtCategory.setText(translate(latestAddDetails.getCategoryName()));
holder.txtHour.setText(Integer.toString(latestAddDetails.getCreated()));
holder.txtPhotoNo.setText(Integer.toString(0) + " photos ");
try {
imageLoader = VolleyHandler.getImageLoader();
} catch (Exception e) {
e.printStackTrace();
}
holder.imgPhoto.setImageUrl(latestAddDetails.getDefault_photo(), imageLoader);
}
#Override
public int getItemCount() {
Log.e("size", String.valueOf(latestAddDetailsList.size()));
return latestAddDetailsList.size();
}
private String translate(String myString) {
try {
myString = myString.replace("\n", "").replace("\r", "");
byte[] utf8Bytes = myString.getBytes("UTF8");
text = new String(utf8Bytes, "UTF8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return text;
}}
on refreshing adapter size is zero,but getting json correctly,but not adding to adapter,and the recycler view is not showing new data,please help me ,the json is giving 10 datas on every swipe but it is not getting added to recyclerview
It seems like a logical bug :
In method : refreshLatestAd(), Remove these line :
latestAdapter.clear();
latestAdapter.addAll(latestAdDetailsList);
and
recyclerLatest.setAdapter(latestAdapter); // It need not be set again.
Let me know if it helps.
latestAdapter.notifyDataSetChanged() is sufficient to notify the
adapter that the data is changed. Always modify the list
[latestAdDetailsList] which is being set to adapter, this is the sure
shot way to make the changes reflect when you call notifyDataSetChanged.

Async request slow performance

I'm making a web based scoring system for a robotic competition. When a point is scored, I want to refresh the page of everybody watching the game. My code is working "correctly".
My problem is that when I test and I open about 5 to 10 web pages, any other pages that I request are not processed until I close some pages. I think that what's happening is that request.startAsync() is not releasing the thread and it's waiting infinitely.
I've tested on both Jetty 9.2.7.v20150116 and Tomcat7. Both have the same slow behavior.
// Display a game with all it's events
// http://stackoverflow.com/questions/10878243/sse-and-servlet-3-0
#WebServlet(urlPatterns = { "/gameRefresh" }, asyncSupported = true)
public class GameRefreshController extends HttpServlet
{
private static final long serialVersionUID = -6890088129187673292L;
private static AtomicBoolean refreshNeeded = new AtomicBoolean();
private final Queue<AsyncContext> ongoingRequests = new ConcurrentLinkedQueue<>();
private ScheduledExecutorService service;
public static void setRefreshNeeded(boolean value)
{
refreshNeeded.set(value);
}
#Override
public void init(ServletConfig config) throws ServletException
{
final Runnable notifier = new Runnable()
{
#Override
public void run()
{
// Don't refresh if it's not needed.
if(!refreshNeeded.get())
{
return;
}
// This var is set by the backend when an event occurs.
setRefreshNeeded(false);
final Iterator<AsyncContext> iterator = ongoingRequests.iterator();
// not using for : in to allow removing items while iterating
while (iterator.hasNext())
{
AsyncContext asyncContext = iterator.next();
final ServletResponse servletResponse = asyncContext.getResponse();
PrintWriter out;
try
{
out = servletResponse.getWriter();
String toOutput = "data: refresh\n\n";
out.write(toOutput);
out.checkError();
}
catch(IOException exception)
{
// iterator is always removed because we refresh the whole page.
}
finally
{
iterator.remove();
}
}
}
};
service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(notifier, 1, 1, TimeUnit.SECONDS);
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
final AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(0);
asyncContext.addListener(new AsyncListener()
{
#Override
public void onComplete(AsyncEvent event) throws IOException
{
ongoingRequests.remove(asyncContext);
}
#Override
public void onTimeout(AsyncEvent event) throws IOException
{
ongoingRequests.remove(asyncContext);
}
#Override
public void onError(AsyncEvent event) throws IOException
{
ongoingRequests.remove(asyncContext);
}
#Override
public void onStartAsync(AsyncEvent event) throws IOException
{
}
});
ongoingRequests.add(asyncContext);
}
}

Google glass live stream video using RTSP server of Wowza

I'm trying to build a Google glass app that supports live streaming. Am aware that Livestream app is available to do this but i don't think we can integrate it in our application or am i wrong? is there a way to integrate the livestream in our app?
I came across this https://github.com/andermaco/GlassStream open source project which do the same thing using RTSP server of Wowza. As per the instructions i have given the user name/password and updated the url. But while running there is an issue while running the application., i tried to debug it but am not successful. This is the log am getting repeatedly
java.lang.IllegalStateException at android.media.MediaCodec.dequeueOutputBuffer(Native Method)
at net.majorkernelpanic.streaming.rtp.MediaCodecInputStream.read(MediaCodecInputStream.java :75)
at net.majorkernelpanic.streaming.rtp.AACLATMPacketizer.run(AACLATMPacketizer.java:88)
at java.lang.Thread.run(Thread.java:841)
Some of the users have used and are successful, Please share me the source code or let me know if am missing something in setting up the server. Even if there are any other resource for implementing, it would be great.
Thanks in Advance.
This the code I've used to get it working on Google Glass (XE22) using Wowza media server and libstreaming.
I've two classes AppConfig and MyActivity.
AppConfig:
package com.example.GlassApp;
/**
* User: Colin Shewell
* Date: 21/08/14
* Time: 15:30
*/
public class AppConfig {
public static final String STREAM_URL = "rtsp://193.61.148.73:1935/serg/android_test";
//public static final String STREAM_URL = "rtsp://192.168.2.2:1935/serg/android_test";
public static final String PUBLISHER_USERNAME = "";
public static final String PUBLISHER_PASSWORD = "";
}
MyActivity:
package com.example.GlassApp;
/**
* User: Colin Shewell
* Date: 21/08/14
* Time: 15:30
*/
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.majorkernelpanic.streaming.Session;
import net.majorkernelpanic.streaming.SessionBuilder;
import net.majorkernelpanic.streaming.audio.AudioQuality;
import net.majorkernelpanic.streaming.gl.SurfaceView;
import net.majorkernelpanic.streaming.rtsp.RtspClient;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.Window;
import android.view.WindowManager;
import net.majorkernelpanic.streaming.video.VideoQuality;
public class MyActivity extends Activity implements RtspClient.Callback, Session.Callback, SurfaceHolder.Callback {
// log tag
public final static String TAG = MyActivity.class.getSimpleName();
// surfaceview
private static SurfaceView mSurfaceView;
// Rtsp session
private Session mSession;
private static RtspClient mClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
mSurfaceView.getHolder().addCallback(this);
// Initialize RTSP client
initRtspClient();
}
#Override
protected void onResume() {
super.onResume();
toggleStreaming();
}
#Override
protected void onPause(){
super.onPause();
toggleStreaming();
}
private void initRtspClient() {
// Configures the SessionBuilder
mSession = SessionBuilder.getInstance()
.setContext(getApplicationContext())
.setAudioEncoder(SessionBuilder.AUDIO_NONE)
.setVideoEncoder(SessionBuilder.VIDEO_H264)
.setVideoQuality(new VideoQuality(640, 480, 20, 500000)) //only need if you want to change the resolution from default
.setSurfaceView(mSurfaceView).setPreviewOrientation(0)
.setCallback(this).build();
// Configures the RTSP client
mClient = new RtspClient();
mClient.setSession(mSession);
mClient.setCallback(this);
mSurfaceView.setAspectRatioMode(SurfaceView.ASPECT_RATIO_PREVIEW);
String ip, port, path;
// We parse the URI written in the Editext
Pattern uri = Pattern.compile("rtsp://(.+):(\\d+)/(.+)");
Matcher m = uri.matcher(AppConfig.STREAM_URL);
m.find();
ip = m.group(1);
port = m.group(2);
path = m.group(3);
mClient.setCredentials(AppConfig.PUBLISHER_USERNAME,
AppConfig.PUBLISHER_PASSWORD);
mClient.setServerAddress(ip, Integer.parseInt(port));
mClient.setStreamPath("/" + path);
}
private void toggleStreaming() {
if (!mClient.isStreaming()) {
// Start camera preview
mSession.startPreview();
// Start video stream
mClient.startStream();
} else {
// already streaming, stop streaming
// stop camera preview
mSession.stopPreview();
// stop streaming
mClient.stopStream();
}
}
#Override
public void onDestroy() {
super.onDestroy();
mClient.release();
mSession.release();
mSurfaceView.getHolder().removeCallback(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onSessionError(int reason, int streamType, Exception e) {
switch (reason) {
case Session.ERROR_CAMERA_ALREADY_IN_USE:
break;
case Session.ERROR_CAMERA_HAS_NO_FLASH:
break;
case Session.ERROR_INVALID_SURFACE:
break;
case Session.ERROR_STORAGE_NOT_READY:
break;
case Session.ERROR_CONFIGURATION_NOT_SUPPORTED:
break;
case Session.ERROR_OTHER:
break;
}
if (e != null) {
alertError(e.getMessage());
e.printStackTrace();
}
}
private void alertError(final String msg) {
final String error = (msg == null) ? "Unknown error: " : msg;
AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);
builder.setMessage(error).setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
#Override
public void onRtspUpdate(int message, Exception exception) {
switch (message) {
case RtspClient.ERROR_CONNECTION_FAILED:
case RtspClient.ERROR_WRONG_CREDENTIALS:
alertError(exception.getMessage());
exception.printStackTrace();
break;
}
}
#Override
public void onPreviewStarted() {
}
#Override
public void onSessionConfigured() {
}
#Override
public void onSessionStarted() {
}
#Override
public void onSessionStopped() {
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
// #Override
public void onBitrateUpdate(long bitrate) {
}
}
EDIT:
I can confirm that the following video quality settings work:
.setVideoQuality(new VideoQuality(640, 480, 20, 500000))
.setVideoQuality(new VideoQuality(960, 720, 20, 500000))
I'd also like to add that an fps value of over 20 seems to result in the app failing to start.

how to get contacts list from google glass using GDK

I'm implement Google Glass app.
I want to get contacts list from google glass using GDK.
I already tried contacts Api v3 (ContactsService)
but i failed because -
i can't scrolling & tapping(click) pop-up (OK Button) after glass update XE16
-> run to android phone is ok.
i tried
mirror api. device OAuth.... -> no example.. i don't know how...
if you have sample code, As it is also upload. Would you? I'd appreciate that.
here is my code.
public class MainActivity extends Activity
{
private Account[] accounts;
private AccountManager mManager;
private ContactsService mService;
private URL feedUrl;
private final String url = "https://www.google.com/m8/feeds/contacts/default/full";
private final String ACCOUNTS_TYPE = "com.google";
private final String AUTH_TOKEN_TYPE = "cp";
private String mToken;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mManager = AccountManager.get(this);
accounts = mManager.getAccountsByType(ACCOUNTS_TYPE);
Log.d("account", ""+accounts[0]);
mManager.getAuthToken(accounts[0], AUTH_TOKEN_TYPE, null, this, new AccountManagerCallback<Bundle>()
{
public void run(AccountManagerFuture<Bundle> future)
{
try
{
mToken = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);
GetTask task = new GetTask();
task.execute(mToken);
}
catch (OperationCanceledException e)
{
e.printStackTrace();
}
catch (AuthenticatorException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}, null);
}
public void createService(String token) throws IOException, ServiceException
{
mService = new ContactsService("contacts_list");
mService.setUserToken(token);
feedUrl = new URL(url);
ContactFeed resultFeed = (ContactFeed)mService.getFeed(feedUrl, ContactFeed.class);
for (ContactEntry entry : resultFeed.getEntries()) getContacts(entry);
}
private class GetTask extends AsyncTask<String, Void, Void>
{
#Override
protected Void doInBackground(String... params)
{
try
{
String token = "";
if(params != null)
{
for(String s : params) token += s;
}
createService(token);
}
catch (ServiceException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}
public void getContacts(ContactEntry entry) throws ServiceException, IOException
{
if (entry.hasName())
{
Name name = entry.getName();
if (name.hasFullName())
{
String fullName = name.getFullName().getValue();
Log.d("name", fullName);
}
}
else Log.d("name", "no name");
if (entry.hasPhoneNumbers())
{
for (PhoneNumber phone : entry.getPhoneNumbers())
{
String phoneNum = phone.getPhoneNumber();
Log.d("phone", phoneNum);
}
}
else Log.d("phone", "no phone");
}
}

JMockit: Mocking all implementations of an interface

Is it possible to mock all implementations of an interface?
I want to mock the WatchService interface like the following
public class ServiceTest {
#Test
public void callTest(
#Capturing
#Injectable
final WatchService ws
) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
new MockUp<ServiceTest>() {
#Mock(invocations = 1)
public void onChange() {
latch.countDown();
}
};
new NonStrictExpectations() {
{
ws.take();
result = new Delegate() {
WatchKey take(Invocation inv) {
System.out.println("> " + inv.getInvokedInstance());
try {
new File("target/newFile").createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return inv.proceed();
}
};
}
};
final Thread thread = new Thread() {
#Override
public void run() {
final Path target = Paths.get("target");
final FileSystem fs = target.getFileSystem();
try {
try (WatchService watcher = fs.newWatchService()) {
target.register(watcher, ENTRY_CREATE);
while (!Thread.currentThread().isInterrupted()) {
WatchKey take = watcher.take();
onChange();
System.out.println("take " + take);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
assertTrue("", latch.await(5, TimeUnit.SECONDS));
thread.interrupt();
}
private void onChange() {
System.out.println("CHANGE");
}
How can I accomplish that?
You can use the #Capturing annotation on a mock field or mock parameter of the interface type. Below we have a complete example test (minus imports).
public class CapturingAndProceedingTest {
static class WatchKey { String key; WatchKey(String k) {key = k;} }
public interface WatchService { public abstract WatchKey take(); }
static class WatchServiceImpl1 implements WatchService {
#Override public WatchKey take() { return new WatchKey("Abc"); }
}
static class WatchServiceImpl2 implements WatchService {
#Override public WatchKey take() { return new WatchKey("123"); }
}
#Test
public void mockAllImplementationsOfAnInterface(
#Capturing // so that all implementing classes are mocked
#Injectable // so that Invocation#proceed() is supported
final WatchService watchService
) {
final List<WatchService> services = new ArrayList<>();
// Record an expectation that will match all calls to
// WatchService#take(), on any class implementing the interface.
new NonStrictExpectations() {{
watchService.take();
result = new Delegate() {
WatchKey take(Invocation inv) throws IOException {
// Do something here...
WatchService service = inv.getInvokedInstance();
services.add(service);
// ...then proceed to the real implementation.
return inv.proceed();
}
};
}};
// Instantiate and use different implementations of the interface.
WatchServiceImpl1 impl1 = new WatchServiceImpl1();
assertEquals("Abc", impl1.take().key);
WatchServiceImpl2 impl2 = new WatchServiceImpl2();
assertEquals("123", impl2.take().key);
assertEquals(Arrays.asList(impl1, impl2), services);
System.out.println(services);
}
}
See the JMockit Tutorial for more examples.