Yesterday i ask a simplified question of my problem, but think its too simplified.
What my programm should do, is to hear a keyword and when he hear it, he should listen to what i said. (like if you told to siri or google now, by saying siri or ok google).
I'm using pocketsphinx for the keyword and the google speechrecognizer for the longer parts. It works, but only for one time. The pocketsphinx is in the MainActivity and the google recognizer is in an extra class (Jarvis).
The programm starts with the pocketsphinx listener, when he hear the KEYPHRASE, he starts the google listener by calling jarvis.startListener() (by the next()-method) and there is the problem, when the googlelistener is done, i dont come back from the Jarvis-class to the MainActivity to call the next() method again.
(when the google recognizer is done, the last things he do is in the onResult() in Jarvis-class, but from there i cant call the next()-method from MainActivity-class)
MainActivity
package com.example.superuser.jarvis;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import edu.cmu.pocketsphinx.Assets;
import edu.cmu.pocketsphinx.Hypothesis;
import edu.cmu.pocketsphinx.SpeechRecognizer;
import edu.cmu.pocketsphinx.SpeechRecognizerSetup;
import static android.widget.Toast.makeText;
import static edu.cmu.pocketsphinx.SpeechRecognizerSetup.defaultSetup;
public class MainActivity extends Activity implements edu.cmu.pocketsphinx.RecognitionListener {
private String LOG_TAG = "Jarvis_hears_anything";
private TextView tv;
private Jarvis jarvis;
private boolean wannahearjarvis = false;
/* Named searches allow to quickly reconfigure the decoder */
private static final String KWS_SEARCH = "wakeup";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "jarvis";
private edu.cmu.pocketsphinx.SpeechRecognizer recognizer;
//private HashMap<String, Integer> captions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.b1);
tv = (TextView) findViewById(R.id.tv1);
//captions = new HashMap<String, Integer>();
//captions.put(KWS_SEARCH, R.string.kws_caption);
jarvis = new Jarvis(getApplicationContext());
new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(MainActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) findViewById(R.id.tv1))
.setText("Failed to init recognizer " + result);
} else {
//switchSearch(KWS_SEARCH);
recognizer.startListening(KWS_SEARCH);
}
}
}.execute();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "geht", Toast.LENGTH_SHORT).show();
}
});
}
public void next(){
if (wannahearjarvis){
recognizer.startListening(KWS_SEARCH);
wannahearjarvis = false;
}
else{
jarvis.startListening();
wannahearjarvis = true;
}
}
#Override
public void onDestroy() {
super.onDestroy();
recognizer.cancel();
recognizer.shutdown();
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
if (text.equals(KEYPHRASE)){
tv.append("found");
recognizer.stop();
//switchSearch(KWS_SEARCH);
}
else {
//((TextView) findViewById(R.id.tv1)).append(text+"PR");
//Log.i(LOG_TAG, text+"PR");
}
}
/**
* This callback is called when we stop the recognizer.
*/
#Override
public void onResult(Hypothesis hypothesis) {
//((TextView) findViewById(R.id.tv1)).setText("");
((TextView) findViewById(R.id.tv1)).append("oR");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
next();
}
#Override
public void onBeginningOfSpeech() {
}
/**
* We stop recognizer here to get a final result
*/
#Override
public void onEndOfSpeech() {
if (!recognizer.getSearchName().equals(KWS_SEARCH)){
tv.append("fuck");
}
//switchSearch(KWS_SEARCH);
}
/*private void switchSearch(String searchName) {
recognizer.stop();
// If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
if (searchName.equals(KWS_SEARCH))
recognizer.startListening(searchName);
else
recognizer.startListening(searchName, 10000);
//String caption = getResources().getString(captions.get(searchName));
//((TextView) findViewById(R.id.tv1)).setText(caption);
//((TextView) findViewById(R.id.tv1)).append(caption);
}*/
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
// To disable logging of raw audio comment out this call (takes a lot of space on the device)
.setRawLogDir(assetsDir)
// Threshold to tune for keyphrase to balance between false alarms and misses
.setKeywordThreshold(1e-20f)
// Use context-independent phonetic search, context-dependent is too slow for mobile
.setBoolean("-allphone_ci", true)
.getRecognizer();
recognizer.addListener(this);
/** In your application you might not need to add all those searches.
* They are added here for demonstration. You can leave just one.
*/
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
}
#Override
public void onError(Exception error) {
((TextView) findViewById(R.id.tv1)).setText(error.getMessage());
}
#Override
public void onTimeout() {
//switchSearch(KWS_SEARCH);
}
}
Jarvis
package com.example.superuser.jarvis;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.widget.Toast;
import java.util.ArrayList;
public class Jarvis implements RecognitionListener{
private AudioManager audiom;
private SpeechRecognizer speech;
private Intent recogIntent;
private Toast m;
private Context c;
private String text;
public Jarvis(Context context){
speech = SpeechRecognizer.createSpeechRecognizer(context);
speech.setRecognitionListener(this);
recogIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recogIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "de");
//recogIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName());
m = new Toast(context);
c=context;
}
public void startListening(){
speech.startListening(recogIntent);
}
public void destroy(){
speech.stopListening();
speech.cancel();
speech.destroy();
}
#Override
public void onReadyForSpeech(Bundle params) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float rmsdB) {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int error) {
}
#Override
public void onResults(Bundle results) {
ArrayList<String> matches = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
Toast.makeText(c, matches.get(0), Toast.LENGTH_LONG).show();
speech.cancel();
//tried
//MainActivity m = new MainActivity();
//m.next();
//but got a Nullpointer Exception
}
#Override
public void onPartialResults(Bundle partialResults) {
}
#Override
public void onEvent(int eventType, Bundle params) {
}
}
You can store reference to the main activity in Jarvis object in a field:
class Jarvis {
....
private MainActivity m;
....
public Jarvis(MainActivity m) {
this.m = m;
}
....
public void onResults(Bundle results) {
....
m.next();
}
You can also send intents to the main activity as described here. This might be overkill in your case though.
Related
I try to use Google ConsentSDK to show in Android app consent form.
When I call form.show() I get this error:
"Consent form error Consent form is not ready to be displayed."
Who can help me?
My code:
ConsentForm form = new ConsentForm.Builder(context, privacyUrl)
.withListener(new ConsentFormListener() {
#Override
public void onConsentFormLoaded() {
// Consent form loaded successfully.
Log.d("SplashScreen", "Consent form Loaded ");
}
#Override
public void onConsentFormOpened() {
// Consent form was displayed.
Log.d("SplashScreen", "Consent form opened ");
}
#Override
public void onConsentFormClosed(
ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed.
Log.d("SplashScreen", "Consent form Closed ");
}
#Override
public void onConsentFormError(String errorDescription) {
// Consent form error.
Log.d("SplashScreen", "Consent form error " + errorDescription);
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.build();
form.load();
form.show();
Here is my helper class for the Google Consent SDK that I use in my app. To initialise the consent information and display the Consent Form if needed, I have following code in onCreate() method of my main activity:
GdprHelper gdprHelper = new GdprHelper(this);
gdprHelper.initialise();
Similarly, I run following code when user clicks on "Reset my privacy consent" in preferences:
GdprHelper gdprHelper = new GdprHelper(this);
gdprHelper.resetConsent();
where both times, this is referencing current running activity.
Full implementation of the helper class:
package com.example.app;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import com.google.ads.consent.ConsentForm;
import com.google.ads.consent.ConsentFormListener;
import com.google.ads.consent.ConsentInfoUpdateListener;
import com.google.ads.consent.ConsentInformation;
import com.google.ads.consent.ConsentStatus;
import java.net.MalformedURLException;
import java.net.URL;
public class GdprHelper {
private static final String PUBLISHER_ID = "YOUR-PUBLISHER-ID";
private static final String PRIVACY_URL = "YOUR-PRIVACY-URL";
private static final String MARKET_URL_PAID_VERSION = "market://details?id=com.example.app.pro";
private final Context context;
private ConsentForm consentForm;
public GdprHelper(Context context) {
this.context = context;
}
// Initialises the consent information and displays consent form if needed
public void initialise() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.requestConsentInfoUpdate(new String[]{PUBLISHER_ID}, new ConsentInfoUpdateListener() {
#Override
public void onConsentInfoUpdated(ConsentStatus consentStatus) {
// User's consent status successfully updated.
if (consentStatus == ConsentStatus.UNKNOWN) {
displayConsentForm();
}
}
#Override
public void onFailedToUpdateConsentInfo(String errorDescription) {
// Consent form error. Would be nice to have proper error logging. Happens also when user has no internet connection
if (BuildConfig.BUILD_TYPE.equals("debug")) {
Toast.makeText(context, errorDescription, Toast.LENGTH_LONG).show();
}
}
});
}
// Resets the consent. User will be again displayed the consent form on next call of initialise method
public void resetConsent() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.reset();
}
private void displayConsentForm() {
consentForm = new ConsentForm.Builder(context, getPrivacyUrl())
.withListener(new ConsentFormListener() {
#Override
public void onConsentFormLoaded() {
// Consent form has loaded successfully, now show it
consentForm.show();
}
#Override
public void onConsentFormOpened() {
// Consent form was displayed.
}
#Override
public void onConsentFormClosed(
ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed. This callback method contains all the data about user's selection, that you can use.
if (userPrefersAdFree) {
redirectToPaidVersion();
}
}
#Override
public void onConsentFormError(String errorDescription) {
// Consent form error. Would be nice to have some proper logging
if (BuildConfig.BUILD_TYPE.equals("debug")) {
Toast.makeText(context, errorDescription, Toast.LENGTH_LONG).show();
}
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.withAdFreeOption()
.build();
consentForm.load();
}
private URL getPrivacyUrl() {
URL privacyUrl = null;
try {
privacyUrl = new URL(PRIVACY_URL);
} catch (MalformedURLException e) {
// Since this is a constant URL, the exception should never(or always) occur
e.printStackTrace();
}
return privacyUrl;
}
private void redirectToPaidVersion() {
Intent i = new Intent(
Intent.ACTION_VIEW,
Uri.parse(MARKET_URL_PAID_VERSION));
context.startActivity(i);
}
}
Ok I solved this way: create an instance of your form with the Builder and then you have to call the form.load().
Wait for the form to be loaded and call the .show() inside:
#Override
public void onConsentFormLoaded() {
// Consent form loaded successfully... now you can show it.
Log.d("SplashScreen", "Consent form Loaded ");
showConsentForm();
}
To accomplish this I created a private function :
private showConsentForm(){ form.show(); }
To see how the form works you can try this app:
https://play.google.com/store/apps/details?id=com.mapkcode.whereis
The simple answer is that the form cannot be shown until the form has completed loading. The docs on this nuance are rather dreadful. The fix is to call form.show() within onConsentFormLoaded() like this:
public class MyGdprHelper {
private ConsentForm form;
private void getUsersConsent() {
form = new ConsentForm.Builder(context, privacyUrl)
.withListener(new ConsentFormListener() {
#Override
public void onConsentFormLoaded() {
// Consent form loaded successfully.
form.show();
}
#Override public void onConsentFormOpened() {...}
#Override public void onConsentFormClosed(ConsentStatus consentStatus, Boolean userPrefersAdFree) {...}
#Override public void onConsentFormError(String errorDescription) {...}
)
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.withAdFreeOption()
.build();
form.load();
}
...
}
Based on #WebMajstr answer and #Frank's comment, here is my own class that has two additional features: A callback listener and non EEA users are checked.
package com.levionsoftware.photos.utils.consensus;
import android.content.Context;
import android.util.Log;
import com.google.ads.consent.ConsentForm;
import com.google.ads.consent.ConsentFormListener;
import com.google.ads.consent.ConsentInfoUpdateListener;
import com.google.ads.consent.ConsentInformation;
import com.google.ads.consent.ConsentStatus;
import com.google.ads.consent.DebugGeography;
import com.levionsoftware.photos.MyApplication;
import com.levionsoftware.photos.R;
import java.net.MalformedURLException;
import java.net.URL;
public class GdprHelper {
private static final String PUBLISHER_ID = "pub-2308843076741286";
private final Context context;
private final ConsensusUpdatedListener consensusUpdatedListener;
private ConsentForm consentForm;
public GdprHelper(Context context, ConsensusUpdatedListener consensusUpdatedListener) {
this.context = context;
this.consensusUpdatedListener = consensusUpdatedListener;
}
// Initialises the consent information and displays consent form if needed
public void initialise() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_EEA);
consentInformation.requestConsentInfoUpdate(new String[]{PUBLISHER_ID}, new ConsentInfoUpdateListener() {
#Override
public void onConsentInfoUpdated(ConsentStatus consentStatus) {
Log.d("GdprHelper", "onConsentInfoUpdated: " + consentStatus.toString());
if(consentInformation.isRequestLocationInEeaOrUnknown()) {
Log.d("GdprHelper", "isRequestLocationInEeaOrUnknown: true");
// If the isRequestLocationInEeaOrUnknown() method returns true:
// If the returned ConsentStatus is PERSONALIZED or NON_PERSONALIZED, the user has already provided consent. You can now forward consent to the Google Mobile Ads SDK.
// If the returned ConsentStatus is UNKNOWN, see the Collect consent section below, which describes the use of utility methods to collect consent.
// User's consent status successfully updated.
if (consentStatus == ConsentStatus.UNKNOWN) {
consensusUpdatedListener.reset();
displayConsentForm();
} else {
consensusUpdatedListener.set(consentStatus == ConsentStatus.NON_PERSONALIZED, false);
}
} else {
Log.d("GdprHelper", "isRequestLocationInEeaOrUnknown: false");
// If the isRequestLocationInEeaOrUnknown() method returns false:
// the user is not located in the European Economic Area and consent is not required under the EU User Consent Policy. You can make ad requests to the Google Mobile Ads SDK.
consensusUpdatedListener.set(false, true);
}
}
#Override
public void onFailedToUpdateConsentInfo(String errorDescription) {
// Consent form error. Would be nice to have proper error logging. Happens also when user has no internet connection
MyApplication.toastSomething(new Exception(errorDescription));
}
});
}
// Resets the consent. User will be again displayed the consent form on next call of initialise method
public void resetConsent() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.reset();
}
private void displayConsentForm() {
consentForm = new ConsentForm.Builder(context, getPrivacyUrl())
.withListener(new ConsentFormListener() {
#Override
public void onConsentFormLoaded() {
// Consent form has loaded successfully, now show it
consentForm.show();
}
#Override
public void onConsentFormOpened() {
// Consent form was displayed.
}
#Override
public void onConsentFormClosed(
ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed. This callback method contains all the data about user's selection, that you can use.
Log.d("GdprHelper", "onConsentFormClosed: " + consentStatus.toString());
if (consentStatus == ConsentStatus.UNKNOWN) {
consensusUpdatedListener.reset();
displayConsentForm();
} else {
consensusUpdatedListener.set(consentStatus == ConsentStatus.NON_PERSONALIZED, false);
}
}
#Override
public void onConsentFormError(String errorDescription) {
// Consent form error. Would be nice to have some proper logging
MyApplication.toastSomething(new Exception(errorDescription));
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
//.withAdFreeOption()
.build();
consentForm.load();
}
private URL getPrivacyUrl() {
URL privacyUrl = null;
try {
privacyUrl = new URL(MyApplication.get().getString(R.string.privacyPolicyURL));
} catch (MalformedURLException e) {
// Since this is a constant URL, the exception should never(or always) occur
e.printStackTrace();
}
return privacyUrl;
}
}
Listener:
package com.levionsoftware.photos.utils.consensus;
public interface ConsensusUpdatedListener {
void set(Boolean npa, Boolean consensusNotNeeded);
void reset();
}
Edit: See Android: Getting user's location using Admob's Consent SDK, isRequestLocationInEeaOrUnknown must be called AFTER onConsentInfoUpdated.
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import com.google.ads.consent.ConsentForm;
import com.google.ads.consent.ConsentFormListener;
import com.google.ads.consent.ConsentInfoUpdateListener;
import com.google.ads.consent.ConsentInformation;
import com.google.ads.consent.ConsentStatus;
import com.google.ads.consent.DebugGeography;
import com.google.ads.mediation.admob.AdMobAdapter;
import com.google.android.gms.ads.AdRequest;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private ConsentForm consentForm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getConsentInformation();
String android_id = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
Log.d("Android", "Android ID : " + android_id);
}
private void getConsentInformation() {
final ConsentInformation consentInformation = ConsentInformation.getInstance(MainActivity.this);
String[] publisherIds = {"pub-0123456789012345"};
consentInformation.requestConsentInfoUpdate(publisherIds, new ConsentInfoUpdateListener() {
#Override
public void onConsentInfoUpdated(ConsentStatus consentStatus) {
boolean inEEA = ConsentInformation.getInstance(MainActivity.this).isRequestLocationInEeaOrUnknown();
if (inEEA) {
switch (consentStatus) {
case PERSONALIZED:
personalizeAds(true);
break;
case NON_PERSONALIZED:
personalizeAds(false);
break;
case UNKNOWN:
displayConsentDialog();
break;
default:
break;
}
}
}
#Override
public void onFailedToUpdateConsentInfo(String reason) {
}
});
consentInformation.addTestDevice("33BE2250B43518CCDA7DE426D04EE231");
consentInformation.setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_EEA);
}
private void personalizeAds(boolean isPersonalize) {
AdRequest adRequest;
if (isPersonalize) {
adRequest = new AdRequest.Builder().build();
} else {
Bundle extras = new Bundle();
extras.putString("npa", "1");
adRequest = new AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter.class, extras).build();
}
}
private void displayConsentDialog() {
URL privacyUrl = null;
try {
// TODO: Replace with your app's privacy policy URL.
privacyUrl = new URL("PRIVACY_POLICY");
} catch (MalformedURLException e) {
e.printStackTrace();
// Handle error.
}
consentForm = new ConsentForm.Builder(this, privacyUrl).withListener(new ConsentFormListener() {
#Override
public void onConsentFormLoaded() {
super.onConsentFormLoaded();
consentForm.show();
}
#Override
public void onConsentFormClosed(ConsentStatus consentStatus, Boolean userPrefersAdFree) {
super.onConsentFormClosed(consentStatus, userPrefersAdFree);
if (consentStatus.equals(ConsentStatus.PERSONALIZED))
personalizeAds(true);
else
personalizeAds(false);
}
})
.withNonPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.build();
consentForm.load();
}
}
I have a problem with my first real android project. I need to start a new activity from this one down there, when the client tracker does recognize a target. It would mean the world to me if someone could help me.
The things I already tried, ended always in a disaster... probably because I have no idea what I’m doing (thats also the reason I'm not posting what I have tried)
P.S. I used the Wikitude native Api libary
package com.ia.grafp.maturapp2_2;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.ia.grafp.maturapp2_2.rendering.external.CustomSurfaceView;
import com.ia.grafp.maturapp2_2.rendering.external.Driver;
import com.ia.grafp.maturapp2_2.rendering.external.GLRenderer;
import com.wikitude.WikitudeSDK;
import com.wikitude.WikitudeSDKStartupConfiguration;
import com.wikitude.common.camera.CameraSettings;
import com.wikitude.common.rendering.RenderExtension;
import com.wikitude.common.tracking.RecognizedTarget;
import com.wikitude.rendering.ExternalRendering;
import com.wikitude.tracker.ClientTracker;
import com.wikitude.tracker.ClientTrackerEventListener;
import com.wikitude.tracker.Tracker;
/**
*/
public class ArchitectView extends AppCompatActivity implements ClientTrackerEventListener, ExternalRendering {
private static final String TAG = "ArchitectView";
private WikitudeSDK _wikitudeSDK;
private CustomSurfaceView _view;
private Driver _driver;
private GLRenderer _glRenderer;
private boolean tracking;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_wikitudeSDK = new WikitudeSDK(this);
WikitudeSDKStartupConfiguration startupConfiguration
= new WikitudeSDKStartupConfiguration
(WikitudeSDKConstants.WIKITUDE_SDK_KEY,
CameraSettings.CameraPosition.BACK,
CameraSettings.CameraFocusMode.CONTINUOUS);
_wikitudeSDK.onCreate(getApplicationContext(), this, startupConfiguration);
ClientTracker tracker
= _wikitudeSDK.getTrackerManager().create2dClientTracker
("file:///android_asset/magazine.wtc");
tracker.registerTrackerEventListener(this);
}
#Override
protected void onResume() {
super.onResume();
_wikitudeSDK.onResume();
_view.onResume();
_driver.start();
}
#Override
protected void onPause() {
super.onPause();
_wikitudeSDK.onPause();
_view.onPause();
_driver.stop();
}
#Override
protected void onDestroy() {
super.onDestroy();
_wikitudeSDK.onDestroy();
}
#Override
public void onRenderExtensionCreated(final RenderExtension renderExtension_) {
_glRenderer = new GLRenderer(renderExtension_);
_view = new CustomSurfaceView(getApplicationContext(), _glRenderer);
_driver = new Driver(_view, 30);
setContentView(_view);
}
#Override
public void onExtendedTrackingQualityUpdate(final Tracker tracker_, final String targetName_, final int oldTrackingQuality_, final int newTrackingQuality_) {
}
#Override
public void onErrorLoading(final ClientTracker clientTracker_, final String errorMessage_) {
Log.v(TAG, "onErrorLoading: " + errorMessage_);
}
#Override
public void onTrackerFinishedLoading(final ClientTracker clientTracker_, final String trackerFilePath_) {
}
#Override
public void onTargetRecognized(final Tracker tracker_, final String targetName_) {
}
#Override
public void onTracking(final Tracker tracker_, final RecognizedTarget recognizedTarget_) {
_glRenderer.setCurrentlyRecognizedTarget(recognizedTarget_);
}
#Override
public void onTargetLost(final Tracker tracker_, final String targetName_) {
_glRenderer.setCurrentlyRecognizedTarget(null);
}
}
#Override
public void onTargetRecognized(final Tracker tracker_, final String targetName_) {
Intent i = new Intent(ArchitectView.this, yourActivityClass.class);
startactivity(i);
}
I don't know if this answer your question, but that is the way of starting a new activity.
In my app, I am relying on onUserLeaveHint() method when the user presses the home button, but this method is also being called when you are starting multi window mode in android 7.0 by long pressing "recents button" (which I don't want to perform same thing that I do when home button been pressed). So I want to know if there is a way to detect which is which. Cheers!
Note: onMultiWindowModeChanged() being called after onUserLeaveHint()
I think this is what you're looking for.
HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
#Override
public void onHomePressed() {
// do something here...
}
#Override
public void onHomeLongPressed() {
}
});
mHomeWatcher.startWatch();
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
public class HomeWatcher {
static final String TAG = "hg";
private Context mContext;
private IntentFilter mFilter;
private OnHomePressedListener mListener;
private InnerRecevier mRecevier;
public HomeWatcher(Context context) {
mContext = context;
mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
}
public void setOnHomePressedListener(OnHomePressedListener listener) {
mListener = listener;
mRecevier = new InnerRecevier();
}
public void startWatch() {
if (mRecevier != null) {
mContext.registerReceiver(mRecevier, mFilter);
}
}
public void stopWatch() {
if (mRecevier != null) {
mContext.unregisterReceiver(mRecevier);
}
}
class InnerRecevier extends BroadcastReceiver {
final String SYSTEM_DIALOG_REASON_KEY = "reason";
final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
final String SYSTEM_DIALOG_REASON_LONG_PRESS = "assist";
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null) {
Log.e(TAG, "action:" + action + ",reason:" + reason);
if (mListener != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
mListener.onHomePressed();
} else if (reason.equals(SYSTEM_DIALOG_REASON_LONG_PRESS)) {
mListener.onHomeLongPressed();
}
}
}
}
}
}
}
public interface OnHomePressedListener {
public void onHomePressed();
public void onHomeLongPressed();
}
I have an activity with uses onOptionsItemSelected(MenuItem item) method in FolderActivity and I want to call this method on another activity (MainActivity)
the main activity uses CMU Sphinx - Speech Recognition Toolkit.
I need to call some methods from FolderActivity to MainActivity.
package com.evolution.filemanager.folders;
import static android.widget.Toast.makeText;
import java.io.File;
import java.util.ArrayList;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
import com.evolution.filemanager.FileManagerApplication;
import com.evolution.filemanager.about.AboutActivity;
import com.evolution.filemanager.clipboard.Clipboard;
import com.evolution.filemanager.clipboard.Clipboard.ClipboardListener;
import com.evolution.filemanager.clipboard.ClipboardFileAdapter;
import com.evolution.filemanager.favourites.FavouritesManager;
import com.evolution.filemanager.favourites.FavouritesManager.FavouritesListener;
import com.evolution.filemanager.nav_drawer.NavDrawerAdapter;
import com.evolution.utils.FontApplicator;
import com.evolution.utils.ListViewUtils;
import edu.cmu.pocketsphinx.demo.R;
public class FolderActivity extends Activity implements OnItemClickListener, ClipboardListener, FavouritesListener
{
public static class FolderNotOpenException extends Exception
{
}
private static final String LOG_TAG = "Main Activity";
public static final String EXTRA_DIR = FolderFragment.EXTRA_DIR;
DrawerLayout drawerLayout;
ActionBarDrawerToggle actionBarDrawerToggle;
File lastFolder=null;
private FontApplicator fontApplicator;
public static Activity FOLDERACTIVITY;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_folder);
setupDrawers();
Clipboard.getInstance().addListener(this);
FOLDERACTIVITY = this;
fontApplicator = new FontApplicator(getApplicationContext(), "Roboto_Light.ttf").applyFont(getWindow().getDecorView());
}
public FontApplicator getFontApplicator()
{
return fontApplicator;
}
#Override
protected void onDestroy()
{
Clipboard.getInstance().removeListener(this);
FileManagerApplication application = (FileManagerApplication) getApplication();
application.getFavouritesManager().removeFavouritesListener(this);
super.onDestroy();
}
public void setLastFolder(File lastFolder)
{
this.lastFolder = lastFolder;
}
#Override
protected void onPause()
{
if (lastFolder != null)
{
FileManagerApplication application = (FileManagerApplication) getApplication();
application.getAppPreferences().setStartFolder(lastFolder).saveChanges(getApplicationContext());
Log.d(LOG_TAG, "Saved last folder "+lastFolder.toString());
}
super.onPause();
}
public void setActionbarVisible(boolean visible)
{
ActionBar actionBar = getActionBar();
if (actionBar == null) return;
if (visible)
{
actionBar.show();
setSystemBarTranslucency(false);
}
else
{
actionBar.hide();
setSystemBarTranslucency(true);
}
}
#TargetApi(Build.VERSION_CODES.KITKAT)
protected void setSystemBarTranslucency(boolean translucent)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
if (translucent)
{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
else
{
WindowManager.LayoutParams params = getWindow().getAttributes();
params.flags &= (~WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setAttributes(params);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
}
public void setupDrawers()
{
this.drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer, R.string.open_drawer, R.string.close_drawer)
{
boolean actionBarShown = false;
#Override
public void onDrawerOpened(View drawerView)
{
makeText(getApplicationContext(), "drawer open", Toast.LENGTH_SHORT).show();
super.onDrawerOpened(drawerView);
setActionbarVisible(true);
invalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView)
{
makeText(getApplicationContext(), "drawer close", Toast.LENGTH_SHORT).show();
actionBarShown=false;
super.onDrawerClosed(drawerView);
invalidateOptionsMenu();
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset)
{
super.onDrawerSlide(drawerView, slideOffset);
if (slideOffset > 0 && actionBarShown == false)
{
actionBarShown = true;
setActionbarVisible(true);
}
else if (slideOffset <= 0) actionBarShown = false;
}
};
drawerLayout.setDrawerListener(actionBarDrawerToggle);
drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);
drawerLayout.setFocusableInTouchMode(false);
// drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.END);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
setupNavDrawer();
setupClipboardDrawer();
}
#Override
public void onBackPressed()
{
if (drawerLayout.isDrawerOpen(GravityCompat.START))
drawerLayout.closeDrawer(GravityCompat.START);
else if (drawerLayout.isDrawerOpen(GravityCompat.END))
drawerLayout.closeDrawer(GravityCompat.END);
else
super.onBackPressed();
}
void setupNavDrawer()
{
FileManagerApplication application = (FileManagerApplication) getApplication();
// add listview header to push items below the actionbar
ListView navListView = (ListView) findViewById(R.id.listNavigation);
ListViewUtils.addListViewPadding(navListView, this, true);
loadFavourites(application.getFavouritesManager());
application.getFavouritesManager().addFavouritesListener(this);
}
void setupClipboardDrawer()
{
// add listview header to push items below the actionbar
ListView clipboardListView = (ListView) findViewById(R.id.listClipboard);
ListViewUtils.addListViewHeader(clipboardListView, this);
onClipboardContentsChange(Clipboard.getInstance());
}
void loadFavourites(FavouritesManager favouritesManager)
{
ListView listNavigation = (ListView) findViewById(R.id.listNavigation);
NavDrawerAdapter navDrawerAdapter = new NavDrawerAdapter(this, new ArrayList<NavDrawerAdapter.NavDrawerItem>(favouritesManager.getFolders()));
navDrawerAdapter.setFontApplicator(fontApplicator);
listNavigation.setAdapter(navDrawerAdapter);
listNavigation.setOnItemClickListener(this);
}
#Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
actionBarDrawerToggle.syncState();
if (getFragmentManager().findFragmentById(R.id.fragment) == null)
{
FolderFragment folderFragment = new FolderFragment();
if (getIntent().hasExtra(EXTRA_DIR))
{
Bundle args = new Bundle();
args.putString(FolderFragment.EXTRA_DIR, getIntent().getStringExtra(EXTRA_DIR));
folderFragment.setArguments(args);
}
getFragmentManager()
.beginTransaction()
.replace(R.id.fragment, folderFragment)
.commit();
}
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
makeText(getApplicationContext(), "unsa ni?", Toast.LENGTH_SHORT).show();
super.onConfigurationChanged(newConfig);
actionBarDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
makeText(getApplicationContext(), item.toString(), Toast.LENGTH_SHORT).show();
if (actionBarDrawerToggle.onOptionsItemSelected(item))
return true;
switch (item.getItemId())
{
case R.id.menu_about:
startActivity(new Intent(getApplicationContext(), AboutActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
public void showFragment(Fragment fragment)
{
getFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.fragment, fragment)
.commit();
}
public void goBack()
{
getFragmentManager().popBackStack();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public FolderFragment getFolderFragment()
{
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment);
if (fragment instanceof FolderFragment)
return (FolderFragment) fragment;
else return null;
}
public File getCurrentFolder() throws FolderNotOpenException
{
FolderFragment folderFragment = getFolderFragment();
if (folderFragment == null)
throw new FolderNotOpenException();
else return folderFragment.currentDir;
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
switch (arg0.getId())
{
case R.id.listNavigation:
NavDrawerAdapter.NavDrawerItem item = (NavDrawerAdapter.NavDrawerItem) arg0.getItemAtPosition(arg2);
if (item.onClicked(this))
drawerLayout.closeDrawers();
break;
case R.id.listClipboard:
FolderFragment folderFragment = getFolderFragment();
if (folderFragment != null)
{
// TODO: paste single file
}
break;
default:
break;
}
}
public File getLastFolder()
{
return lastFolder;
}
#Override
public void onClipboardContentsChange(Clipboard clipboard)
{
invalidateOptionsMenu();
ListView clipboardListView = (ListView) findViewById(R.id.listClipboard);
if (clipboard.isEmpty() && drawerLayout != null)
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.END);
else
{
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END);
FileManagerApplication application = (FileManagerApplication) getApplication();
if (clipboardListView != null)
{
ClipboardFileAdapter clipboardFileAdapter = new ClipboardFileAdapter(this, clipboard, application.getFileIconResolver());
clipboardFileAdapter.setFontApplicator(fontApplicator);
clipboardListView.setAdapter(clipboardFileAdapter);
}
}
}
#Override
public void onFavouritesChanged(FavouritesManager favouritesManager)
{
loadFavourites(favouritesManager);
}
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event)
{
Log.d("Key Long Press", event.toString());
if (keyCode == KeyEvent.KEYCODE_BACK)
{
finish();
return true;
}
else return super.onKeyLongPress(keyCode, event);
}
}
and the activity where I want to call
package edu.cmu.pocketsphinx.demo;
import static android.widget.Toast.makeText;
import static edu.cmu.pocketsphinx.SpeechRecognizerSetup.defaultSetup;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.evolution.filemanager.about.AboutActivity;
import com.evolution.filemanager.folders.FolderActivity;
import com.evolution.utils.DataClearer;
import edu.cmu.pocketsphinx.Assets;
import edu.cmu.pocketsphinx.Hypothesis;
import edu.cmu.pocketsphinx.RecognitionListener;
import edu.cmu.pocketsphinx.SpeechRecognizer;
public class MainActivity extends Activity implements
RecognitionListener {
public AnimationDrawable rocketAnimation;
private static final String KWS_SEARCH = "wakeup";
private static final String FORECAST_SEARCH = "forecast";
private static final String DIGITS_SEARCH = "digits";
private static final String MENU_SEARCH = "menu";
private static final String KEYPHRASE = "frost";
private static final String GO_BACK = "back";
private static final String PREVIOUS = "previous";
private static final String OPEN_FILE_MANAGER = "open file manager";
private static final String OPEN_ABOUT = "open about";
private static final String OPEN_MUSIC = "open music";
private static final String OPEN_PICTURES = "open pictures";
private static final String OPEN_VIDEOS = "open videos";
private static final String SHOW_COMMANDS = "show commands";
private static final String CLOSE_FILE_MANAGER = "close file manager";
private static final String CLOSE_ABOUT = "close about";
private static final String CLOSE_MUSIC = "close music";
private static final String CLOSE_PICTURES = "close pictures";
private static final String CLOSE_VIDEOS = "close videos";
private static final String CLOSE_COMMANDS = "close commands";
private static final String SHOW_DRAWER = "show drawer";
private static final String HIDE_DRAWER = "hide drawer";
public static boolean isOPEN_FILE_MANAGER = false;
private static boolean isOPEN_ABOUT = false;
private static boolean isOPEN_MUSIC = false;
private static boolean isOPEN_PICTURES = false;
private static boolean isOPEN_VIDEOS = false;
private static boolean isSHOW_COMMANDS = false;
private static boolean isSHOW_DRAWER = false;
private static String MENU_CAPTION;
private SpeechRecognizer recognizer;
private HashMap<String, Integer> captions;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
// Prepare the data for UI
captions = new HashMap<String, Integer>();
captions.put(KWS_SEARCH, R.string.kws_caption);
captions.put(MENU_SEARCH, R.string.menu_caption);
captions.put(DIGITS_SEARCH, R.string.digits_caption);
captions.put(FORECAST_SEARCH, R.string.forecast_caption);
setContentView(R.layout.main);
((TextView) findViewById(R.id.caption_text))
.setText("Preparing the recognizer");
ImageView rocketImage = (ImageView) findViewById(R.id.imageViewAnim);
rocketImage.setBackgroundResource(R.drawable.heart_animation);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(PocketSphinxActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) findViewById(R.id.caption_text))
.setText("Failed to init recognizer " + result);
} else {
switchSearch(KWS_SEARCH);
}
}
}.execute();
}
#Override
public void onPartialResult(Hypothesis hypothesis) {
String text = hypothesis.getHypstr();
TextView tv = ((TextView) findViewById(R.id.caption_text));
if (text.equals(KEYPHRASE))
{
switchSearch(MENU_SEARCH);
rocketAnimation.start();
}
else if (text.equals(OPEN_FILE_MANAGER))
{
switchSearch(KWS_SEARCH);
Intent intent = new Intent (PocketSphinxActivity.this , FolderActivity.class);
startActivity(intent);
isOPEN_FILE_MANAGER = true;
}
else if (text.equals(CLOSE_FILE_MANAGER))
{
if(isOPEN_FILE_MANAGER == true)
{
switchSearch(KWS_SEARCH);
FolderActivity.FOLDERACTIVITY.finish();
isOPEN_FILE_MANAGER = false;
}
}
else if (text.equals(SHOW_COMMANDS))
{
switchSearch(KWS_SEARCH);
Intent intent = new Intent (PocketSphinxActivity.this , Commands.class);
startActivity(intent);
isSHOW_COMMANDS = true;
}
else if (text.equals(CLOSE_COMMANDS))
{
if(isSHOW_COMMANDS == true)
{
switchSearch(KWS_SEARCH);
Commands.SHOWCOMMANDS.finish();
}
}
else if (text.equals(OPEN_PICTURES))
{
switchSearch(KWS_SEARCH);
Intent intent = new Intent (PocketSphinxActivity.this , AboutActivity.class);
startActivity(intent);
}
else if(text.equals(OPEN_ABOUT))
{
switchSearch(KWS_SEARCH);
Intent intent = new Intent(PocketSphinxActivity.this, AboutActivity.class);
startActivity(intent);
isOPEN_ABOUT = true;
}
else if(text.equals(CLOSE_ABOUT))
{
if (isOPEN_ABOUT == true)
{
switchSearch(KWS_SEARCH);
AboutActivity.ABOUTACTIVITY.finish();
}
}
else if(text.equals(GO_BACK) || text.equals(PREVIOUS))
{
if(isOPEN_FILE_MANAGER == true )
{
FolderActivity.FOLDERACTIVITY//where i want to call onOptionsItemSelected
switchSearch(KWS_SEARCH);
}
}
else
{
switchSearch(KWS_SEARCH);
((TextView) findViewById(R.id.result_text)).setText(text);
}
}
#Override
public void onResult(Hypothesis hypothesis) {
((TextView) findViewById(R.id.result_text)).setText("");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onEndOfSpeech() {
if (DIGITS_SEARCH.equals(recognizer.getSearchName())
|| FORECAST_SEARCH.equals(recognizer.getSearchName())
|| OPEN_FILE_MANAGER.equals(recognizer.getSearchName()))
switchSearch(KWS_SEARCH);
}
private void switchSearch(String searchName) {
recognizer.stop();
recognizer.startListening(searchName);
String caption = getResources().getString(captions.get(searchName));
((TextView) findViewById(R.id.caption_text)).setText(caption);
}
private void setupRecognizer(File assetsDir) {
File modelsDir = new File(assetsDir, "models");
recognizer = defaultSetup()
.setAcousticModel(new File(modelsDir, "hmm/en-us-semi"))
.setDictionary(new File(modelsDir, "dict/cmu07a.dic"))
.setRawLogDir(assetsDir).setKeywordThreshold(1e-20f)
.getRecognizer();
recognizer.addListener(this);
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
// Create grammar-based searches.
File menuGrammar = new File(modelsDir, "grammar/menu.gram");
recognizer.addGrammarSearch(MENU_SEARCH, menuGrammar);
File digitsGrammar = new File(modelsDir, "grammar/digits.gram");
recognizer.addGrammarSearch(DIGITS_SEARCH, digitsGrammar);
// Create language model search.
File languageModel = new File(modelsDir, "lm/weather.dmp");
recognizer.addNgramSearch(FORECAST_SEARCH, languageModel);
}
#Override
protected void onStop(){
super.onStop();
}
//Fires after the OnStop() state
#Override
protected void onDestroy() {
super.onDestroy();
try {
trimCache(this); //clear cache to minimize the app size
DataClearer.getInstance().clearApplicationData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void trimCache(Context context) {
try {
File dir = context.getCacheDir();
if (dir != null && dir.isDirectory()) {
deleteDir(dir);
}
} catch (Exception e) {
// TODO: handle exception
}
}
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;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
}
the FolderActivity runs on top of the MainActivty but the voice recognition in MainActivity is still active and I want the voice itself do some manipulation in the FolderActivity
Here's a few suggestions:
Have FolderActivity register a BroadcastReceiver as a listener for a certain Intent. When MainActivity wants to do something in FolderActivity, it can send a broadcast Intent which will be seen by the BroadcastReceiver in FolderActivity, which can then call the appropriate method in the `Activity.
When MainActivity wants to do something in FolderActivity, it can launch FolderActivity again using an Intent with flag Intent.FLAG_ACTIVITY_SINGLE_TOP and some "extra" that describes what FolderActivity should do. In FolderActivity override onNewIntent(), read the passed Intent parameter and use it to determine what method to call in FolderActivity. Because the Activity was launched withIntent.FLAG_ACTIVITY_SINGLE_TOP, Android won't create a new instance of the Activity, it will just callonNewIntent()` on the existing instance.
Have FolderActivity set a public static variable of type Activity to a reference to itself in onCreate(). MainActivity can then call a method on FolderActivity by doing something like FolderActivity.activityReference.doSomething()
Method 3 is not the preferred method, since you need to make sure that you set the public static variable to null in FolderActivity.onDestroy() and there are other concerns (timing issues, memory leaks, etc.) that need to be dealt with properly.
NOTE: You probably don't want to call onOptionsItemSelected() directly. This method is called by the Android framework when an options item is selected by the user. You should call directly the method that actually does something, not this framework callback method.
I generated the below code from the default template SettingsActivity from Eclipse and ADT. I find it overly complicated. I also added some pieces myself. How can I improve the structure?
Currently Activity listener and a Fragment listener -> Better way?
Get rid of the static Preference proxyEmail = null; -> How? Is static OK?
How can I call/use findPreference(getText(R.string.key_proxy_email)) in onPreferenceChange() method (line 123)?
Refactor ideas?
package com.xyz.abc;
import java.util.List;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.widget.Toast;
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
private static final boolean ALWAYS_SIMPLE_PREFS = false;
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
setupSimplePreferencesScreen();
// TODO Not used at the moment
//final SharedPreferences sp = new SecureSharedPreferences(this, this.getSharedPreferences(MY_PREFS_FILE_NAME, Context.MODE_PRIVATE) );
SharedPreferences settings = getSharedPreferences(Global.PREFERENCES, 0);
boolean sent = settings.getBoolean(Global.PREF_SETTING_SENT, false);
if (sent) {
Toast.makeText(getApplicationContext(), Global.TOAST_MSG_SENT, Toast.LENGTH_LONG);
} else {
Toast.makeText(getApplicationContext(), Global.TOAST_MSG_ERROR, Toast.LENGTH_LONG);
}
}
private void setupSimplePreferencesScreen() {
if (!isSimplePreferences(this)) {
return;
}
addPreferencesFromResource(R.xml.pref_dummy); // Be able to display first title
PreferenceCategory fakeHeader = new PreferenceCategory(this);
fakeHeader.setTitle(R.string.pref_header_settings);
getPreferenceScreen().addPreference(fakeHeader);
addPreferencesFromResource(R.xml.pref_settings);
fakeHeader = new PreferenceCategory(this);
fakeHeader.setTitle(R.string.pref_header_advanced);
getPreferenceScreen().addPreference(fakeHeader);
addPreferencesFromResource(R.xml.pref_advanced);
fakeHeader = new PreferenceCategory(this);
fakeHeader.setTitle(R.string.pref_header_general);
getPreferenceScreen().addPreference(fakeHeader);
addPreferencesFromResource(R.xml.pref_general);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener(this);
toggleProxyEmail(findPreference(getText(R.string.key_via)), findPreference(getText(R.string.key_proxy_email)));
}
/** {#inheritDoc} */
#Override
public boolean onIsMultiPane() {
return isXLargeTablet(this) && !isSimplePreferences(this);
}
/**
* Helper method to determine if the device has an extra-large screen. For example, 10" tablets are extra-large.
*/
private static boolean isXLargeTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
}
private static boolean isSimplePreferences(Context context) {
return ALWAYS_SIMPLE_PREFS || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB || !isXLargeTablet(context);
}
/** {#inheritDoc} */
#Override
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onBuildHeaders(List<Header> target) {
if (!isSimplePreferences(this)) {
loadHeadersFromResource(R.xml.pref_headers, target);
}
}
private static Preference.OnPreferenceChangeListener bindPrefSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();
if (preference instanceof ListPreference) {
// For list preferences, look up the correct display value in the preference's 'entries' list.
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(stringValue);
// Set the summary to reflect the new value.
preference.setSummary(index >= 0 ? listPreference.getEntries()[index] : null);
} else {
// For all other preferences, set the summary to the value's simple string representation.
preference.setSummary(stringValue);
}
return true;
}
};
private static Preference.OnPreferenceChangeListener bindPrefKeyToEditTextListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object value) {
((CheckBoxPreference) preference).setChecked((Boolean) value);
toggleProxyEmail(preference, SettingsPreferenceFragment.proxyEmail);
return true;
}
};
private static void bindPreferenceSummaryToValue(Preference preference) {
preference.setOnPreferenceChangeListener(bindPrefSummaryToValueListener);
// Trigger the listener immediately with the preference's current value.
bindPrefSummaryToValueListener.onPreferenceChange(preference, PreferenceManager.getDefaultSharedPreferences(preference.getContext()).getString(preference.getKey(), ""));
}
private static void bindPreferenceKeyToEditText(Preference preference) {
preference.setOnPreferenceChangeListener(bindPrefKeyToEditTextListener);
// Trigger the listener immediately with the preference's current value.
bindPrefKeyToEditTextListener.onPreferenceChange(preference, PreferenceManager.getDefaultSharedPreferences(preference.getContext()).getBoolean(preference.getKey(), false));
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class SettingsPreferenceFragment extends PreferenceFragment {
static Preference proxyEmail = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_settings);
proxyEmail = findPreference(getText(R.string.key_proxy_email));
toggleProxyEmail(findPreference(getText(R.string.key_via)), proxyEmail);
bindPreferenceSummaryToValue(findPreference(getText(R.string.key_dest_email)));
bindPreferenceKeyToEditText(findPreference(getText(R.string.key_via)));
bindPreferenceSummaryToValue(findPreference(getText(R.string.key_proxy_email)));
bindPreferenceSummaryToValue(findPreference(getText(R.string.key_pwd)));
bindPreferenceSummaryToValue(findPreference(getText(R.string.key_provider)));
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class AdvancedPreferenceFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_advanced);
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPreferenceFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
bindPreferenceSummaryToValue(findPreference(getText(R.string.key_help)));
}
}
private static void toggleProxyEmail(Preference prefKey, Preference prefValue) {
if (prefKey instanceof CheckBoxPreference) {
if(((CheckBoxPreference) prefKey).isChecked()) {
prefValue.setEnabled(true);
} else {
prefValue.setEnabled(false);
}
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { // Only called in a normal Activity
if(key.equals(findPreference(getString(R.string.key_via)).getKey())) {
toggleProxyEmail(findPreference(getText(R.string.key_via)), findPreference(getText(R.string.key_proxy_email)));
}
}
}