I'm stuck with these problem several day now, I don't know what is my problem is. I really need some help now, hopping can help me out here. These is my code.
public class MainActivity extends AppCompatActivity implements LocationListener {
TextView text;
String trip;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.id_trip);
scheduleAlarm();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras){
}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
public void onLocationChanged(Location location) {
new MyAsyncTask ().execute();
}
public class MyAsyncTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... arg0) {
trip = "Hai";
return null;
}
#Override
protected void onPostExecute(String strFromDoInBg) {
text.setText(trip);
}
}
public void scheduleAlarm() {
Intent intent = new Intent(getApplicationContext(), Track.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, Track.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), 60 * 1000, pIntent);
}
}
Services class
public class Services extends Service {
public LocationManager locationManager;
public MainActivity listener;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MainActivity();
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, listener, null);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}}
Track class
public class Track extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, Services.class);
context.startService(i);
}}
And the error are :
java.lang.NullPointerException: Attempt to invoke virtual method
'android.view.View android.view.Window.findViewById(int)' on a null
object reference
Thanks
Here is your error :
TextView text = (TextView) main.findViewById(R.id.id_trip);
text.setText(string);
you cannot get TextView object like this from Service. Either create TextView object as static or use BroadcastReceiver.
You are returning null value from doInBackground, that is the reason you are getting NullPointerException.
Change MyAsyncTask code with the following code.
public class MyAsyncTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
if(text==null){
text = MainActivity.this.findViewById(R.id.id_trip);
}
}
#Override
protected String doInBackground(String... arg0) {
trip = "Hai";
return trip;
}
#Override
protected void onPostExecute(String strFromDoInBg) {
text.setText(strFromDoInBg);
}
}
Remove below 2 lines from setText(String str) methood.
MainActivity main = new MainActivity();
TextView text = (TextView) main.findViewById(R.id.id_trip);
Hope this will help you.
Related
I have codes in two classes
First class is ExampleBroadcastReceiver:
public class ExampleBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
boolean noConnectivity = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false
);
if (noConnectivity) {
Toast.makeText(context, "Disconnected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Connected", Toast.LENGTH_SHORT).show();
}
}
}
}
Second class is MainActivity:
public class MainActivity extends AppCompatActivity {
ExampleBroadcastReceiver exampleBroadcastReceiver = new ExampleBroadcastReceiver();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(exampleBroadcastReceiver, filter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(exampleBroadcastReceiver);
}
}
How can I make the two classes into one by passing the code from the ExampleBroadcastReceiver class to MainActivity? Is it possible? Please don't ask why. Thanks.
Use java interface to handle an event in MainActivity that occurs in ExampleBroadcastReceiver. This way you don't have to merge classes to share an event based data.
public class ExampleBroadcastReceiver extends BroadcastReceiver {
public interface ConnectivityMonitorCallback {
void onConnectivityChanged(boolean connectivity);
}
public ConnectivityMonitorCallback callback;
public ExampleBroadcastReceiver(#NonNull ConnectivityMonitorCallback eventCallback) {
callback = eventCallback;
}
#Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
boolean noConnectivity = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false
);
callback.onConnectivityChanged(noConnectivity);
}
}
}
Finally in the MainActivity you handle the event.
public class MainActivity extends AppCompatActivity {
ExampleBroadcastReceiver exampleBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Define event handling code here which occurs in ExampleBroadcastReceiver
exampleBroadcastReceiver = new ExampleBroadcastReceiver(new ExampleBroadcastReceiver.ConnectivityMonitorCallback {
#Override
void onConnectivityChanged(boolean connectivity) {
// Handle the event that occured in ExampleBroadcastReceiver
}
});
}
#Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(exampleBroadcastReceiver, filter);
}
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(exampleBroadcastReceiver);
}
}
I have a Service (Bound) which I am trying to start from my MainActivity.java. The below is my Main Activity code:
public class MainActivity extends AppCompatActivity {
Handler m_handler;
Runnable m_handlerTask ;
private static ServiceConnection sConnection;
static boolean serviceBound = false;
#Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, DataDownloaderService.class);
bindService(intent, sConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.NoActionBar);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
if (!Global.isMyServiceRunning(DataDownloaderService.class, this)) {
sConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
DataDownloaderService.LocalBinder binder = (DataDownloaderService.LocalBinder) service;
Global.dService = binder.getService();
serviceBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
serviceBound = false;
}
};
}
}
catch(Exception ex ){
String p="";
}
}
#Override
protected void onResume(){
super.onResume();
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
RefreshNowPlaying();
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
}
}
void RefreshNowPlaying(){
//Do something
}
}
The service code is as shown below:
public class DataDownloaderService extends Service {
private final IBinder dBinder = new LocalBinder();
public class LocalBinder extends Binder {
DataDownloaderService getService() {
// Return this instance of LocalService so clients can call public methods
return DataDownloaderService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return dBinder;
}
#Override
public void onCreate(){
}
#Override
public void onStart(Intent intent, int startid){
super.onStart(intent,startid);
Global.DataDownloaderServiceStatus = "STARTED";
}
#Override
public void onDestroy(){
Global.DataDownloaderServiceStatus = "STOPPED";
super.onDestroy();
}
}
I have also added the service to the AndroidManifest.xml under the Application element. However, I see that the service's onStart is never fired or the override onServiceConnected in the MainActivity is never called. I am new to Anrdoid development and Java. Can someone give me some pointers, please? I have noticed that the service's onCreate is getting hit, by putting breakpoints, but not onStart.
onStart() will be called only if the service was started via context.startService(), see here.
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);
}
}
Guys how Do I change the class signature to implement googleapiclient? If you click on image it shows the tutorial but doesn't show clearly what to do. I don't understand when it says implement it because I don't know how? Can anyone help?
Here is my code:
public class MainActivity extends ActionBarActivity {
//private LocationManager locationManager;
private Location currentLocation;
private TextView locationText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationText = (TextView) findViewById(R.id.textView1);
}
private void updateDisplay(){
if (currentLocation==null){
locationText.setText("determining your location...");
} else {
locationText.setText(
String.format("Your location:\n%2f, %.2f", currentLocation.getLatitude(),
currentLocation.getLongitude()));
}
}
private LocationListener mListener = new LocationListener(){
#Override
public void onLocationChanged(Location location){
currentLocation=location;
updateDisplay();
}
#Override
public void onProviderDisabled(String provider){
}
#Override
public void onProviderEnabled(String provider){
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras){
}
};
#Override
public void onResume(){
super.onResume();
//currentLocation = locationManager.getLastKnownLocation(locationManager.GPS_PROVIDER);
updateDisplay();
//locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0, 0, mListener);
}
#Override
public void onPause(){
super.onPause();
//locationManager.removeUpdates(mListener);
}
how Do I change the class signature to implement googleapiclient?
Add implements GoogleApiClient.ConnectionCallbacks to your class, and implement the methods that it requires.
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);
}
}
}