It shows an error in "startActivity(i);".
Error: startActivity (android.content.Intent) in Activity cannot be
applied.
Here's code:
public class LoadingScreen extends AppCompatActivity {
private static int SplashInterval = 2000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loading_screen);
new Handler().postDelayed(new Runnable(){
#Override
public void run(){
//TODO Auto-generated method stub
Intent i = new Intent(LoadingScreen.this, MainActivity.class);
startActivity(i);
this.finish();
}
private void finish(){
//TODO Auto-generated method stub
}
},SplashInterval);
};
}
Try this,
public class LoadingScreen extends Activity {
private static int SplashInterval = 2000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loading_screen);
new Handler().postDelayed(new Runnable(){
#Override
public void run(){
//TODO Auto-generated method stub
Intent i = new Intent(LoadingScreen.this, MainActivity.class);
startActivity(i);
finish();
}
},SplashInterval);
};
}
Remove this line
this.finish();
which is written inside handler
rather do LoadingScreen.this.finish();
to achieve closing of this activity;
Related
I have two activities, my MainActivity runs TimerTask which increments "counter" value.
public class MainActivity extends AppCompatActivity {
public static int counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
counter++;
}
});
}
};
timer.schedule(timerTask, 0, 1000);
Intent intent = new Intent(this, MapActivity.class);
startActivity(intent);
}
}
My MapActivity is supposed to read this value upon button click.
public class MapActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
}
public void readCounter(View view){
Log.d("counter:", Integer.toString(MainActivity.counter));
}
}
Currently counter is declared as public static variable but since static variables are bad practice, what would be proper and elegant way to do it?
There's nothing wrong with static values. In face if you want to make it MVC and use model, you should probably wrap this value with a Singleton Model class.
But to simplify things I would only recommend to make sure you reset the value on MainActivity onCreate.
The android way to do it would be using services or startActivityForResult.
Bundles are used to add extra parameters to pass to the called activity. So you can get and use this extra parameter as you wish.
Here is how to do it:
in MainActivity:
Intent intent = new Intent(this, MapActivity.class);
intent.putExtra("counter", counter);
startActivity(intent);
in MapActivity:
Bundle extras = getIntent().getExtras();
int counter = extras.getIntExtra("counter");
EDIT 1: For continuous update use custom listener interface
public class MainActivity extends AppCompatActivity {
public static int counter = 0;
private MyCounterUtil util;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler handler = new Handler();
util = MyCounterUtil.getInstance();
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
counter++;
util.notifyUpdate(counter);
}
});
}
};
timer.schedule(timerTask, 0, 1000);
Intent intent = new Intent(this, MapActivity.class);
startActivity(intent);
}
}
Create this class
public class MyCounterUtil {
private static MyCounterUtil mInstance;
private MyCounterListener mListener;
private MyCounterUtil() {}
public static MyCounterUtil getInstance() {
if(mInstance == null) {
mInstance = new MyCounterUtil();
}
return mInstance;
}
public void setListener(MyCounterListener listener) {
mListener = listener;
}
private void notifyUpdate(int count) {
if(mListener != null)
mListener.onUpdate(count);
}
public interface MyCounterListener{
public void onUpdate(int count);
}
}
Implement listener interface in MapActivity
public class MapActivity extends AppCompatActivity implements MyCounterListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
MyCounterUtil.getInstance().setListener(this);
}
/*
public void readCounter(View view){
Log.d("counter:", Integer.toString(MainActivity.counter));
}
*/
#Override
public void onUpdate(int count){
Log.d("counter:", Integer.toString(count));
}
}
EDIT 2:
Another clean and simple approach without TimerTask is using system time as counter and pass its first value with intent or sharedpreferences.
in MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putLong("startTime", System.currentTimeMillis());
editor.apply();
*/
Intent intent = new Intent(this, MapActivity.class);
intent.putExtra("startTime", System.currentTimeMillis());
startActivity(intent);
}
}
in MapActivity:
public class MapActivity extends AppCompatActivity {
private long startTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
/* in case use of sharedpref
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
startTime = preferences.getLong("startTime", 0);
*/
//in case use of bundle
startTime = getIntent().getExtras().getLongExtra("startTime", 0);
}
public void readCounter(View view){
long counter = (System.currentTimeMillis() - startTime)/1000;
Log.d("counter:", "" + counter);
}
}
I have a Main Activity from where I call an Splash Screen Intent which destroys itself after 3 seconds but between the lifecycle of the Splash Screen Intent the Main Activity destroys itself too (which is wrong!).. so when the Splash Screen Intent is finished the App crashes because the Main Activity has been destroyed itself.
I really Appreciate if someone can help me with this, I'm really out of ideas at this point.
Here's my code:
MainActivity.java
public class MainActivity extends Activity {
private WebView webview;
public MainActivity() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
log.debug("onCreate(): " + savedInstanceState);
MyApplication.startSomeMobileCore(this);
MyApplication.startSomeMobileNotifier(this);
setContentView(R.layout.main);
this.onNewIntent(this.getIntent());
}
#Override
protected void onStart() {
log.debug("onStart()");
super.onStart();
}
#Override
protected void onRestart() {
super.onRestart();
this.wasRestarted = true;
}
#Override
protected void onResume() {
super.onResume();
}
protected void onPause() {
super.onPause();
this.receivedIntent = false;
}
protected void onStop() {
super.onStop();
this.receivedIntent = false;
}
public void onDestroy() {
super.onDestroy();
}
#Override
public void onNewIntent(Intent intent) {
log.debug("onNewIntent(): " + intent);
super.onNewIntent(intent);
if(intent == null) {
log.warn("Received null intent, will ignore");
}
if ("OK".equals(authCode)) {
if (intent != null && intent.getData() != null &&
("content".equals(intent.getData().getScheme()) ||
"http".equals(intent.getData().getScheme()))) {
log.debug("intent.getData() :" + intent.getData() + "; intent.getData().getScheme() : " + intent.getData().getScheme());
String requestedPath;
if ("http".equals(intent.getData().getScheme())) {
requestedPath = URLDecoder.decode(intent.getData().toString());
} else {
requestedPath = intent.getData().getPath();
}
showResource(requestedPath);
} else {
log.debug("Intent without data -> go to entry page after splash screen");
showResource(Configuration.properties.getProperty("PORTAL"));
}
} else {
Intent errorIntent = new Intent(this, ErrorIntent.class);
startActivity(errorIntent);
// finish actual activity
finish();
}
log.debug("Show splash screen");
Intent intentSplash = new Intent(this, SplashIntent.class);
startActivity(intentSplash);
}
void showResource(String resourceToShow) {
webview = (WebView)findViewById(R.id.browser);
webview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
webview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
webview.setWebViewClient(new WebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setDomStorageEnabled(true);
webview.loadUrl(resourceToShow);
}
}
}
here is my SplashIntent.java
public class SplashIntent extends Activity {
// Time splash screen should be shown (in ms)
private static final int splashTime = 3000;
static Logger log = Logger.getLogger(SplashIntent.class);
#Override
public void onCreate(final Bundle savedInstanceState) {
log.debug("SplashIntent: onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
log.debug("SplashIntent: killing splash");
finish();
}
}, splashTime);
}
}
here is a part of logcat
There doesn't seem to be any reason to override onNewInent in your MainActivity.
In the onCreate() method use the following:
if(savedInstanceState == null){
Intent splashIntent = new Intent(this, SplashIntent.class);
startActivity(splashIntent);
}
This will start the splash screen whenever the MainActivity is initialized without a saved state. Since your SplashIntent activity calls finish after it is done it should revert to the last activity in the stack (aka your MainActivity).
An even better way to do this would be to use your SplashIntent activity as your launcher activity and then forward the user to the MainActivity using an intent.
Very simple example would be:
public class SplashIntent extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
log.debug("SplashIntent: onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
log.debug("SplashIntent: killing splash");
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}, splashTime);
}
}
Try startActivityForResult to launch splash screen (SplashIntent).
instead of
Intent intentSplash = new Intent(this, SplashIntent.class);
startActivity(intentSplash);
Try the below
startActivityForResult
And then from SplashIntent.java
Intent i = new Intent();
setResult(Activity.RESULT_OK,i); //pass your result
finish(); // Call finish to remove splash from the stack
Ref link :
http://developer.android.com/training/basics/intents/result.html
Sample code :
public class MainActivity extends Activity {
static final int SHOW_SPLASH_SCREEN_REQUEST = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showSplashSCreen();
}
private void showSplashSCreen() {
Intent intentSplash = new Intent(this, SplashActivity.class);
startActivityForResult(intentSplash,
SHOW_SPLASH_SCREEN_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
// Check which request we're responding to
if (requestCode == SHOW_SPLASH_SCREEN_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// code to handle anything after splash screen finished.
}
}
}
}
Splash Screen :
public class SplashActivity extends Activity {
private static final int splashTime = 3000;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// optional per your requirement
setResult(MainActivity.SHOW_SPLASH_SCREEN_REQUEST);
// must call finish
finish();
}
}, splashTime);
}
}
Can I know how to create AsyncTask for Android from all of these? I would like to remove the buttons and let all of these run in the background then redirect to the MainPage.java after clicking Logout.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
Button btnDelete = (Button)findViewById(R.id.delete);
Button btnSignUp = (Button)findViewById(R.id.btnSignUp);
Button btnLogin = (Button)findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(getApplicationContext(),HomePage.class);
startActivity(intent);
}
});
btnSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,SignUp.class);
startActivity(intent);
}
});
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
cDB.resetTables();
mDB.resetTables();
db.resetTables();
pDB.resetTables();
}
});
}
here is one AsyncTask Example. This will show a peogress dialog while executing the task.
private class LoginProcessing extends AsyncTask<Object, Void, Void> {
private LoginCredentials myLoginCredentials;
private ProgressDialog progressDialog;
public LoginProcessing(LoginCredentials Credentials) {
super();
myLoginCredentials=Credentials;
}
protected void onPreExecute (){
progressDialog = ProgressDialog.show(context, "", "Please Wait...",true);
}
#Override
protected Void doInBackground(Object... arg0) {
// TODO Auto-generated method stub
//Code to do the process in background
return null;
}
protected void onPostExecute(Void result){
progressDialog.dismiss();
//Your code after the process
}
}
You can call this Task as,
new LoginProcessing(loginCredentials).execute();
In this Example loginCredentials is the parameter I am passing to the AsyncTask. You can change it to your own parameter.
Edit 1
I need to call a method from BroadcastReceiver and method exist in the Activity class mention below.
I tried this code and got NULL_POINTER_EXCEPTION where I create the reference the MainActivity class.
Correct me what I'm doing wrong ?
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void myTesting(){
Toast.makeText(MainActivity.this, "Welcome to Activity", Toast.LENGTH_SHORT).show();
}
}
BroadcastReceiver.java
public class BootCompeteReceiver extends BroadcastReceiver {
public Context mContext;
private MainActivity mainActivity;
#Override
public void onReceive(Context context, Intent intent) {
mContext = context;
try {
mainActivity = new MainActivity();
mainActivity.myTesting();
} catch (Exception e) {
Toast.makeText(context, ""+e, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
Do something like that:
public class MainActivity extends Activity {
private BroadcastReceiver receiver = new BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
MainActivity.this.myTesting();
} catch (Exception e) {
Toast.makeText(MainActivity.this, ""+e, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intFilt = new IntentFilter(Constants.YOUR_BROADCAST_RECEIVER_ACTION);
registerReceiver(receiver, intFilt);
}
public void myTesting(){
Toast.makeText(MainActivity.this, "Welcome to Activity", Toast.LENGTH_SHORT).show();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
You can startActivity in onReceive, and call myTesting in onCreate of your Activity.
You can try this:
public class MainActivity extends Activity {
private static volatile int INSTANCE_COUNTER = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
INSTANCE_COUNTER++;
IntentFilter intentFilter = new IntentFilter("com.your.package.ACTION");
registerReceiver(mWhateverReceiver, intentFilter);
if (getIntent().getBooleanExtra("fromYourReceiver", false)) {
myTesting();
}
}
private void myTesting() {
// Do something here
}
private BroadcastReceiver mWhateverReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
myTesting();
}
};
public static boolean isInstanceExist() {
return INSTANCE_COUNTER > 0;
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
INSTANCE_COUNTER--;
unregisterReceiver(mWhateverReceiver);
}
}
Your receiver
public class BootCompeteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (MainActivity.isInstanceExist()) {
// There is already one instance of MainActivity, so broadcast this
// event to trigger the receiver inside MainActivity to do your task
Intent broadcastIntent = new Intent("com.your.package.ACTION");
context.sendBroadcast(broadcastIntent);
} else {
// There is no instances of MainActivity exist, so start a new one
// with the action that let the instance know what it should do
Intent activityIntent = new Intent(context, MainActivity.class);
activityIntent.putExtra("fromYourReceiver", true);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activityIntent);
}
}
}
I want to create an activity that opens when I start my app, wait some time and jumps to the next activity without the user pressing anything.
Here is my code:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread();
thread.start();
}
public class waitSeconds extends Thread {
public void run() {
Log.i("MyActivity", "MyClass");
try {
wait(300);
Intent intent = new Intent(MainActivity.this, main_window.class);
startActivity(intent);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
As it seems that it is never going to the "run" method.
How can I do this?
include this in your Activity:
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SplashHandler handler=new SplashHandler();
Message msg = new Message();
msg.what = 0;
handler.sendMessageDelayed(msg, 3000);
}
private class SplashHandler extends Handler {
public void handleMessage(Message msg)
{
switch (msg.what)
{
default:
case 0:
super.handleMessage(msg);
Intent intent = new Intent(MainActivity.this,main_window.class);
startActivity(intent);
MainActivity.this.finish();
}
}
}
you need something like this:
public class SplashScreenActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
new Thread() {
public void run() {
try {
Intent i = new Intent(SplashScreenActivity.this,
MainActivity.class);
Thread.sleep(2000);
startActivity(i);
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}