I'm trying to do an exercise from edx.org (Chat Firebase, whole code from https://github.com/ykro/android-chat-firebase) and I cannot understand where does this error comes, it's a NPE but it's getting me off, it crashes when application runs on Genymotion Emulator.
ERROR
java.lang.RuntimeException: Unable to start activity ComponentInfo{cat.edx_manel.exercises.chatfirebase/cat.edx_manel.exercises.chatfirebase.activities.LoginActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setEnabled(boolean)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setEnabled(boolean)' on a null object reference
at cat.edx_manel.exercises.chatfirebase.activities.LoginActivity.setInputs(LoginActivity.java:114)
at cat.edx_manel.exercises.chatfirebase.activities.LoginActivity.disableInputs(LoginActivity.java:57)
at cat.edx_manel.exercises.chatfirebase.implementations.login.LoginPresenterImpl.checkForAuthenticateUser(LoginPresenterImpl.java:43)
at cat.edx_manel.exercises.chatfirebase.activities.LoginActivity.onCreate(LoginActivity.java:46)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
LOGINACTIVITY
public class LoginActivity extends AppCompatActivity implements LoginView {
#BindView(R.id.user)
EditText inputEmail;
#BindView(R.id.pass)
EditText inputPassword;
#BindView(R.id.signIn)
Button btnSignIn;
#BindView(R.id.signUp)
Button btnSignUp;
#BindView(R.id.progressBar)
ProgressBar progressBar;
#BindView(R.id.layoutMainContainer)
RelativeLayout container;
private LoginPresenter loginPresenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
loginPresenter = new LoginPresenterImpl(this);
loginPresenter.onCreate();
loginPresenter.checkForAuthenticateUser();
}
#Override
protected void onDestroy() {
loginPresenter.onDestroy();
super.onDestroy();
}
#Override
public void disableInputs() {
setInputs(false);
}
#Override
public void enableInputs() {
setInputs(true);
hideProgress();
}
#Override
public void showProgress() {
progressBar.setVisibility(View.VISIBLE);
}
#Override
public void hideProgress() {
progressBar.setVisibility(View.INVISIBLE);
}
#Override
#OnClick(R.id.signUp)
public void handleSignUp() {
loginPresenter.registerNewUser(inputEmail.getText().toString(),
inputPassword.getText().toString());
}
#Override
#OnClick(R.id.signIn)
public void handleSignIn() {
loginPresenter.validateLogin(inputEmail.getText().toString(),
inputPassword.getText().toString());
}
#Override
public void navigateToMainScreen() {
startActivity(new Intent(this, ContactListActivity.class));
}
#Override
public void loginError(String error) {
inputPassword.setText("");
String msgError = String.format(getString(R.string.login_error_message_signin), error);
inputPassword.setError(msgError);
}
#Override
public void newUserSuccess() {
Snackbar.make(container, R.string.login_error_message_signup, Snackbar.LENGTH_SHORT).show();
}
#Override
public void newUserError(String error) {
inputPassword.setText("");
String msgError = String.format(getString(R.string.login_error_message_signup), error);
inputPassword.setError(msgError);
}
private void setInputs(boolean enabled) {
btnSignIn.setEnabled(enabled);
btnSignUp.setEnabled(enabled);
inputEmail.setEnabled(enabled);
inputPassword.setEnabled(enabled);
}
}
As you can see, button is binded by Butterknife framework, but I don't know what causes it...
Thanks you very much
UPDATED
LAYOUT
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layoutMainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".activities.LoginActivity">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="Name"
android:ems="10"
android:id="#+id/user"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="Password"
android:ems="10"
android:id="#+id/pass"/>
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:id="#+id/layoutButtons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/signIn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/signUp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar"
android:layout_below="#id/layoutButtons"/>
UPDATE 2
LOGINVIEW INTERFACE
public interface LoginView {
void enableInputs();
void disableInputs();
void showProgress();
void hideProgress();
void handleSignUp();
void handleSignIn();
void navigateToMainScreen();
void loginError(String error);
void newUserSuccess();
void newUserError(String error);
}
First, here is one of my answers I shared to setup ButterKnife correctly.
Consider this possible issue:
What are you Overriding here?
#Override //this line here
#OnClick(R.id.signUp)
public void handleSignUp() {
loginPresenter.registerNewUser(inputEmail.getText().toString(),
inputPassword.getText().toString());
}
#Override //this line here
#OnClick(R.id.signIn)
public void handleSignIn() {
loginPresenter.validateLogin(inputEmail.getText().toString(),
inputPassword.getText().toString());
}
Try this instead without the overrides:
#OnClick(R.id.signUp)
public void handleSignUp() {
loginPresenter.registerNewUser(inputEmail.getText().toString(),
inputPassword.getText().toString());
}
#OnClick(R.id.signIn)
public void handleSignIn() {
loginPresenter.validateLogin(inputEmail.getText().toString(),
inputPassword.getText().toString());
}
Then clean your project and run again!
I hope this helps!
I'm referring to the tutorial at ButterKnife tutorial. I think instead of using #BindView it should be #Bind
#Bind(R.id.button)
Button button;
#Bind(R.id.textView)
TextView textView;
#Bind(R.id.radioButton)
RadioButton radioButton;
#Bind(R.id.checkBox)
Related
when i try to run this app after enter the emulator when it's try to open the apps suddenly it's stop.
This is my logcat
2021-01-09 20:43:41.905 12890-12890/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 12890
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.ClassCastException: com.google.android.material.textview.MaterialTextView cannot be cast to android.widget.EditText
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.ClassCastException: com.google.android.material.textview.MaterialTextView cannot be cast to android.widget.EditText
at com.example.myapplication.MainActivity.onCreate(MainActivity.java:44)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
mainactivity
public class MainActivity extends AppCompatActivity {
private EditText mPhoneNumber, mCode;
private Button msend;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
String mVerificationId;
#SuppressLint("WrongViewCast")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseApp.initializeApp(this);
userIsLoggedIn();
mPhoneNumber = findViewById(R.id.phoneNumber);
mCode = findViewById (R.id.code);
msend= findViewById(R.id.send);
msend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mVerificationId!=null)
verifyPhoneNumberWithCode();
else
startPhoneNumberVerification();
}
});
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks(){
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential){
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
}
#Override
public void onCodeSent(String verificationeId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(verificationeId, forceResendingToken);
mVerificationId = verificationeId;
msend.setText("Verify Code");
}
};
}
private void verifyPhoneNumberWithCode(){
PhoneAuthCredential credential= PhoneAuthProvider.getCredential(mVerificationId, mCode.getText().toString());
signInWithPhoneAuthCredential(credential);
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential phoneAuthCredential){
FirebaseAuth .getInstance().signInWithCredential(phoneAuthCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful())
userIsLoggedIn();
}
});
}
private void userIsLoggedIn() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user !=null){
startActivity(new Intent(getApplicationContext(),MainActivity.class));
finish();
return;
}
}
private void startPhoneNumberVerification() {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
mPhoneNumber.getText().toString(),
60,
TimeUnit.SECONDS,
this,
mCallbacks);
}
}
2nd activity
package com.example.myapplication;
public class MainPageActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_page);
Button mlogout = findViewById(R.id.logout);
mlogout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FirebaseAuth.getInstance().signOut();
Intent intent= new Intent(getApplicationContext(), MainActivity.class);
//to clear the activity after logout instant
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return;
}
});
}
}
activitymainxml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="MainActivity"
android:layout_alignParentTop="true"
tools:actionBarNavMode="standard"
android:orientation="vertical">
<TextView
android:id="#+id/phoneNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Enter Phone Number" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Enter Code"
android:id="#+id/code"/>
<Button
android:id="#+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Verification Code" />
</LinearLayout>
You got this in your exception:
java.lang.ClassCastException: com.google.android.material.textview.MaterialTextView cannot be cast to android.widget.EditText
This means you are trying to cast TextView to EditText. So I guess one of these two:
private EditText mPhoneNumber, mCode;
is TextView inside your XML layout.
EDIT: Just saw you have posted your XML code. So your mPhoneMumber and mCode are both TextView. If you want them to be EditText just use EditText. But since you are using MaterialTheme I guess then try to use following:
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:text="wadwada"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
For more about this check this link on Material Design: https://material.io/components/text-fields/android#using-text-fields
When I change the seekbar in spite of showing the value it says "unfortunately SeekBarActivity has been stopped"
activity_main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<SeekBar
android:id="#+id/sb"
android:layout_width="match_parent"
android:layout_height="63dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="178dp"
tools:layout_editor_absoluteX="99dp"
tools:layout_editor_absoluteY="201dp" />
<TextView
android:id="#+id/tv"
android:layout_width="326dp"
android:layout_height="64dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/sb"
android:layout_marginStart="14dp"
android:text=""
tools:ignore="UnknownId"
tools:layout_editor_absoluteX="99dp"
tools:layout_editor_absoluteY="219dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="14dp" />
<RatingBar
android:id="#+id/rb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="53dp" />
</RelativeLayout>
MainActivity.java file
package com.example.mypc.seekbarapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.*;
public class MainActivity extends AppCompatActivity {
TextView tv;
SeekBar sb;
RatingBar rb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
sb=(SeekBar)findViewById(R.id.sb);
rb=(RatingBar)findViewById(R.id.rb);
sb.setMax(100);
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int pro=0;
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
pro=progress;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
tv.setText(pro);
//
Toast.makeText(MainActivity.this,pro,Toast.LENGTH_LONG).show();
}
});
rb.setOnRatingBarChangeListener(new
RatingBar.OnRatingBarChangeListener() {
#Override
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
Toast.makeText(MainActivity.this,
String.valueOf(rating),Toast.LENGTH_LONG)
.show();
}
});
}
}
my Stack trace:
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller
.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
09-04 17:37:04.097 2773-2773/? I/Process: Sending signal. PID: 2773 SIG:
9
Where I am wrong?? Any help will b appreciated, thanks in advance.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
My guess is that the mediastream isn't keeping up with the position of the seeker.
When you update the seeker, make sure the content you're trying to seek to is already in queue.
you are calling tv.setText(pro); when pro is an int value int argument in setText is an string id such as R.string.some_id when you call it with an int and Android can not find string resource with an id equals to pro value you get Resource not found exception. you should change it to:
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int pro=0;
String proStr = "";
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
pro=progress;
proStr = String.valueOf(pro);// convert int to String
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
tv.setText(proStr); // use String instead of int
Toast.makeText(MainActivity.this, proStr, Toast.LENGTH_LONG).show(); // use String instead of int
}
});
i am making a image downloading android app that takes a certain number of image urls, creates GUI for required for the number of urls provided and then displays them. I succeeded in doing so. Now i am trying to separate a module of this task. In order to do so i want to do everything out of the MainActivity class. The MainActivity class just provides the input in the form of urls and then takes the result back and displays it.
JAVA Code:
MainActivity Class:
public class MainActivity extends AppCompatActivity {
ArrayList<String> urls = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addUrls();
}
public void downloadImages(View view){
Manager manager = new Manager(MainActivity.this,urls);
manager.downloadImages();
}
public void addUrls() {
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTXEZRoYOhIJxL5foNz_NlatDlgYStzZgVIiKuo6vtRtz2wY-8b4Q");
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSFL3WYbqNOX-dwjtT1LroBlY5W-3YuwSIuCMRaLpnjMXbVPEJy");
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQiwgrJeAJN-7lcy92N51uP7XzccK_p-fTSJNCXPLPSVih8wqPf");
urls.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT19dYLCEZlMRqojedJB-05jTrflD74nasvkXs-SdVeyM2BEpCSFA");
urls.add("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg");
urls.add("https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg");
urls.add("https://images.unsplash.com/photo-1418489098061-ce87b5dc3aee?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=2f033882f3c25404e3f904fbfe2351be&w=1000&q=80");
urls.add("https://techcrunch.com/wp-content/uploads/2018/03/gettyimages-705351545.jpg?w=730&crop=1");
}
}
Manager class(a class that acts as a manager or GUI making class):
class Manager {
private Context context;
private ArrayList<String> urls = new ArrayList<>();
LinearLayout linearLayoutScrollView;
ImageView imageView;
ProgressBar progressBar;
RelativeLayout relativeLayout;
ImageDownloader imageDownloader;
public Manager(Context context, ArrayList<String> urls) {
this.context = context;
this.urls = urls;
}
public void buildUI() {
System.out.println("Error # 1");
imageView = new ImageView(context);
imageView.setVisibility(View.GONE);
System.out.println("Error # 2");
progressBar = new ProgressBar(context);
progressBar.setIndeterminate(true);
progressBar.setVisibility(View.GONE);
System.out.println("Error # 3");
relativeLayout = new RelativeLayout(context);
relativeLayout.addView(imageView);
relativeLayout.addView(progressBar);
System.out.println("Error # 4");
linearLayoutScrollView = (LinearLayout) findViewById(R.id.linearLayoutScrollView);
linearLayoutScrollView.addView(relativeLayout);
System.out.println("Error # 5");
}
public void downloadImages() {
for (int i = 0; i < urls.size(); i++) {
buildUI();
imageDownloader = new ImageDownloader(imageView,progressBar,imageDownloader);
progressBar.setVisibility(View.VISIBLE);
imageDownloader.execute(urls.get(i));
}
}
}
ImageDownloader Class:
public class ImageDownloader extends AsyncTask<String, Void, Bitmap> {
ImageView imageView;
ProgressBar progressBar;
ImageDownloader imageDownloader;
public ImageDownloader(ImageView imageView, ProgressBar progressBar, ImageDownloader imageDownloader) {
this.imageView = imageView;
this.progressBar = progressBar;
this.imageDownloader = imageDownloader;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
imageView.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected Bitmap doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
System.out.println("Content Type = " + connection.getContentType());
if (connection.getContentType().contains("image")) {
InputStream inputStream = connection.getInputStream();
return BitmapFactory.decodeStream(inputStream);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
try {
imageView.setImageBitmap(bitmap);
progressBar.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
XML Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
tools:context="com.example.syeddanish.downloadingimages.MainActivity">
<LinearLayout
android:id="#+id/buttonsLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<Button
android:id="#+id/downloadImagesButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="downloadImages"
android:text="Download Images" />
<Button
android:id="#+id/resetButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="reset"
android:text="Reset" />
</LinearLayout>
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/buttonsLinearLayout">
<LinearLayout
android:id="#+id/linearLayoutScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</RelativeLayout>
The issue is that in the "Manager"class it gives error to "add qualifier to method" in findViewById() method.
linearLayoutScrollView = (LinearLayout) findViewById(R.id.linearLayoutScrollView);
And if i add a this qualifier it changes the above line like this
linearLayoutScrollView = (LinearLayout) linearLayoutScrollView.findViewById(R.id.linearLayoutScrollView);
and then gives the error
logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.syeddanish.downloadingimages, PID: 29339
java.lang.IllegalStateException: Could not execute method for
android:onClick
at
android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:6291)
at android.view.View$PerformClick.run(View.java:24931)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at
android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6291)
at android.view.View$PerformClick.run(View.java:24931)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual
method 'android.view.View
android.widget.LinearLayout.findViewById(int)' on a null object
reference
at
com.example.syeddanish.downloadingimages.Manager.buildUI(Manager.java:45)
at
com.example.syeddanish.downloadingimages.Manager.downloadImages(Manager.java:54)
at
com.example.syeddanish.downloadingimages.MainActivity.downloadImages(MainActivity.java:24)
at java.lang.reflect.Method.invoke(Native Method)
at
android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6291)
at android.view.View$PerformClick.run(View.java:24931)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
please point out what i am doing wrong and what to change to remove this issue.
findViewById is a method of View according to the official documentation:
Finds the first descendant view with the given ID, the view itself if the ID matches getId(), or null if the ID is invalid (< 0) or there is no matching view in the hierarchy.
or a method of activity:
Finds a view that was identified by the android:id XML attribute that was processed in onCreate(Bundle)
It is simple, It find a view inside a parent view. In most case, findviewById() is called inside an Activity, a Fragment or a CustomView. There, we call:
this.findViewById(ID_OF_THE_CHILD)
So, if you want to retrieve R.id.linearLayoutScrollView you need a reference to the parent view. you can pass it from buildGUI like this:
public void buildUI(View parent) {
...
linearLayoutScrollView = (LinearLayout)parent.findViewById(R.id.linearLayoutScrollView);
}
So, in Activity for example, you will call
buildGUI(findViewById(R.layout.activity_main));
the problem solved by putting this in the MainActivity class
linearLayoutScrollView = (LinearLayout) findViewById(R.id.linearLayoutScrollView);
and then then passing this linearLayoutScrollView as an argument in the the constructor of the "Manager" class.
public Manager(Context context, ArrayList<String> urls,LinearLayout linearLayoutScrollView) {
this.context = context;
this.urls = urls;
this.linearLayoutScrollView = linearLayoutScrollView;
}
and then making this linearLayoutScrollView as a local member of the "Manager" class and use it as required.
I am facing an issue in using the FirebaseRecyclerAdapter.
The firebase realtime database structure is as follows:
What I'm trying to do here is,
Get only the key's from data present in the "MainGroup" part of the firebase realtime database.
So to do that, I've created a model class named RecyclerDataGetSetCLass
and one viewholder class named RecyclerDataGetSetClassViewHolder
but i am getting an error saying
com.google.firebase.database.DatabaseException: Can't convert object
of type java.lang.String to type
com.example.talarir.mapproject.NonAdminClasses.RecyclerDataGetSetCLass
The Activity classes and other java files are as follows:
1) NonAdminACtivity.java //which contains the viewholder class
public class NonAdminACtivity extends AppCompatActivity implements View.OnClickListener {
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
public Button saveLocationBtn,getLocationBtn;
public RecyclerView nonAdminRecyclerView;
private Boolean flag=false;
private DatabaseReference mFirebaseDatabase;
private FirebaseDatabase mFirebaseInstance;
private DatabaseReference mFirebaseDatabase1;
private FirebaseDatabase mFirebaseInstance1;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_non_admin_activity);
mFirebaseInstance1 = FirebaseDatabase.getInstance();
mFirebaseDatabase1 = mFirebaseInstance1.getReference("MainGroup");
nonAdminRecyclerView= (RecyclerView) findViewById(R.id.recycler_view_fragment_one);
nonAdminRecyclerView.setHasFixedSize(true);
nonAdminRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
flag=true;
Log.d("CooActivity", "onAuthStateChanged:signed_in:" + user.getUid());
Toast.makeText(getApplicationContext(),"done",Toast.LENGTH_SHORT).show();
}
else
{
// User is signed out
Log.d("CooActivity", "onAuthStateChanged:signed_out");
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
finish();
}
}
};
}
#Override
public void onStart()
{
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
saveLocationBtn= (Button) findViewById(R.id.saveLocationOfUser);
saveLocationBtn.setOnClickListener(this);
getLocationBtn= (Button) findViewById(R.id.getLocationOfUser);
getLocationBtn.setOnClickListener(this);
FirebaseRecyclerAdapter<RecyclerDataGetSetCLass,RecyclerDataGetSetClassViewHolder> firebaseRecyclerAdapter=new FirebaseRecyclerAdapter<RecyclerDataGetSetCLass, RecyclerDataGetSetClassViewHolder>(
RecyclerDataGetSetCLass.class,
R.layout.each_list_non_admin,
RecyclerDataGetSetClassViewHolder.class,
mFirebaseDatabase1
) {
#Override
protected void populateViewHolder(RecyclerDataGetSetClassViewHolder viewHolder, RecyclerDataGetSetCLass model, int position)
{
viewHolder.setMainGroupName(model.getMainGroupName());
}
};
nonAdminRecyclerView.setAdapter(firebaseRecyclerAdapter);
}
public static class RecyclerDataGetSetClassViewHolder extends RecyclerView.ViewHolder
{
View mView;
public RecyclerDataGetSetClassViewHolder(View itemView) {
super(itemView);
mView=itemView;
}
public void setMainGroupName(String mainGroupName)
{
TextView textView= (TextView) mView.findViewById(R.id.textViewRecyclerViewNonAdmin);
textView.setText(mainGroupName);
}
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
#Override
protected void onDestroy() {
FirebaseAuth.getInstance().signOut();
super.onDestroy();
}
#Override
public void onClick(View v)
{
if (v.getId()==R.id.saveLocationOfUser)
{
if (flag)
{
saveUserLocation_NonAdminActivity();
}
else
{
Toast.makeText(this,"firebase not ready",Toast.LENGTH_SHORT).show();
}
}
if (v.getId()==R.id.getLocationOfUser)
{
retrieveUserLocation_NonAdminActivity();
}
}
private void retrieveUserLocation_NonAdminActivity()
{
CreationOfUserClass creationOfUserClass=new CreationOfUserClass(this);
creationOfUserClass.retrieveUserDataFromFireBase(mFirebaseDatabase,mFirebaseInstance);
}
private void saveUserLocation_NonAdminActivity()
{
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
final CreationOfUserClass creationOfUserClass=new CreationOfUserClass(this);
creationOfUserClass.createUsers(user, mFirebaseDatabase,mFirebaseInstance);
}
}
2) RecyclerDataGetSetCLass //The model class
public class RecyclerDataGetSetCLass
{
private String mainGroupName;
public RecyclerDataGetSetCLass()
{
}
public RecyclerDataGetSetCLass(String mainGroupName)
{
this.mainGroupName=mainGroupName;
}
public String getMainGroupName() {
return mainGroupName;
}
public void setMainGroupName(String mainGroupName) {
this.mainGroupName = mainGroupName;
}
}
3) activity_non_admin_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_non_admin_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.talarir.mapproject.NonAdminACtivity">
<Button
android:text="SaveLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/saveLocationOfUser" />
<Button
android:text="getLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/getLocationOfUser" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_fragment_one"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
4) each_list_non_admin.xml //the layout to be inflated for each recycler list element
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
xmlns:card_view="http://schemas.android.com/tools">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_margin="5dp"
card_view:cardCornerRadius="2dp"
card_view:contentPadding="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/textViewRecyclerViewNonAdmin"/>
</android.support.v7.widget.CardView>
</RelativeLayout>
The error log is as follows :
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.talarir.mapproject.NonAdminClasses.RecyclerDataGetSetCLass
at com.google.android.gms.internal.zzbtg.zze(Unknown Source)
at com.google.android.gms.internal.zzbtg.zzb(Unknown Source)
at com.google.android.gms.internal.zzbtg.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at com.firebase.ui.database.FirebaseRecyclerAdapter.parseSnapshot(FirebaseRecyclerAdapter.java:151)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:140)
at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:183)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6308)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6341)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5287)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5550)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5392)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5388)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2149)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1533)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1496)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:593)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3535)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3264)
at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1633)
at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:341)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:616)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6209)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
D/AppTracker: App Event: crash
I/Process: Sending signal. PID: 29821 SIG: 9
Application terminated.
Kindly assist me to get through this issue.
The value of each item you're displaying is a single string (-K....). You're trying to read an entire class out of the value, and that simply won't work.
final FirebaseRecyclerAdapter<RecyclerDataGetSetCLass,RecyclerDataGetSetClassViewHolder> firebaseRecyclerAdapter=new FirebaseRecyclerAdapter<RecyclerDataGetSetCLass, RecyclerDataGetSetClassViewHolder>(
String.class,
R.layout.each_list_non_admin,
RecyclerDataGetSetClassViewHolder.class,
mFirebaseDatabase1
) {
#Override
protected void populateViewHolder(RecyclerDataGetSetClassViewHolder viewHolder, String model, int position)
{
String key = adapter.getRef(position).getKey();
viewHolder.setMainGroupName(key);
}
};
In this snippet I look up the key of the item being shown, which is likely the value that you're looking for.
I am trying to make a remote control for a Google TV.
I want to change the text I have in a layout (TextView statusText) with connected when the device has successfully connected. But I get an exception when I try to do this:
"07-07 22:42:20.870: E/AndroidRuntime(5750):android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
"Appreciate any help/pointers
Here is my MainActivity.java and main.xml:
MainActivity.java:
package uk.co.mypack.gtvremote;
//imports removed for paste
public class MainActivity extends Activity implements ClientListener{
private AnymoteSender anymoteSender;
private TextView statusText;
protected AnymoteClientService mAnymoteClientService;
private static String statusPrefix = "Status: ";
private Context mContext;
private ProgressBar progressBar;
private Handler handler;
private TouchHandler touchPadHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
progressBar = (ProgressBar) findViewById(R.id.a_progressbar);
progressBar.setVisibility(View.VISIBLE);
mContext = this;
ImageButton upArrowButton = (ImageButton) findViewById(R.id.upArrow);
ImageButton leftArrowButton = (ImageButton) findViewById(R.id.leftArrow);
ImageButton centreButton = (ImageButton) findViewById(R.id.centreButton);
ImageButton rightArrowButton = (ImageButton) findViewById(R.id.rightArrow);
ImageButton downArrowButton = (ImageButton) findViewById(R.id.downArrow);
upArrowButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
sendKeyEvent(KeyEvent.KEYCODE_DPAD_UP);
}
});
leftArrowButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
sendKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT);
}
});
centreButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
sendKeyEvent(KeyEvent.KEYCODE_DPAD_CENTER);
}
});
rightArrowButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
sendKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT);
}
});
downArrowButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
sendKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN);
}
});
handler = new Handler();
// Bind to the AnymoteClientService
Intent intent = new Intent(mContext, AnymoteClientService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
statusText = (TextView) findViewById(R.id.statusText);
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
/*
* ServiceConnection listener methods.
*/
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mAnymoteClientService = ((AnymoteClientService.AnymoteClientServiceBinder) service)
.getService();
mAnymoteClientService.attachClientListener(MainActivity.this);
}
#Override
public void onServiceDisconnected(ComponentName name) {
mAnymoteClientService.detachClientListener(MainActivity.this);
mAnymoteClientService = null;
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onConnected(AnymoteSender anymoteSender) {
if (anymoteSender != null) {
// Send events to Google TV using anymoteSender.
// save handle to the anymoteSender instance.
this.anymoteSender = anymoteSender;
//THIS IS WHERE I AM TRYING TO SET THE TEXTVIEW
TextView localStatusText = (TextView) findViewById(R.id.statusText);
localStatusText.setText(statusPrefix + "Connected to GoogleTV");
//ABOVE IS WHERE I AM TRYING TO SET THE TEXTVIEW
// Attach touch handler to the touchpad view
touchPadHandler = new TouchHandler(
findViewById(R.id.touchPad), Mode.POINTER_MULTITOUCH, anymoteSender);
} else {
statusText.setText(statusPrefix + "Connection attempt failed, cant find send handler");
//attempt to connect again?
//attemptToConnect();
}
// Hide the progressBar once connection to Google TV is established.
handler.post(new Runnable() {
public void run() {
progressBar.setVisibility(View.INVISIBLE);
}
});
}
#Override
public void onDisconnected() {
// show message to tell the user about disconnection.
statusText.setText(statusPrefix + "Disconnected");
// Try to connect again if needed. This may be need to be done via button
attemptToConnect();
this.anymoteSender = null;
}
#Override
public void onConnectionError() {
// show message to tell the user about disconnection.
statusText.setText(statusPrefix + "Connection error encountered");
// Try to connect again if needed.
attemptToConnect();
this.anymoteSender = null;
}
#Override
protected void onDestroy() {
if (mAnymoteClientService != null) {
mAnymoteClientService.detachClientListener(this);
}
unbindService(mConnection);
super.onDestroy();
}
public void attemptToConnect()
{
//stub to invoke connection attempt
}
private void sendKeyEvent(final int keyEvent) {
// create new Thread to avoid network operations on UI Thread
if (anymoteSender == null) {
Toast.makeText(MainActivity.this, "Waiting for connection",
Toast.LENGTH_LONG).show();
return;
}
anymoteSender.sendKeyPress(keyEvent);
}
}
Main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/control_message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="#dimen/padding_medium"
android:text="#string/control_msg"
android:textSize="90dp"
tools:context=".MainActivity" />
<LinearLayout
android:id="#+id/middlePanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/statusText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Status: Disconnected - startup"
android:textSize="20dp" />
<ImageView
android:id="#+id/touchPad"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="#drawable/greysquare"
/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical" >
<ImageButton
android:id="#+id/upArrow"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#drawable/blackuparrow" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/leftArrow"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#drawable/blackleftarrow" />
<ImageButton
android:id="#+id/centreButton"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#drawable/emptycircle"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" />
<ImageButton
android:id="#+id/rightArrow"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#drawable/blackrightarrow" />
</LinearLayout>
<ImageButton
android:id="#+id/downArrow"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#drawable/blackdownarrow" />
</LinearLayout>
</LinearLayout>
<ProgressBar
android:id="#+id/a_progressbar"
style="#android:style/Widget.ProgressBar.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
The onConnected() callback is not called on the Main UI thread, but on a separate thread that is used by the Service. So it is not able to access the TextView created in Main UI thread. What you should do is create a Handler in the main UI thread and then use that handler to post a runnable that makes changes to the TextView. You can read more about Handlers on the Android developer site.