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?
Related
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();
}
How do i start a service when an activity is opened, I am using intent but the service isn't starting at all. Music is meant to be played when a certain page is opened, but no service is running at all.
This is the code i am using to start the service on the MainPage class.
public class BackgroundMusic extends Service implements Application.ActivityLifecycleCallbacks, Runnable {
MediaPlayer player;
private static final Handler uiHandler = new Handler(Looper.getMainLooper());
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.backgroundmusic);
player.setLooping(true);
player.setVolume(100, 100);
player.start();
Intent BackgrndMusic = new Intent(this, MainPage.class);
startService(BackgrndMusic);
getApplication().registerActivityLifecycleCallbacks(this);
}
#Override
public void onDestroy() {
super.onDestroy();
// stop listening for activities
getApplication().unregisterActivityLifecycleCallbacks(this);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onActivityStarted(Activity activity) {
// do not destroy this service
uiHandler.removeCallbacks(this);
}
#Override
public void onActivityStopped(Activity activity) {
// if an activity don't show up in 1 second, destroy this service
uiHandler.postDelayed(this, 1000);
}
#Override
public void run() {
// no more activity, destroy this service
stopSelf();
}
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
startService(BackgrndMusic);
}
#Override
public void onActivityResumed(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
startService(BackgrndMusic);
}
#Override
public void onActivityPaused(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
stopService(BackgrndMusic);
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
stopService(BackgrndMusic);
}
}
Use
#Override
protected void onResume()
{
super.onResume();
startService(foo);
}
#Override
protected void onDestroy()
{
super.onDestroy();
StopService(foo);
}
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");
}
}
This is my service class in that i increment the i value based on time...
public class BackService extends Service {
int i=0;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
pollForUpdates();
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
private void pollForUpdates() {
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("Service class called", "service class called "+i);
getRunningApps();
i++;
}
},0,1000);
}
private void getRunningApps()
{
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
I want to append the i value to the TextView. i.e the TextView value is dynamically change based on i value...
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, BackService.class));
TextView tx=(TextView)findViewById(R.id.textView1);
}}
how to append the i value to tx...
Thank you in advance..
You will need to register Broadcast receiver for Sending data back from Service to Activity.see these usefull example for communication between Activity to service :
http://androidexperinz.wordpress.com/2012/02/14/communication-between-service-and-activity-part-1/
http://androidexperinz.wordpress.com/2012/02/21/communication-between-service-and-activity-part-2/
http://blog.philippheckel.com/2012/06/10/android-example-communication-between-activity-and-service-using-messaging/
Use this
public class MainActivity extends Activity {
TextView tx;
RefreshBroadcastReciver mBroadCastReciver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, BackService.class));
tx =(TextView)findViewById(R.id.textView1);
}
#Override
protected void onResume() {
super.onResume();
mBroadCastReciver = new RefreshBroadcastReciver();
registerReceiver(mBroadCastReciver, new IntentFilter("sendData"));
}
private class RefreshBroadcastReciver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
tx.setText(intent.getIntExtra("i", 0)+"");
}
}
#Override
protected void onStop() {
super.onStop();
if(mBroadCastReciver!=null)
unregisterReceiver(mBroadCastReciver);
}
}
and your service is here
public class BackService extends Service {
int i=0;
Intent intent1;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
pollForUpdates();
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
intent1=new Intent("sendData");
}
private void pollForUpdates() {
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("Service class called", "service class called "+i);
getRunningApps();
i++;
Message msg=new Message();
msg.arg1=i;
handler.sendMessage(msg);
}
},0,1000);
}
private void getRunningApps()
{
}
#Override
public void onDestroy() {
super.onDestroy();
}
protected Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
intent1.putExtra("i", msg.arg1);
sendBroadcast(intent1);
}
};
}
I added a listener to the service called "BindService".
And then I killed the Activity which have added the listener to the "BindService".
"BindService" is still running. I can see it on DDMS of eclipse.
Now I started the Activity again and I want to add a listener to the "BindService" again.
How could I?
"BindService" is just a service which is counting number.
With the following code, after I start the Activity again and tap the button "button_sendwords", it starts to count number from 0 again. That is not my purpose.
public class MainActivity extends Activity {
private ICallbackService service;
private static final int CALLBACK_MESSAGE = 1;
private Handler handler = new Handler(){
#Override
public void dispatchMessage(Message msg){
if(msg.what == CALLBACK_MESSAGE){
TextView resultlbl = (TextView)findViewById(R.id.label_result);
resultlbl.setText((String)msg.obj);
}else{
super.dispatchMessage(msg);
}
}
};
private ICallbackListener listener = new ICallbackListener.Stub() {
#Override
public void receiveMessage(String message) throws RemoteException {
handler.sendMessage(handler.obtainMessage(CALLBACK_MESSAGE, message));
}
};
private ServiceConnection conn = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ICallbackService.Stub.asInterface(binder);
try{
service.addListener(listener);
}catch(RemoteException e){
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnSendWords = (Button)findViewById(R.id.button_sendwords);
btnSendWords.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, BindService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}
});
}
}