I want to get swimming data from Samsung Health App but not get any proper solution.
Below is my code.
public class SwimmingReport {
private final HealthDataStore mStore;
private SwimObserver swimObserver;
private static final long ONE_DAY_IN_MILLIS = 24 * 60 * 60 * 1000L;
public SwimmingReport(HealthDataStore store) {
mStore = store;
}
public void start(SwimObserver listener, String strDate, JSONObject jsonObject) {
swimObserver = listener;
HealthDataObserver.addObserver(mStore, HealthConstants.Exercise.HEALTH_DATA_TYPE, new HealthDataObserver(null) {
#Override
public void onChange(String s) {
readTodaySwimData(strDate,jsonObject);
}
});
readTodaySwimData(strDate,jsonObject);
}
private void readTodaySwimData(String strDate,JSONObject jsonObject) {
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
long startTime = GlobalMethods.getEpochTime(strDate);
long endTime = startTime + ONE_DAY_IN_MILLIS;
HealthDataResolver.ReadRequest request = new HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.Exercise.HEALTH_DATA_TYPE)
.setProperties(new String[]{HealthConstants.Exercise.EXERCISE_TYPE})
.setLocalTimeRange(HealthConstants.Exercise.START_TIME, HealthConstants.Exercise.TIME_OFFSET,
startTime, endTime)
.build();
try {
resolver.read(request).setResultListener(result ->{
double distance = 0.0;
try {
for (HealthData data : result) {
distance += data.getFloat(HealthConstants.Exercise.DISTANCE);
}
} finally {
result.close();
}
if (swimObserver != null) {
swimObserver.onChanged(distance,strDate,jsonObject);
}
});
} catch (Exception e) {
Log.e("=> ", "Getting step count fails.", e);
}
}
public interface SwimObserver {
void onChanged(Double distance, String date, JSONObject jsonObject);
}
}
Here is my whole source code this
I figured out on your code that you want to read distance value from the read result.
distance += data.getFloat(HealthConstants.Exercise.DISTANCE);
But you described absolutely not related property. Maybe that is the problem.
.setProperties(new String[]{HealthConstants.Exercise.EXERCISE_TYPE})
Try this.
.setProperties(new String[]{HealthConstants.Exercise.DISTANCE})
Related
I want to WorkManager startWork() to be called every time the user connects to the internet through wifi or 3g/4g/5g.
It calls only one time at the start where I register it.
enqueuing work when a user signs in.
Worker.startWorkManager(SignInActivity.this);
startActivity(new Intent(SignInActivity.this,UsersActivity.class);
it never calls again whenever the user turns Wifi OFF and ON again regardless app is in foreground or background or app is killed through swiped from recent apps.
I want it to be called every time user turned Wifi OFF and ON in every scenario i.e foreground, background, or app is killed.
Worker.class
public class Worker {
public Worker(Context context, WorkerParameters workerParams) {
}
public static void startWorkManager(Context context) {
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
WorkManager.getInstance(context).enqueueUniqueWork(Constants.TAG_SYNC_DATA, ExistingWorkPolicy.KEEP, new OneTimeWorkRequest.Builder(SyncDataWorker.class)
.addTag(Constants.TAG_SYNC_DATA)
.setConstraints(constraints)
.build());
}
}
SyncDataWorker.class
public class SyncDataWorker extends ListenableWorker {
public SyncDataWorker(
#NonNull Context context,
#NonNull WorkerParameters params) {
super(context, params);
}
#NonNull
#Override
public ListenableFuture<Result> startWork() {
return CallbackToFutureAdapter.getFuture(completer -> {
AsyncCallback callback = new AsyncCallback() {
#Override
public void onFailure(Exception e) {
completer.setException(e);
}
#Override
public void onSuccess() {
completer.set(Result.success());
}
#Override
public void onRetry() {
completer.set(Result.retry());
}
};
new AsyncSyncData(getApplicationContext(), callback).execute();
return callback;
});
}
}
AsyncSynData.class
public class AsyncSyncData extends AsyncTask<Void, Void, Void> {
private final Context context;
ArrayList<message> messageArrayListNotSync;
ArrayList<unread_messages> unreadMessagesArrayList;
String user_id = "";
private AsyncCallback callback = null;
public AsyncSyncData(Context context, AsyncCallback callback) {
this.context = context;
messageArrayListNotSync = new ArrayList<>();
unreadMessagesArrayList = new ArrayList<>();
this.callback = callback;
}
#Override
protected Void doInBackground(Void... voids) {
AppDatabase db = AppDatabase.getAppDatabase(context);
user user = null;
ArrayList<user> userArrayList = new ArrayList<>(db.applicationDao().getAllUsers());
if (userArrayList.size() > 0) {
user = userArrayList.get(0);
}
messageArrayListNotSync = new ArrayList<>(db.applicationDao().getAllMessagesNotSync(!user_id.isEmpty() ? user_id : user.threadId));
unreadMessagesArrayList = new ArrayList<>(db.applicationDao().getUnreadMessageStatus());
System.out.println("messageArrayListNotSync: " + messageArrayListNotSync);
System.out.println("unreadMessagesArrayList: " + unreadMessagesArrayList);
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("user_id", !user_id.isEmpty() ? user_id : user.threadId);
Gson gson = new GsonBuilder().create();
JsonArray json_messages = gson.toJsonTree(messageArrayListNotSync).getAsJsonArray();
JsonArray json_unread_messages = gson.toJsonTree(unreadMessagesArrayList).getAsJsonArray();
jsonObject.put("messages", json_messages);
jsonObject.put("unread_messages", json_unread_messages);
RequestHandler.postRequest("/messages", jsonObject, context, new VolleyCallback() {
#Override
public void onSuccess(JSONObject result) {
final JSONObject finalResult = result;
try {
if (result != null && result.has("success") && result.getBoolean("success")) {
new AsyncDeleteUnreadMessagesList(context, unreadMessagesArrayList, new Callback() {
#Override
public void onCallbackCompleted() {
try {
ArrayList<com.app.amber.internet.DATABASE_OPERATIONS.schema.message> messagesToStore = new ArrayList<>();
JSONObject result = finalResult.getJSONObject("data");
JSONObject last_messages = result.getJSONObject("last_messages");
new AsyncUpdateLastMessage(context, last_messages, true, new Callback() {
#Override
public void onCallbackCompleted() {
try {
JSONArray json_messages_to_store = result.getJSONArray("messages");
JSONArray json_evetns_type_1 = result.getJSONArray("eventsType1");
JSONArray json_evetns_type_2 = result.getJSONArray("eventsType2");
for (int i = 0; i < json_messages_to_store.length(); i++) {
JSONObject data = json_messages_to_store.getJSONObject(i);
String id = data.getString("id"),
sender_id = data.getString("sender_id"),
receiver_id = data.getString("receiver_id"),
msg = data.getString("msg"),
type = data.getString("type"),
path = data.getString("path"),
download_status = data.getString("download"),
group_users = data.getString("group_users"),
group_message_status = data.getString("group_message_status");
boolean is_sender = false;
long data_created = data.getLong("date_created");
int is_read = 0;
com.app.amber.internet.DATABASE_OPERATIONS.schema.message message =
new com.app.amber.internet.DATABASE_OPERATIONS.schema.message(id, sender_id, receiver_id, msg, type, path, is_sender, data_created,
is_read, download_status, sender_id, group_users, group_message_status);
messagesToStore.add(message);
}
ArrayList<String> messageIdsType1 = new ArrayList<>();
ArrayList<String> messageIdsType2 = new ArrayList<>();
for (int i = 0; i < json_evetns_type_1.length(); i++) {
messageIdsType1.add(json_evetns_type_1.getJSONObject(i).getString("id"));
}
for (int i = 0; i < json_evetns_type_2.length(); i++) {
messageIdsType2.add(json_evetns_type_2.getJSONObject(i).getString("id"));
}
new AsyncStoreOldMessagesLocally(context, messagesToStore, new Callback() {
#Override
public void onCallbackCompleted() {
new AsyncUpdateMessageStatus(context, messageIdsType1, 1, new Callback() {
#Override
public void onCallbackCompleted() {
new AsyncUpdateMessageStatus(context, messageIdsType2, 2, new Callback() {
#Override
public void onCallbackCompleted() {
new AsyncUpdateMessageStatusList(context, messageArrayListNotSync, new Callback() {
#Override
public void onCallbackCompleted() {
sendCallBack();
}
}).execute();
}
}).execute();
}
}).execute();
}
}).execute();
} catch (Exception e) {
System.out.println("Exception occurred while getting data from data JSONObject received from service: " + e.toString());
e.printStackTrace();
sendCallBack();
}
}
}).execute();
} catch (Exception e) {
System.out.println("Exception occurred while parsing data JSONObject received from service: " + e.toString());
e.printStackTrace();
sendCallBack();
}
}
}).execute();
} else {
sendCallBack();
}
} catch (Exception e) {
System.out.println("Exception occurred while parsing webservice result: " + e.toString());
sendCallBack();
}
}
});
} catch (Exception e) {
System.out.println("exception occurred while parsing messaging lists: " + e.toString());
sendCallBack();
}
return null;
}
private void sendCallBack() {
if (callback != null) {
callback.onSuccess();
}
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
"WorkManager startWork() never calls when constraints are met"
"It calls only one time at the start where I register it."
The ListenableWorker can be recreated in some situations, a new instance of ListenableWorker with the same first ListenableWorker.id. But for it be recreated, it can't be finished. Here are some situations:
Some of the constraints do not matches anymore and it matches again
System was rebooted
Now here are some situations where it will be finished:
Some Exception was raised without treatment
completer.set(Result.success()) was called
completer.set(Result.failure()) was called
There are some situations in your code that the worker can be finished.
There are lots of calls to AsyncSyncData.sendCallBack, which can causes the call of completer.set(Result.success()) on the ListenableWorker instance. If it happens the ListenableWorker completes the job, so it will not be recreated anymore.
"I want to WorkManager startWork() to be called every time the user connects to the internet through wifi or 3g/4g/5g."
The WorkManager alone won't create a new instance of the ListenableWork every time the user connects to Internet. The WorkManager is a API to schedule tasks, and the constraints defined in the ListenableWork are used to not start it while them are not matched, after the ListenableWork finishes, how was discussed above, this task is finished, so no more to do.
If you want to listen to some connectivity changes, you should use ConnectivityManager.registerNetworkCallback and then when the user connects to, you do what you want. Here are some examples that could help you
to do it.
Hello My app is freezes ui for some seconds while it is fetching data from network and stores it in db and then shows it in recyclerview. For fetching data from network I am using retrofit and for storing it and fetching form db Room library. Both with the help of MVVM pattern. Is there a way to remoove the UI freeze?
Here is my code:
In the Mainactivity when clicking download btn
downloadBtn.setOnClickListener(v ->
eventsViewModel.insertEvents(this));
Viewmodel class:
public void insertEvents(Context context){
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String token = preferences.getString("token", "");
final Map<String,String> queryData = new HashMap<>();
queryData.put("token", token);
Call<EventsResponse> call = RetrofitClient.getmInstance().getApi().getEvents(queryData);
call.enqueue(new Callback<EventsResponse>() {
#Override
public void onResponse(Call<EventsResponse> call, Response<EventsResponse> response) {
if (response.code() == 401){
String email = preferences.getString("email", "");
String password = preferences.getString("password", "");
Call<LoginResponse> call1 = RetrofitClient.getmInstance().getApi().loginuser(email, password);
call1.enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.code() == 200){
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); // 0 - for private mode
SharedPreferences.Editor editor = pref.edit();
editor.putString("token", response.body().getToken());
editor.apply();
insertEvents(context);
}
else {
}
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
}
});
}
if (response.code() == 200){
eventList = response.body().getData();
EventsTable eventsTable = new EventsTable();
TicketDatesTable ticketDatesTable = new TicketDatesTable();
for (int i = 0; i < eventList.size(); i++) {
eventsTable.setEvent_id(eventList.get(i).getId());
eventsTable.setTitle_tk(eventList.get(i).getTitle_tk());
eventsTable.setTitle_ru(eventList.get(i).getTitle_ru());
eventsTable.setImageURL("https://bilettm.com/" + eventList.get(i).getImage_url());
eventsTable.setStart_date(eventList.get(i).getStart_date());
eventsTable.setEnd_date(eventList.get(i).getEnd_date());
eventsTable.setSales_volume(eventList.get(i).getEnd_date());
eventsTable.setOrganiser_fees_volume(eventList.get(i).getOrganiser_fees_volume());
eventsTable.setViews(eventList.get(i).getViews());
eventsTable.setSales_volume(eventList.get(i).getSales_volume());
eventsTable.setIs_live(eventList.get(i).getIs_live());
if (!eventList.get(i).getTicket_dates().isEmpty()) {
showTimeList = eventList.get(i).getTicket_dates();
int b = 0;
while (b < showTimeList.size()) {
ticketDatesTable.setEvent_id(showTimeList.get(b).getEvent_id());
ticketDatesTable.setTicket_date(showTimeList.get(b).getTicket_date());
insertTicketDates(ticketDatesTable);
try {
Thread.sleep(150);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
b++;
}
}
insert(eventsTable);
try {
Thread.sleep(150);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
#Override
public void onFailure(Call<EventsResponse> call, Throwable t) {
}
});
}
public void insert(EventsTable data){
repository.insertEvents(data);
}
public void insertTicketDates(TicketDatesTable ticketDatesTable){
repository.insertTicketDates(ticketDatesTable);
Here is my repository :
public void insertEvents(EventsTable data){
new EventInsertion(eventsDAO).execute(data);
}
private static class EventInsertion extends AsyncTask<EventsTable, Void, Void> {
private EventsDAO eventsDAO;
private EventInsertion(EventsDAO eventsDAO) {
this.eventsDAO = eventsDAO;
}
#Override
protected Void doInBackground(EventsTable... eventsTables) {
eventsDAO.insertEvents(eventsTables[0]);
return null;
}
}
public void insertTicketDates(TicketDatesTable data){
new TicketDatesInsertion(eventsDAO).execute(data);
}
private static class TicketDatesInsertion extends AsyncTask<TicketDatesTable, Void, Void> {
private EventsDAO eventsDAO;
private TicketDatesInsertion(EventsDAO eventsDAO) {
this.eventsDAO = eventsDAO;
}
#Override
protected Void doInBackground(TicketDatesTable... ticketDatesTables) {
eventsDAO.insertTicketDates(ticketDatesTables[0]);
return null;
}
}
Here is my DAO:
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertEvents(EventsTable data);
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertTicketDates(TicketDatesTable datesTable);
I think it freezes when it is storing it into sqlite db
I found my problem. It was initializing entity before starting for loop:
BEFORE:
EventsTable eventsTable = new EventsTable();
for (int i = 0; i < eventList.size(); i++) {
INSERT();
}
AFTER:
for (int i = 0; i < eventList.size(); i++) {
EventsTable eventsTable = new EventsTable();
INSERT();
}
A better solution would be to collect all your required objects in an ArrayList and then pass it on to the AsyncTask and from there to DAO for bulk insertion.
And remove all Thread.sleep(150) statements as they serve no purpose.
why you are using this Thread.sleep(150);Call is already a background task in retrofit
Currently, I am implementing google Speech to Text in my project. The sample code referred is this: Click Here.
I have used the SpeechService and Voice Recorder class from this project.
public class SpeechService extends Service {
public static final List<String> SCOPE =
Collections.singletonList("https://www.googleapis.com/auth/cloud-platform");
private static final String TAG = "SpeechService";
private static final String PREFS = "SpeechService";
private static final String PREF_ACCESS_TOKEN_VALUE = "access_token_value";
private static final String PREF_ACCESS_TOKEN_EXPIRATION_TIME = "access_token_expiration_time";
/**
* We reuse an access token if its expiration time is longer than this.
*/
private static final int ACCESS_TOKEN_EXPIRATION_TOLERANCE = 30 * 60 * 1000; // thirty minutes
/**
* We refresh the current access token before it expires.
*/
private static final int ACCESS_TOKEN_FETCH_MARGIN = 60 * 1000; // one minute
private static final String HOSTNAME = "speech.googleapis.com";
private static final int PORT = 443;
private static Handler mHandler;
private final SpeechBinder mBinder = new SpeechBinder();
private final ArrayList<Listener> mListeners = new ArrayList<>();
private final StreamObserver<StreamingRecognizeResponse> mResponseObserver
= new StreamObserver<StreamingRecognizeResponse>() {
#Override
public void onNext(StreamingRecognizeResponse response) {
Log.e("Speech", "Recognized");
String text = null;
boolean isFinal = false;
if (response.getResultsCount() > 0) {
System.out.println("result count....."+String.valueOf(response.getResultsCount()));
final StreamingRecognitionResult result = response.getResults(0);
isFinal = result.getIsFinal();
if (result.getAlternativesCount() > 0) {
final SpeechRecognitionAlternative alternative = result.getAlternatives(0);
text = alternative.getTranscript();
}
}
if (text != null && isFinal) {
for (Listener listener : mListeners) {
listener.onSpeechRecognized(text, isFinal);
}
} else {
for (Listener listener : mListeners) {
listener.onRandomStupidity();
}
}
}
#Override
public void onError(Throwable t) {
Log.e(TAG, "Error calling the API.", t);
for(Listener listener : mListeners){
listener.onErrorRecognizing();
}
}
#Override
public void onCompleted() {
Log.i(TAG, "API completed.");
}
};
private volatile AccessTokenTask mAccessTokenTask;
private final Runnable mFetchAccessTokenRunnable = new Runnable() {
#Override
public void run() {
fetchAccessToken();
}
};
private SpeechGrpc.SpeechStub mApi;
private StreamObserver<StreamingRecognizeRequest> mRequestObserver;
public static SpeechService from(IBinder binder) {
return ((SpeechBinder) binder).getService();
}
#Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
fetchAccessToken();
}
#Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mFetchAccessTokenRunnable);
mHandler = null;
// Release the gRPC channel.
if (mApi != null) {
final ManagedChannel channel = (ManagedChannel) mApi.getChannel();
if (channel != null && !channel.isShutdown()) {
try {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Log.e(TAG, "Error shutting down the gRPC channel.", e);
}
}
mApi = null;
}
}
private void fetchAccessToken() {
if (mAccessTokenTask != null) {
return;
}
mAccessTokenTask = new AccessTokenTask();
mAccessTokenTask.execute();
}
private String getDefaultLanguageCode() {
final LangInnerResponse languageToLearn = MemoryCache.getLanguageToLearn();
if(languageToLearn != null) {
Log.e("Test Lang", languageToLearn.getCode());
return languageToLearn.getCode();
} else {
final Locale locale = Locale.getDefault();
final StringBuilder language = new StringBuilder(locale.getLanguage());
final String country = locale.getCountry();
if (!TextUtils.isEmpty(country)) {
language.append("-");
language.append(country);
}
return language.toString();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void addListener(#NonNull Listener listener) {
mListeners.add(listener);
}
public void removeListener(#NonNull Listener listener) {
mListeners.remove(listener);
}
/**
** Starts recognizing speech audio.
*
* #param sampleRate The sample rate of the audio.
*/
public void startRecognizing(int sampleRate) {
if (mApi == null) {
Log.w(TAG, "API not ready. Ignoring the request.");
return;
}
System.out.println("calling api....");
// Configure the API
mRequestObserver = mApi.streamingRecognize(mResponseObserver);
mRequestObserver.onNext(StreamingRecognizeRequest.newBuilder()
.setStreamingConfig(StreamingRecognitionConfig.newBuilder()
.setConfig(RecognitionConfig.newBuilder()
.setLanguageCode(getDefaultLanguageCode())
.setEncoding(RecognitionConfig.AudioEncoding.LINEAR16)
.setSampleRateHertz(sampleRate)
.build())
.setInterimResults(true)
.setSingleUtterance(true)
.build())
.build());
}
/**
* Recognizes the speech audio. This method should be called every time a chunk of byte buffer
* is ready.
*
* #param data The audio data.
* #param size The number of elements that are actually relevant in the {#code data}.
*/
public void recognize(byte[] data, int size) {
if (mRequestObserver == null) {
return;
}
// Call the streaming recognition API
mRequestObserver.onNext(StreamingRecognizeRequest.newBuilder()
.setAudioContent(ByteString.copyFrom(data, 0, size))
.build());
}
/**
* Finishes recognizing speech audio.
*/
public void finishRecognizing() {
if (mRequestObserver == null) {
return;
}
mRequestObserver.onCompleted();
mRequestObserver = null;
}
public interface Listener {
/**
* Called when a new piece of text was recognized by the Speech API.
*
* #param text The text.
* #param isFinal {#code true} when the API finished processing audio.
*/
void onSpeechRecognized(String text, boolean isFinal);
void onErrorRecognizing();
void onRandomStupidity();
}
/**
* Authenticates the gRPC channel using the specified {#link GoogleCredentials}.
*/
private static class GoogleCredentialsInterceptor implements ClientInterceptor {
private final Credentials mCredentials;
private Metadata mCached;
private Map<String, List<String>> mLastMetadata;
GoogleCredentialsInterceptor(Credentials credentials) {
mCredentials = credentials;
}
private static Metadata toHeaders(Map<String, List<String>> metadata) {
Metadata headers = new Metadata();
if (metadata != null) {
for (String key : metadata.keySet()) {
Metadata.Key<String> headerKey = Metadata.Key.of(
key, Metadata.ASCII_STRING_MARSHALLER);
for (String value : metadata.get(key)) {
headers.put(headerKey, value);
}
}
}
return headers;
}
#Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
final MethodDescriptor<ReqT, RespT> method, CallOptions callOptions,
final Channel next) {
return new ClientInterceptors.CheckedForwardingClientCall<ReqT, RespT>(
next.newCall(method, callOptions)) {
#Override
protected void checkedStart(Listener<RespT> responseListener, Metadata headers)
throws StatusException {
Metadata cachedSaved;
URI uri = serviceUri(next, method);
synchronized (this) {
Map<String, List<String>> latestMetadata = getRequestMetadata(uri);
if (mLastMetadata == null || mLastMetadata != latestMetadata) {
mLastMetadata = latestMetadata;
mCached = toHeaders(mLastMetadata);
}
cachedSaved = mCached;
}
headers.merge(cachedSaved);
delegate().start(responseListener, headers);
}
};
}
/**
* Generate a JWT-specific service URI. The URI is simply an identifier with enough
* information for a service to know that the JWT was intended for it. The URI will
* commonly be verified with a simple string equality check.
*/
private URI serviceUri(Channel channel, MethodDescriptor<?, ?> method)
throws StatusException {
String authority = channel.authority();
if (authority == null) {
throw Status.UNAUTHENTICATED
.withDescription("Channel has no authority")
.asException();
}
// Always use HTTPS, by definition.
final String scheme = "https";
final int defaultPort = 443;
String path = "/" + MethodDescriptor.extractFullServiceName(method.getFullMethodName());
URI uri;
try {
uri = new URI(scheme, authority, path, null, null);
} catch (URISyntaxException e) {
throw Status.UNAUTHENTICATED
.withDescription("Unable to construct service URI for auth")
.withCause(e).asException();
}
// The default port must not be present. Alternative ports should be present.
if (uri.getPort() == defaultPort) {
uri = removePort(uri);
}
return uri;
}
private URI removePort(URI uri) throws StatusException {
try {
return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), -1 /* port */,
uri.getPath(), uri.getQuery(), uri.getFragment());
} catch (URISyntaxException e) {
throw Status.UNAUTHENTICATED
.withDescription("Unable to construct service URI after removing port")
.withCause(e).asException();
}
}
private Map<String, List<String>> getRequestMetadata(URI uri) throws StatusException {
try {
return mCredentials.getRequestMetadata(uri);
} catch (IOException e) {
throw Status.UNAUTHENTICATED.withCause(e).asException();
}
}
}
private class SpeechBinder extends Binder {
SpeechService getService() {
return SpeechService.this;
}
}
private class CreateApiSingle implements SingleOnSubscribe<SpeechGrpc.SpeechStub> {
#Override
public void subscribe(SingleEmitter<SpeechGrpc.SpeechStub> emitter) throws Exception {
final AccessToken accessToken = generateCredentials();
final SpeechGrpc.SpeechStub api = generateApi(accessToken);
emitter.onSuccess(api);
}
private AccessToken generateCredentials() throws IOException {
final SharedPreferences prefs =
getSharedPreferences(PREFS, Context.MODE_PRIVATE);
String tokenValue = prefs.getString(PREF_ACCESS_TOKEN_VALUE, null);
long expirationTime = prefs.getLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, -1);
// Check if the current token is still valid for a while
if (tokenValue != null && expirationTime > 0) {
if (expirationTime
> System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION_TOLERANCE) {
return new AccessToken(tokenValue, new Date(expirationTime));
}
}
// ***** WARNING *****
// In this sample, we load the credential from a JSON file stored in a raw resource
// folder of this client app. You should never do this in your app. Instead, store
// the file in your server and obtain an access token from there.
// *******************
final InputStream stream = getResources().openRawResource(R.raw.credential);
final GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
.createScoped(SCOPE);
final AccessToken token = credentials.refreshAccessToken();
prefs.edit()
.putString(PREF_ACCESS_TOKEN_VALUE, token.getTokenValue())
.putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME,
token.getExpirationTime().getTime())
.apply();
stream.close();
return token;
}
private SpeechGrpc.SpeechStub generateApi(AccessToken accessToken) {
final ManagedChannel channel = new OkHttpChannelProvider()
.builderForAddress(HOSTNAME, PORT)
.nameResolverFactory(new DnsNameResolverProvider())
.intercept(new GoogleCredentialsInterceptor(new GoogleCredentials(accessToken)
.createScoped(SCOPE)))
.build();
return SpeechGrpc.newStub(channel);
}
}
private class AccessTokenTask extends AsyncTask<Void, Void, AccessToken> {
#Override
protected AccessToken doInBackground(Void... voids) {
final SharedPreferences prefs =
getSharedPreferences(PREFS, Context.MODE_PRIVATE);
String tokenValue = prefs.getString(PREF_ACCESS_TOKEN_VALUE, null);
long expirationTime = prefs.getLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, -1);
// Check if the current token is still valid for a while
if (tokenValue != null && expirationTime > 0) {
if (expirationTime
> System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION_TOLERANCE) {
return new AccessToken(tokenValue, new Date(expirationTime));
}
}
// ***** WARNING *****
// In this sample, we load the credential from a JSON file stored in a raw resource
// folder of this client app. You should never do this in your app. Instead, store
// the file in your server and obtain an access token from there.
// *******************
final InputStream stream = getResources().openRawResource(R.raw.credential);
try {
final GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
.createScoped(SCOPE);
final AccessToken token = credentials.refreshAccessToken();
prefs.edit()
.putString(PREF_ACCESS_TOKEN_VALUE, token.getTokenValue())
.putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME,
token.getExpirationTime().getTime())
.apply();
return token;
} catch (IOException e) {
Log.e(TAG, "Failed to obtain access token.", e);
}
return null;
}
#Override
protected void onPostExecute(AccessToken accessToken) {
mAccessTokenTask = null;
final ManagedChannel channel = new OkHttpChannelProvider()
.builderForAddress(HOSTNAME, PORT)
.nameResolverFactory(new DnsNameResolverProvider())
.intercept(new GoogleCredentialsInterceptor(new GoogleCredentials(accessToken)
.createScoped(SCOPE)))
.build();
mApi = SpeechGrpc.newStub(channel);
// Schedule access token refresh before it expires
if (mHandler != null) {
mHandler.postDelayed(mFetchAccessTokenRunnable,
Math.max(accessToken.getExpirationTime().getTime()
- System.currentTimeMillis()
- ACCESS_TOKEN_FETCH_MARGIN, ACCESS_TOKEN_EXPIRATION_TOLERANCE));
}
}
}}
public class VoiceRecorder {
private static final int[] SAMPLE_RATE_CANDIDATES = new int[]{48000, 44100};
private static final int CHANNEL = AudioFormat.CHANNEL_IN_MONO;
private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private static final int AMPLITUDE_THRESHOLD = 1500;
private static final int SPEECH_TIMEOUT_MILLIS = 2000;
private static final int MAX_SPEECH_LENGTH_MILLIS = 30 * 1000;
public static abstract class Callback {
/**
* Called when the recorder starts hearing voice.
*/
public void onVoiceStart() {
}
/**
* Called when the recorder is hearing voice.
*
* #param data The audio data in {#link AudioFormat#ENCODING_PCM_16BIT}.
* #param size The size of the actual data in {#code data}.
*/
public void onVoice(byte[] data, int size) {
}
/**
* Called when the recorder stops hearing voice.
*/
public void onVoiceEnd() {
}
}
private final Callback mCallback;
private AudioRecord mAudioRecord;
private Thread mThread;
private byte[] mBuffer;
private final Object mLock = new Object();
/** The timestamp of the last time that voice is heard. */
private long mLastVoiceHeardMillis = Long.MAX_VALUE;
/** The timestamp when the current voice is started. */
private long mVoiceStartedMillis;
public VoiceRecorder(#NonNull Callback callback) {
mCallback = callback;
}
/**
* Starts recording audio.
*
* <p>The caller is responsible for calling {#link #stop()} later.</p>
*/
public void start() {
// Stop recording if it is currently ongoing.
stop();
// Try to create a new recording session.
mAudioRecord = createAudioRecord();
if (mAudioRecord == null) {
throw new RuntimeException("Cannot instantiate VoiceRecorder");
}
// Start recording.
mAudioRecord.startRecording();
// Start processing the captured audio.
mThread = new Thread(new ProcessVoice());
mThread.start();
}
/**
* Stops recording audio.
*/
public void stop() {
synchronized (mLock) {
System.out.println("stop audio record....");
dismiss();
if (mThread != null) {
mThread.interrupt();
mThread = null;
}
if (mAudioRecord != null) {
mAudioRecord.stop();
mAudioRecord.release();
mAudioRecord = null;
}
mBuffer = null;
System.out.println("stop audio record....2");
}
}
/**
* Dismisses the currently ongoing utterance.
*/
public void dismiss() {
if (mLastVoiceHeardMillis != Long.MAX_VALUE) {
mLastVoiceHeardMillis = Long.MAX_VALUE;
mCallback.onVoiceEnd();
}
}
/**
* Retrieves the sample rate currently used to record audio.
*
* #return The sample rate of recorded audio.
*/
public int getSampleRate() {
if (mAudioRecord != null) {
return mAudioRecord.getSampleRate();
}
return 0;
}
/**
* Creates a new {#link AudioRecord}.
*
* #return A newly created {#link AudioRecord}, or null if it cannot be created (missing
* permissions?).
*/
private AudioRecord createAudioRecord() {
for (int sampleRate : SAMPLE_RATE_CANDIDATES) {
final int sizeInBytes = AudioRecord.getMinBufferSize(sampleRate, CHANNEL, ENCODING);
if (sizeInBytes == AudioRecord.ERROR_BAD_VALUE) {
continue;
}
final AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, CHANNEL, ENCODING, sizeInBytes);
if (audioRecord.getState() == AudioRecord.STATE_INITIALIZED) {
mBuffer = new byte[sizeInBytes];
return audioRecord;
} else {
audioRecord.release();
}
}
return null;
}
/**
* Continuously processes the captured audio and notifies {#link #mCallback} of corresponding
* events.
*/
private class ProcessVoice implements Runnable {
#Override
public void run() {
while (true) {
synchronized (mLock) {
if (Thread.currentThread().isInterrupted()) {
break;
}
final int size = mAudioRecord.read(mBuffer, 0, mBuffer.length);
final long now = System.currentTimeMillis();
if (isHearingVoice(mBuffer, size)) {
if (mLastVoiceHeardMillis == Long.MAX_VALUE) {
mVoiceStartedMillis = now;
mCallback.onVoiceStart();
}
mCallback.onVoice(mBuffer, size);
mLastVoiceHeardMillis = now;
if (now - mVoiceStartedMillis > MAX_SPEECH_LENGTH_MILLIS) {
end();
}
} else if (mLastVoiceHeardMillis != Long.MAX_VALUE) {
mCallback.onVoice(mBuffer, size);
if (now - mLastVoiceHeardMillis > SPEECH_TIMEOUT_MILLIS) {
end();
}
}
}
}
}
private void end() {
mLastVoiceHeardMillis = Long.MAX_VALUE;
mCallback.onVoiceEnd();
System.out.println("end...");
}
private boolean isHearingVoice(byte[] buffer, int size) {
for (int i = 0; i < size - 1; i += 2) {
// The buffer has LINEAR16 in little endian.
int s = buffer[i + 1];
if (s < 0) s *= -1;
s <<= 8;
s += Math.abs(buffer[i]);
if (s > AMPLITUDE_THRESHOLD) {
return true;
}
}
return false;
}
}}
Then I implemented the Speech Service & Voice Recorder callback as follows:
private VoiceRecorder voiceRecorder;
private final SpeechService.Listener speechServiceListener = new SpeechService.Listener() {
#Override
public void onSpeechRecognized(final String text, final boolean isFinal) {
if (isFinal) {
System.out.println("ui thread...");
if (!TextUtils.isEmpty(text)) {
runOnUiThread(() -> {
showMessage(text);
flingAnswer(text);
});
}
}
}
#Override
public void onErrorRecognizing() {
showMessage("Please try again. Could not detect.");
}
#Override
public void onRandomStupidity() {
}
};
private SpeechService speechService;
private final VoiceRecorder.Callback voiceCallback = new VoiceRecorder.Callback() {
#Override
public void onVoiceStart() {
if (speechService != null) {
System.out.println("voice start....");
speechService.startRecognizing(voiceRecorder.getSampleRate());
}
}
#Override
public void onVoice(byte[] data, int size) {
if (speechService != null) {
speechService.recognize(data, size);
}
}
#Override
public void onVoiceEnd() {
if (speechService != null) {
speechService.finishRecognizing();
}
}
};
private final ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder binder) {
speechService = SpeechService.from(binder);
speechService.addListener(speechServiceListener);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
speechService = null;
}
};
For voice input this is the code:
#Override
public void stopRecognizing() {
stopVoiceRecorder();
Log.e("Recording", "Stopped");
}
#Override
public void startRecognizing() {
if (permissionManager != null && permissionManager.askForPermissions()) {
startVoiceRecorder();
vibrate.vibrate(50);//Providing haptic feedback to user on press.
}
Log.e("Recording", "Started");
}
binding.imgVoice.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
System.out.println("up...");
mCallback.stopRecognizing();
binding.imgVoice
.animate()
.scaleX(1.0f)
.scaleY(1.0f);
binding.imgVoice.setVisibility(View.GONE);
binding.progressBar.setVisibility(View.VISIBLE);
break;
case MotionEvent.ACTION_DOWN:
System.out.println("down...");
binding.imgVoice
.animate()
.scaleX(1.8f)
.scaleY(1.8f);
mCallback.startRecognizing();
break;
}
return true;
});
}
When I press the mic, event registered as Action_Down, I start the voice recorder and on releasing the mic , voice recorder is stopped. Also, with the Action_Down I am scaling up the mic icon which needs to be scaled down on Action_Up . But the ui freezes as a whole most of the times. I find that the onNext() callback for StreamObserver is continuously being invoked before the isFinal becomes true.
private void startVoiceRecorder() {
if (voiceRecorder != null) {
voiceRecorder.stop();
}
voiceRecorder = new VoiceRecorder(voiceCallback);
voiceRecorder.start();
}
private void stopVoiceRecorder() {
if (voiceRecorder != null) {
voiceRecorder.stop();
voiceRecorder = null;
}
}
But I want the mic to scale down as soon as I release the mic(on Action up event) which is not happening.
So if anyone can help me over this?
Thanks in Advance.
I have the array of objects that look like this:
public class Time {
public String start_time;
public String finish_time;
public Time(String start_time, String finish_time) {
this.start_time = start_time;
this.finish_time = finish_time;
}
}
I need to implement a timer in my Fragment in the following way:
it should start counting down from the first element in array in a way that on one single Time element it should first start counting down to the time left to reach start_time, then when the timer reaches start_time, it should start counting down to finish_time and, eventually, when it reaches finish_time it should do the same previous actions for the next element in the array. And when the whole array is finished, it should display 00:00:00.
PS: start_time and finish_time are formatted like this: HH:mm however the timer should be HH:mm:ss
Can anybody help with implementing that or at least give an idea?
Finally, found the appropriate answer. Thanks a lot to the guy who helped me with it:
class Clazz {
private Timer dateTimer;
private Timer remainderTimer;
private Date nextDate;
private boolean remainderTimerStarted;
private static final long REMINDER_UPDATE_INTERVAL = 1000;
private static final String[] DATES = { "12.04.2015 22:21", "12.04.2015 22:22", "12.04.2015 22:23" };
private int currentIndex;
public Clazz() {
dateTimer = new Timer();
}
public static void main(String[] args) {
Clazz instance = new Clazz();
instance.run();
}
private void run() {
nextDate = parseDate(DATES[currentIndex]);
schedule();
}
public void schedule() {
runSecondsCounter();
dateTimer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("Current date is:" + new Date());
currentIndex++;
if (currentIndex < DATES.length) {
nextDate = parseDate(DATES[currentIndex]);
System.out.println("Next date is:" + nextDate);
schedule();
} else {
remainderTimer.cancel();
}
}
}, nextDate);
}
private Date parseDate(String nextDate) {
Date date = null;
DateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm",
Locale.ENGLISH);
try {
date = format.parse(nextDate);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
private void runSecondsCounter() {
if (remainderTimerStarted) {
remainderTimer.cancel();
}
remainderTimer = new Timer();
remainderTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
remainderTimerStarted = true;
long remains = nextDate.getTime() - new Date().getTime();
System.out.println("Remains: " + (remains / 1000) + " seconds");
}
}, REMINDER_UPDATE_INTERVAL, REMINDER_UPDATE_INTERVAL);
}
}
Code 1 is a part of my Fragment class
From Code 1 i am getting my place name. I want to pass that place name to a non Activity class That is to CODE 2.
Code 1
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
gps = new GPSTracker(getActivity());
Geocoder geocoder= new Geocoder(getActivity(), Locale.ENGLISH);
myAddress=(TextView)getView().findViewById(R.id.gpsLocation);
surveyView = (SurveyView) getView().findViewById(R.id.surveyView);
newsHomeView = (NewsHomeView) getView().findViewById(R.id.newsHomeView);
audioView = (AudioItemView) getView().findViewById(R.id.audioView);
AudioListener listener = (AudioListener)getActivity();
audioView.setListener(listener);
newsHomeView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity mnAct = (MainActivity)HomeFragment.this.getActivity();
mnAct.moveToPage(Constants.NEWS_PAGE);
}
});
iPrevIndex = -1;
// check if GPS enabled
if(gps.canGetLocation()){
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// \n is for new line
//Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
try {
//Place your latitude and longitude
// List<Address> addresses = geocoder.getFromLocation(37.423247,-122.085469, 1);
List<Address> addresses = geocoder.getFromLocation(latitude,longitude, 1);
if(addresses != null) {
Address fetchedAddress = addresses.get(0);
StringBuilder strAddress = new StringBuilder();
for(int i=0; i<=fetchedAddress.getMaxAddressLineIndex(); i++) {
strAddress.append(fetchedAddress.getAddressLine(i)).append("\n");
}
Log.i("country name ",fetchedAddress.getAddressLine(fetchedAddress.getMaxAddressLineIndex()));
String s=fetchedAddress.getAddressLine(fetchedAddress.getMaxAddressLineIndex()-1);// Bangalore, Karnataka, 560038
String str[]=s.split(" ");// array of Bangalore, Karnataka, 560038
System.out.println(Arrays.toString(str)); // print all array element
// myAddress.setText("You'r location is: " +strAddress.toString());
}
else
myAddress.setText("No location found..!");
// Toast.makeText(getActivity(),"Please switch on yor gps",Toast.LENGTH_LONG).show();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(getActivity(),"Could not get address..!", Toast.LENGTH_LONG).show();
}
}else{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
}
CODE 2
public class Audios extends BaseCollection<Audio> {
private static String newValue;
public static setNewValue(String value) {
this.newValue = value;
//Code to use this value.
}
#Override
public void loadWithJson(JSONArray jsonObj) {
if(null == jsonObj) {
return;
}
try {
List<Audio> entries = new ArrayList<Audio>();
for (int o = 0; o < jsonObj.length(); ++o) {
Audio opt = Audio.fromJson(jsonObj.getJSONObject(o));
// String title = opt.getTitle();
//System.out.println(opt.getTitle().substring(0, 4)); // title.substring(0, 3);
// entries.add(opt);
entries.add(opt);
}
this.entries = entries;
} catch (Exception e) {
e.printStackTrace();
}
}
public void getAudioResult(JSONObject jsonRes) {
int id, grpId, dwnCount, upCount;
if(null != jsonRes) {
try {
id = jsonRes.getInt(Constants.MEDIA_ID);
grpId = jsonRes.getInt(Constants.GROUP_ID);
dwnCount= jsonRes.getInt(Constants.SET_THUMBS_DWN);
upCount = jsonRes.getInt(Constants.SET_THUMBS_UP);
}
catch(JSONException je) { id = grpId = dwnCount = upCount = -1;}
if(-1 == id || -1 == grpId) {
return;
}
for(int iLoop = 0; iLoop < entries.size(); iLoop++) {
Audio opt = entries.get(iLoop);
if(opt.token == id && opt.groupId == grpId) {
opt.thumbDwns = dwnCount;
opt.thumbUps = upCount;
break;
}
}
}
}
}
In code 1 Hear i am getting my place name
Values:
place=str[1].substring(0, 4);
AudiosFragment hm=new AudiosFragment();
Bundle bundle = new Bundle();
bundle.putString("place", str[1].substring(0, 4));
Please tell me how i will pass this place value.
easy way to pass data from one class to another is by using constructor
Consider Example:
Class A{
Object o;
private methodA()
{
B b = new B(o); //here you are passing o to Class B
b.methodB();
}
}
Class B{
Object o;
public B(Object O)
{
this.o=o;
}
public methodB()
{
use object o here
}
}
may be this will help..
You can use a Singleton class but is maybe to complex for only a String [].
public class Singleton {
private static Singleton uniqInstance;
private String str[];
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (uInstance == null) {
uInstance = new Singleton();
}
return uInstance;
}
}
Just create a method inside the Audios Class.
Now, depending on the fact that you want different objects of the Audio Class to have different value for this String, you can define it static or not. Then just call that method.
Example :
Class Audios extends BaseCollection<Audio> {
private static String newValue;
public static void setNewValue(String value) {
this.newValue = value;
//Code to use this value.
..
}
}
From the Fragment, just call Audios.setNewValue("This is the value for the String");