How to implement phonegap/cordova in android webview? - android

I need just a few minutes for someone to tell me if these steps are correct for implementing cordova in a android webview:
EDIT: Ok I finally got it working these are the right steps:
1) I create project: cordova create hello com.example.hello HelloWorld and enter the folder
2) cordova platform add android, cordova run android (cordova.jar is created) => the app is launched => device is ready is shown
3) I create a cordova_layout.xml in "/res/layout" with this code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<org.apache.cordova.CordovaWebView
android:id="#+id/cordova_web_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
4)Import the project (as an "existing project" in eclipse) and add to the main java file after imports:
public class HelloWorld extends Activity implements CordovaInterface {
private CordovaWebView cordova_webview;
private String TAG = "CORDOVA_ACTIVITY";
private final ExecutorService threadPool = Executors.newCachedThreadPool();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cordova_layout);
cordova_webview = (CordovaWebView) findViewById(R.id.cordova_web_view);
// Config.init(this);
String url = "file:///android_asset/www/index.html";
cordova_webview.loadUrl(url, 10000);
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
#Override
protected void onDestroy() {
super.onDestroy();
if (this.cordova_webview != null) {
this.cordova_webview
.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
this.cordova_webview.loadUrl("about:blank");
cordova_webview.handleDestroy();
}
}
#Override
public Activity getActivity() {
return this;
}
#Override
public ExecutorService getThreadPool() {
return threadPool;
}
#Override
public Object onMessage(String message, Object obj) {
Log.d(TAG, message);
if (message.equalsIgnoreCase("exit")) {
super.finish();
}
return null;
}
#Override
public void setActivityResultCallback(CordovaPlugin cordovaPlugin) {
Log.d(TAG, "setActivityResultCallback is unimplemented");
}
#Override
public void startActivityForResult(CordovaPlugin cordovaPlugin,
Intent intent, int resultCode) {
Log.d(TAG, "startActivityForResult is unimplemented");
}
}
NOTE: the activity name must match the one in manifest.xml
Hope it will help you.
Have a nice day!

If you want to load an url in a phonegap app then you may use the below code to load your first url from asset
public class MyPhoneGapActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html", 10000);
}
For embedding a cordova webview in native android application and loading an url use the below code
public class CordovaActivity extends Activity implements CordovaInterface {
private CordovaWebView cordova_webview;
private String TAG = "CORDOVA_ACTIVITY";
private final ExecutorService threadPool = Executors.newCachedThreadPool();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cordova_layout);
cordova_webview = (CordovaWebView) findViewById(R.id.cordova_web_view);
// Config.init(this);
String url = "file:///android_asset/www/index.html";
cordova_webview.loadUrl(url, 10000);
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
#Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
#Override
protected void onDestroy() {
super.onDestroy();
if (this.cordova_webview != null) {
this.cordova_webview
.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
this.cordova_webview.loadUrl("about:blank");
cordova_webview.handleDestroy();
}
}
#Override
public Activity getActivity() {
return this;
}
#Override
public ExecutorService getThreadPool() {
return threadPool;
}
#Override
public Object onMessage(String message, Object obj) {
Log.d(TAG, message);
if (message.equalsIgnoreCase("exit")) {
super.finish();
}
return null;
}
#Override
public void setActivityResultCallback(CordovaPlugin cordovaPlugin) {
Log.d(TAG, "setActivityResultCallback is unimplemented");
}
#Override
public void startActivityForResult(CordovaPlugin cordovaPlugin,
Intent intent, int resultCode) {
Log.d(TAG, "startActivityForResult is unimplemented");
}
}

Related

Handler's postDelayed's callback: Checking if the FragmentActivity is not null and not destroyed?

I have written this class:
public class SplashScreen extends AppCompatActivity {
private Handler the_transition_handler;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
}
#Override
protected void onStart() {
super.onStart();
startTheTransitionAfterTheSplashScreen();
}
#Override
protected void onDestroy() {
super.onDestroy();
the_transition_handler.removeCallbacksAndMessages(null);
}
private void startTheTransitionAfterTheSplashScreen() {
the_transition_handler = new Handler();
the_transition_handler.postDelayed(new Runnable() {
#Override
public void run() {
final Intent intentSplashScreenToActivityJustAfterSplashScreen = new Intent(SplashScreen.this, ActivityJustAfterSplashScreen.class);
startActivity(intentSplashScreenToActivityJustAfterSplashScreen);
overridePendingTransition(R.anim.animation_enter_activity, R.anim.animation_leave_activity);
finish();
}
}, 1000);
}
}
My question is: since the run callback is executed after the time I've indicated (according to this doc: https://developer.android.com/reference/android/os/Handler) , should I replace its content with the following code (assuming that being an AppCompatActivity)?
#Override
public void run() {
if(that == null || that.isDestroyed()) {
return;
}
final Intent intentSplashScreenToActivityJustAfterSplashScreen = new Intent(SplashScreen.this, ActivityJustAfterSplashScreen.class);
startActivity(intentSplashScreenToActivityJustAfterSplashScreen);
overridePendingTransition(R.anim.animation_enter_activity, R.anim.animation_leave_activity);
finish();
}
Note that Android Studio says that == null is always false and should be removed.
Use isDestroyed() || isFinishing() or just call removeCallbacksAndMessages to remove any pending posts of callbacks:
#Override
protected void onDestroy() {
if (the_transition_handler != null) {
the_transition_handler.removeCallbacksAndMessages(null);
}
super.onDestroy();
}

Read TextToSpeeh from splash Activity

I created a splash screen in Android Studio. Now I want a text to speech function to say:
Done by Me
This should happen when the splash screen opens. How do I go about this?
Here is my program so far:
public class CinemaList extends Activity {
private static int SPLASH_TIME_OUT = 4000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent homeIntent = new Intent(CinemaList.this, MovieList.class);
startActivity(homeIntent);
finish();
}
}, SPLASH_TIME_OUT);
}
}
I hope that you're enjoying learning Android development. It can be done as follows:
public class SplashActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {
private TextToSpeech mTts;
private static final String TAG = MainActivity.class.getName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTts = new TextToSpeech(this, this);
}
#Override
protected void onPause() {
if(mTts != null){
mTts.stop();
mTts.shutdown();
}
super.onPause();
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onDone(String utteranceId) {
Log.d(TAG, "Done: " + utteranceId);
Intent homeIntent = new Intent(CinemaList.this, MovieList.class);
startActivity(homeIntent);
}
#Override
public void onError(String utteranceId) {
Log.e(TAG, "Error: " + utteranceId);
}
#Override
public void onStart(String utteranceId) {
Log.i(TAG, "Started: " + utteranceId);
}
});
mTts.speak("Done by ME!", TextToSpeech.QUEUE_ADD, null);
} else {
Log.e(TAG, "Failed");
}
}
}
I took the liberty of starting the 'Cinema List' activity after the speech completes. However, you can continue to use your Handler if you wish.
Also, rather than calling finish() explicitly, I'd advise adding the noHistory flag to the SplashActivity in the manifest:
<activity
android:name=".SplashActivity"
android:noHistory="true"/>
The noHistory flag ensures that the Activity will not be there when back is pressed.
noHistory vs finish() - Which is preferred?

How to play music only in foreground

I have trouble to play music across all activity, I had implement service and handle onPause to stop the music when going to background (not visible to user).
The problem is when i navigate to another activity, the onPause method is called that make my music stop. How to fix this issue? I need to play my music across all my activity in foreground only and dont wan to play it when the application in the background. Appeciate anyone know how to solve this.
This is my base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startIntent = new Intent(getApplicationContext(), MusicService.class);
if(binder==null){
bindService(startIntent,this, Context.BIND_AUTO_CREATE);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(binder.getMyService()!=null){
stopService(startIntent);
unbindService(this);
}
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onPause() {
super.onPause();
if(binder!=null) {
binder.getMyService().pauseMusic();
}
}
#Override
protected void onResume() {
super.onResume();
if(binder!=null){
binder.getMyService().resumeMusic();
}
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MusicService.Binder) service;
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
this is my mainactivity extends base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startIntent = new Intent(MainActivity.this, MusicService.class);
startService(startIntent);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
public void how(View view) {
Intent intent = new Intent(this, AboutActivity.class);
this.startActivity(intent);
}
You could implement code that will track current activity in your app. (Good example: How to get current activity)
And stop music only when "current activity" is null.
PS: depending on your implementation of tracking current activity you might want to check current activity not onPause() right away but with some delay .
Don't stop the audio play in onPause() as Harin Kaklotar suggested. You can use his method of onDestroy() or you can have it in an asynchronous task and turn off the sound by using surfaceDestroyed(). You can refer the android documentation of AudioManager if you need anything else of the sort.
https://developer.android.com/reference/android/media/AudioManager.html
Hope I Helped :D
UPDATE
You can create a system to check if your app is in the foreground or background. This involves counting how many activities are paused. Add this to all your activities:
#Override
protected void onPause() {
super.onPause();
MainActivity.Pause++;
}
#Override
protected void onResume() {
super.onResume();
MainActivity.Pause--;
}
And in your MainActivty,
if (Pause == NUMBER_OF_ACTIVITIES) {
//PAUSE MUSIC HERE
}
You have to use ActivityLifecycleCallbacks to tell if you app is in the foreground or background.
For example:
public class DummyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
#Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { }
#Override public void onActivityStarted(Activity activity) { }
#Override public void onActivityResumed(Activity activity) { }
#Override public void onActivityPaused(Activity activity) { }
#Override public void onActivityStopped(Activity activity) { }
#Override public void onActivityDestroyed(Activity activity) { }
#Override public void onActivitySaveInstanceState(Activity activity, Bundle savedInstanceState) { }
}
public class OnApplicationForegroundBackgroundEnterCallbacks extends DummyActivityLifecycleCallbacks {
private Listener listener;
private int activityStartStopCounter = 0;
public interface Listener {
public void onEnterForeground();
public void onEnterBackground();
}
public OnApplicationForegroundBackgroundEnterCallbacks(Listener listener) {
this.listener = listener;
}
#Override public void onActivityStarted(Activity activity) {
if(++activityStartStopCounter == 1) listener.onEnterForeground();
}
#Override public void onActivityStopped(Activity activity) {
if(--activityStartStopCounter == 0) listener.onEnterBackground();
}
}
Then in Application.onCreate call:
registerActivityLifecycleCallbacks(new OnApplicationForegroundBackgroundEnterCallbacks(this));

java.lang.ExceptionInInitializerError When call service

When i run my project from eclipse its working perfectly.
After created signed apk, i've tested on my device. its throws below exception.
FATAL EXCEPTION: main
java.lang.ExceptionInInitializerError
at com.rvg.app.aws.RegisterService.onCreate(Unknown Source)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2529)
My SplashScreen class
public class SplashActivity extends BaseFragmentActivity {
private boolean isDestroyed = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spashscreen);
startRegisterService();
mHandler.sendEmptyMessageDelayed(1,4000l);
}
private void startRegisterService(){
if(!MyApplication.getSnsPreference().isRegistered()){
startService(new Intent(this, RegisterService.class));
}
}
#SuppressLint("HandlerLeak")
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what == 1 && !isDestroyed){
Intent intent;
if(MyApplication.getUserPrefs().isLoggedIn()){
intent = new Intent(SplashActivity.this, HomeActivity.class);
}
else{
intent = new Intent(SplashActivity.this, WelcomeActivity.class);
}
startActivity(intent);
finish();
}
};
};
#Override
protected void onDestroy() {
isDestroyed = true;
super.onDestroy();
}
}
and my RegisterService class
public class RegisterService extends Service{
private PushRegister mRegister;
#Override
public void onCreate() {
super.onCreate();
mRegister = new PushRegister(this);
startRegister();
}
private void startRegister(){
new AsyncTask<Void, Void, Boolean>(){
#Override
protected Boolean doInBackground(Void... params) {
return mRegister.registerSns();
}
protected void onPostExecute(Boolean result) {
stopSelf();
}
}.execute();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
How to solve this.?
When run from eclipse there is no problem. After signed apk i've loaded on sd card and installed. When open the app it crash.
What is the issue and how to solve it?

Need Help Installing Google Play Services in my game

I made this game using libGDX. I already uploaded the game to the play store.
Now I am having trouble installing Google play services to it.
-I followed the instructions and tried running the final .apk file, but after adding all, the Game says Game Unfortunately Stopped working.
Would anybody be able to help me? I dont know what is the problem thats causing the game to not run. There are no errors as well.
Here is my MainActivity File:
public abstract class MainActivity extends AndroidApplication
implements
GameHelperListener,
ActionResolver {
private GameHelper gameHelper;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
cfg.useGL20 = false;
initialize(new ZBGame(), cfg);
// initialize(new TutorialLibgdxGameservices(this), false);
gameHelper.setup(this);
// AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
// cfg.useGL20 = false;
// initialize(new ZBGame(), cfg);
}
public MainActivity() {
gameHelper = new GameHelper(this);
gameHelper.enableDebugLog(true, "GPGS");
}
/** Called when the activity is first created. */
#Override
public void onStart() {
super.onStart();
gameHelper.onStart(this);
}
#Override
public void onStop() {
super.onStop();
gameHelper.onStop();
}
#Override
public void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
gameHelper.onActivityResult(request, response, data);
}
#Override
public boolean getSignedInGPGS() {
return gameHelper.isSignedIn();
}
#Override
public void loginGPGS() {
try {
runOnUiThread(new Runnable() {
public void run() {
gameHelper.beginUserInitiatedSignIn();
}
});
} catch (final Exception ex) {
}
}
#Override
public void submitScoreGPGS(int score) {
gameHelper.getGamesClient().submitScore("CgkI_v3s4-UREAIQAQ", score);
}
#Override
public void getLeaderboardGPGS() {
startActivityForResult(
gameHelper.getGamesClient().getLeaderboardIntent("CgkI_v3s4-UREAIQAQ"), 100);
}
#Override
public void onSignInFailed() {
}
#Override
public void onSignInSucceeded() {
}
}
Thanks

Categories

Resources