Using WebView setHttpAuthUsernamePassword? - android

I'm trying to do basic authentication to view a protected url. I want to access the protected url which looks like this:
http://api.test.com/userinfo/vid?=1234
So I do the following with a WebView:
mWebView.setHttpAuthUsernamePassword("api.test.com", "", "me#test.com", "mypassword");
mWebView.loadUrl("http://api.test.com/userinfo/user?uid=53461");
but the authentication doesn't seem to work, I'm just getting an output error page. Am I using the WebView method correctly here?
Update:
Trying with curl:
curl -u me#test.com:mypassword http://api.test.com/userinfo/user?uid=53461
and it pulls the page fine. I tried every combination of the host parameter, the owners of the api don't know what I mean by 'realm' though (and neither do I) - what info could I give them to help this along?
Thanks

Another option is to use a WebViewClient;
webview.setWebViewClient(new MyWebViewClient ());
private class MyWebViewClient extends WebViewClient {
#Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
handler.proceed("me#test.com", "mypassword");
}
}

webview.setWebViewClient(new WebViewClient () {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
handler.proceed("login", "pass");
}
});

The default behavior of a WebView is to discard all authentication requests. Even if setHttpAuthUsernamePassword.
You have to set a WebViewClient and Override the method onReceivedHttpAuthRequest

If you do not mind writing your username and password into the url, then it is not necessary to change your webview client.
Just open the following url in the webview:
http://username:password#api.test.com/userinfo/vid?=1234

In this example realm is By Invitation Only
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /usr/local/apache/passwd/passwords
Require user rbowen sungo

You may need something other than "" for the second parameter. Contact the developer of the Web site and find out what an appropriate realm should be. Or, use tools like curl to find out what the realm should be.

I never did get setHttpAuthUsernamePassword to work with phonegap's FileTransfer.download (since it doesn't use the webview), but I DID get this to work with phonegap. It's worth noting if any other phonegap people end up on this thread.
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass.toCharArray());
}
});

This is so silly. I hacked something together that worked for me, I hope it'll work for you too.
public class AuthRequestDialogFragment extends DialogFragment
{
#InjectView(R.id.dauth_userinput)
public EditText userinput;
#InjectView(R.id.dauth_passinput)
public EditText passinput;
#OnClick(R.id.dauth_login)
public void login(View view) {
((Callback) getTargetFragment()).login(userinput.getText().toString(), passinput.getText().toString());
this.dismiss();
}
#OnClick(R.id.dauth_cancel)
public void cancel(View view) {
((Callback) getTargetFragment()).cancel();
this.dismiss();
}
public static interface Callback
{
public void login(String username, String password);
public void cancel();
}
#Override
public void onStart() {
super.onStart();
WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
getDialog().getWindow().setLayout(width*2/3, height/5*2);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.dialog_authrequest, container);
ButterKnife.inject(this, view);
getDialog().setTitle("Authorization required");
return view;
}
}
And
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/dauth_requsertext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The server requires a username and password."
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="15dp"/>
<RelativeLayout
android:id="#+id/dauth_centercontainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<TextView
android:id="#+id/dauth_usertext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="15dp"/>
<TextView
android:id="#+id/dauth_passtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Password"
android:layout_below="#+id/dauth_usertext"
android:layout_alignLeft="#+id/dauth_usertext"
android:layout_alignStart="#+id/dauth_usertext"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/dauth_userinput"
android:ems="12"
android:layout_alignBottom="#+id/dauth_usertext"
android:layout_toRightOf="#id/dauth_usertext"
android:layout_toEndOf="#id/dauth_usertext"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/dauth_passinput"
android:layout_marginTop="20dp"
android:inputType="textPassword"
android:ems="12"
android:layout_alignBottom="#+id/dauth_passtext"
android:layout_toRightOf="#id/dauth_passtext"
android:layout_toEndOf="#id/dauth_passtext"
android:layout_alignLeft="#id/dauth_userinput"
android:layout_alignStart="#id/dauth_userinput"/>
</RelativeLayout>
<Button
android:id="#+id/dauth_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="15dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"/>
<Button
android:id="#+id/dauth_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Log In"
android:layout_alignTop="#+id/dauth_cancel"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
android:layout_toLeftOf="#+id/dauth_cancel"/>
</RelativeLayout>
And
public class WebViewFragment extends Fragment implements AuthRequestDialogFragment.Callback {
#Override
public void login(String username, String password) {
Log.d(this.getClass().getName(), "Login");
myWebViewClient.login(username, password);
}
#Override
public void cancel() {
Log.d(this.getClass().getName(), "Cancel");
myWebViewClient.cancel();
}
And the most important:
private class MyWebViewClient extends WebViewClient {
private WebView myView;
private HttpAuthHandler httpAuthHandler;
private String host;
private String realm;
#Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
AuthRequestDialogFragment authRequestDialogFragment = new AuthRequestDialogFragment();
FragmentManager fragmentManager = ((getActivity()).getSupportFragmentManager());
authRequestDialogFragment.setTargetFragment(WebViewFragment.this, 0);
authRequestDialogFragment.show(fragmentManager, "dialog");
this.httpAuthHandler = handler;
this.myView = view;
this.host = host;
this.realm = realm;
}
public void login(String username, String password) {
httpAuthHandler.proceed(username, password);
myView = null;
httpAuthHandler = null;
host = null;
realm = null;
}
public void cancel() {
super.onReceivedHttpAuthRequest(myView, httpAuthHandler, host, realm);
myView = null;
httpAuthHandler = null;
host = null;
realm = null;
}
}
Uses dependency:
compile 'com.jakewharton:butterknife:6.0.0'

Related

Hide ad banner with in app billing

How do i remove the banner ads and text view after the user has made purchase with in app billing. After the user made a payment, the banner and text does go away but as soon as they terminate the app and open again, the banner and textview still shows up but the difference is when they tap the textview, the toast "Thanks for your purchase" shows and the text and banner disappear then. How can i make them to not appear at all upon oncreate. thanks
MAIN
public class MainActivity extends AppCompatActivity implements BillingProcessor.IBillingHandler{
BillingProcessor bp;
AdView Adview;
TextView textView6;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bp = new BillingProcessor(this, "YOUR LICENSE KEY FROM GOOGLE PLAY CONSOLE HERE", this);
MobileAds.initialize(this,"ca-app-pub-3940256099942544~3347511713");
Adview=findViewById(R.id.adView);
textView6=findViewById(R.id.textView6);
AdRequest adRequest = new AdRequest.Builder()/*.addTestDevice("")*/.build();
Adview.loadAd(adRequest);
}
public void onClickAds(View view){
bp.purchase(MainActivity.this, "android.test.purchased");
}
#Override
public void onProductPurchased(#NonNull String productId, #Nullable TransactionDetails details) {
Toast.makeText(this, "Thank you for your purchase",Toast.LENGTH_LONG).show();
ViewGroup parent1 = (ViewGroup) Adview.getParent();
ViewGroup parent2 = (ViewGroup) textView6.getParent();
parent1.removeView(Adview);
parent2.removeView(textView6);
parent1.invalidate();
parent2.invalidate();
}
#Override
public void onPurchaseHistoryRestored() {
}
#Override
public void onBillingError(int errorCode, #Nullable Throwable error) {
Toast.makeText(this, "AN ERROR OCCURED.",Toast.LENGTH_LONG).show();
}
#Override
public void onBillingInitialized() {
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!bp.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onDestroy() {
if (bp != null) {
bp.release();
}
super.onDestroy();
}
}
XML
<com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
ads:adSize="BANNER"
ads:adUnitId="ca-app-pub-3940256099942544/6300978111"
ads:layout_constraintBottom_toBottomOf="parent"
ads:layout_constraintEnd_toEndOf="parent"
ads:layout_constraintStart_toStartOf="parent"
ads:layout_constraintTop_toBottomOf="#+id/constraintLayout"
ads:layout_constraintVertical_bias="0.42"></com.google.android.gms.ads.AdView>
<TextView
android:id="#+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickAds"
android:text="Don't like seeing ads? Tap Here!"
android:textColor="#android:color/background_light"
android:textStyle="bold|italic"
app:layout_constraintBottom_toTopOf="#+id/adView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
Try using shared preference for this issue
following step will help you
step 1. Initialize at top
private static final String PREF_FILE = "PREF_FILE";
private static final String IS_PRODUCT_PURCHASE = "IS_PRODUCT_PURCHASE";
step 2. inside onProductPurchased() method add these line
SharedPreferences.Editor editor = getSharedPreferences(PREF_FILE, MODE_PRIVATE).edit();
editor.putBoolean(IS_PRODUCT_PURCHASE,true);
editor.commit();
setp 3.call this method inside onCreate() at last
private void checkForIsPurchase() {
SharedPreferences preferences = getSharedPreferences(PREF_FILE, MODE_PRIVATE);
boolean isPurchase = preferences.getBoolean(IS_PRODUCT_PURCHASE, false);
if (isPurchase) {
Adview.setVisibility(View.GONE);
textView6.setVisibility(View.GONE);
}
}

I have a progress bar that displays on my emulator but not real device

I have a custom loading bar in my app, when used in my emulator the loading bar is displayed along with the text as defined in the layout with no problems, but when i run the app on my device the loading bar box comes up but it does not display the loading icon or the loading text, just a blank space.
Below is my custom bar class
public class csBar
{
public static csBar s_m_oCShowProgress;
public static Context m_Context;
public static Dialog m_Dialog;
public csBar(Context m_Context) {
this.m_Context = m_Context;
}
public static csBar getInstance() {
if (s_m_oCShowProgress == null) {
s_m_oCShowProgress = new csBar(m_Context);
}
return s_m_oCShowProgress;
}
public void showProgress(Context m_Context)
{
m_Dialog = new Dialog(m_Context);
m_Dialog.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
m_Dialog.setContentView(R.layout.custom_progress_bar);
m_Dialog.setTitle("Loading ....");
m_Dialog.findViewById(R.id.progress_bar).setVisibility(View.VISIBLE);
m_Dialog.setCancelable(true);
m_Dialog.setCanceledOnTouchOutside(true);
m_Dialog.show();
}
public static void hideProgress() {
if (m_Dialog != null) {
m_Dialog.dismiss();
m_Dialog = null;
}
}
}
Below is my layout for it
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:orientation="vertical">
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:indeterminate="true"
android:visibility="invisible"
android:indeterminateBehavior="cycle"
android:indeterminateOnly="true"
style="#android:style/Widget.DeviceDefault.ProgressBar.Large">
</ProgressBar>
</RelativeLayout>

When i declare my button the app stop and does not open

When I declare and try to get a reference to my button, which I declare in XML, the app won't open and I don't know why. PLEASE try to explain to me why not -- don't just give a link.
Here's the code:
public class MainActivity extends AppCompatActivity {
final String stream="<iframe width=\"300\" height=\"193\" src=\"http://cdn.livestream.com/embed/sl48?layout=4&color=0xffad4b&autoPlay=true&mute=false&iconColorOver=0xe17b00&iconColor=0xb96500&allowchat=true&height=193&width=300\" style=\"border:0;outline:0\" frameborder=\"0\" scrolling=\"no\"></iframe>";
// Button button = (Button) findViewById(R.id.home);
//final Button button1 = (Button) findViewById(R.id.stream);
//final Button button2 = (Button) findViewById(R.id.contatti);
WebView custumWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
custumWebView = (WebView) findViewById(R.id.webView);
custumWebView.loadData(stream, "text/html", null);
custumWebView.getSettings().setJavaScriptEnabled(true);
custumWebView.getSettings().setLoadsImagesAutomatically(true);
custumWebView.clearHistory();
custumWebView.clearCache(true);
custumWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
}
public class CustomWebView extends WebView {
public CustomWebView (Context context) {
super( context );
init();
}
public CustomWebView (Context context, AttributeSet attrs) {
super( context, attrs );
init();
}
public CustomWebView (Context context, AttributeSet attrs, int defStyle) {
super( context, attrs, defStyle );
init();
}
public CustomWebView (Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
super( context, attrs, defStyle, privateBrowsing );
init();
}
protected void init () {
getSettings().setJavaScriptEnabled( true );
setWebViewClient( new CustomWebViewClient() );
setDownloadListener( new CustomDownloadListener() );
}
protected boolean overrideUrlLoading (WebView view, String url) {
// ANY CUSTOM LOGIC GOES HERE
view.loadUrl(url);
return true;
}
protected void pageFinished (WebView view, String url) {
}
protected void downloadStarted(String url, String mimetype) {
try {
//Start new activity to load the specific url
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(url), mimetype);
getContext().startActivity(intent);
//custumWebView.loadData(stream, "text/html", null);
} catch (Exception exception) {
exception.printStackTrace();
}
}
/**
* Default webview client.
*/
protected class CustomWebViewClient extends WebViewClient {
/**
* Constructor, default.
*/
public CustomWebViewClient () {
}
#Override
public boolean shouldOverrideUrlLoading (WebView view, String url) {
return overrideUrlLoading( view, url );
}
#Override
public void onPageFinished (WebView view, String url) {
pageFinished(view, url);
}
}
protected class CustomDownloadListener implements DownloadListener {
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
downloadStarted(url, mimetype);
}
}
}
and here the xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<WebView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/webView"
android:layout_below="#+id/stream"
android:layout_alignRight="#+id/stream"
android:layout_alignEnd="#+id/stream"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_above="#+id/imageView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Home"
android:id="#+id/home"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stream"
android:id="#+id/stream"
android:layout_alignTop="#+id/home"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Contatti"
android:id="#+id/contatti"
android:layout_above="#+id/webView"
android:layout_centerHorizontal="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:minHeight="50dp"
android:minWidth="400dp" />
</RelativeLayout>
The CustomWebView class is so I don't get errors with loadData for the streaming site. I don't know why this class is working but it is. I copied it from the livestream support site, I'm only a newbie and I'm trying to learn.
If you're referring to these two lines of code at the top of your class:
// Button button = (Button) findViewById(R.id.home);
//final Button //final Button button2 = (Button) findViewById(R.id.contatti);
That will not work in that location. Those buttons are created in your XML layout. You cannot get a reference to a button declared in an XML layout before you first call setContentView() in your onCreate() method. You must do this.
This is what you need to do:
public class MainActivity extends AppCompatActivity {
private Button mButton;
private Button mButton1;
private Button mButton2;
// declare any other fields you require
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.home);
mButton1 = (Button) findViewById(R.id.stream);
mButton2 = (Button) findViewById(R.id.contatti);
// Your other initialization code
}
Please note that you cannot declare those Buttons as final fields, as they are not instantiated in a constructor (onCreate() is not a constructor).

Android webView InAppBrowserFragment error encroachment menu

I have can WebView in Fragment, when move tab Fragment,and I touch Button aboutUs--> move in Fragment AboutUs; I repeat about 10times.
Error is same picture.
can everyone help me?. Thank :
Code Fragment load WebView :
public class InAppBrowserFragment
extends BaseFragment {
private static final String LINK_PAGE = "linkPage";
private static final String TITLE_ACTION_BAR = "titleActionBar";
#InjectView(R.id.web_settings)
WebView mWebViewSettings;
#InjectView(R.id.actionbar_settings_sub)
ActionBar mActionBar;
#InjectView(R.id.img__settings_background)
ImageView mImgSettingsBackground;
/**
* Static method used to create an instance for this fragment.
*
* #return New instance of Fragment.
*/
public static InAppBrowserFragment newInstance(String titleActionBar,
String linkPage) {
final InAppBrowserFragment fragment = new InAppBrowserFragment();
final Bundle data = new Bundle();
if (titleActionBar != null) {
data.putString(LINK_PAGE,
linkPage);
data.putString(TITLE_ACTION_BAR,
titleActionBar);
}
// Attach data with fragment.
fragment.setArguments(data);
return fragment;
}
#Override
protected int getLayoutResourceId() {
return R.layout.fragment_in_app_browser;
}
#Override
protected void initUi(final Bundle savedInstanceState) {
String titleActionBar = getArguments().getString(TITLE_ACTION_BAR);
//set background
CommonUtil.displayImage(getActivity(),
CommonUtil.getDrawableResource(R.drawable.img_random_frontpage_1),
this.mImgSettingsBackground,
0,
0,
0,
true,
false,
null);
//set UI Action Bar
this.mActionBar.setupUI(null,
titleActionBar,
R.drawable.ab_ic_back,
0,
"");
this.mActionBar.setButtonRightPadding(0);
this.mActionBar.setButtonLeftListener(new ActionBar.IActionBarButtonLeftListener() {
#Override
public void onButtonLeftClicked(final View view) {
popBack(true);
mWebViewSettings.canGoBack();
}
});
}
#Override
protected void loadData(final Bundle savedInstanceState) {
String linkPage = getArguments().getString(LINK_PAGE);
// Init webview setting
WebSettings settings = mWebViewSettings.getSettings();
settings.setJavaScriptEnabled(true);
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(true);
settings.setSupportZoom(true);
mWebViewSettings.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
}
});
mWebViewSettings.loadUrl(linkPage);
}
}
Conrect:
Inconrect:
i fix sucess :(set wrap_content for Webview )
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/CreateTrips.Widget.ScreenContent.Fragment">
<ImageView
android:id="#+id/img__settings_background"
style="#style/CreateTrips.Widget.BackgroundImage"
android:contentDescription="#null"/>
<com.createtrips.ui.widgets.ActionBar
android:id="#+id/actionbar_settings_sub"
style="#style/CreateTrips.Widget.ActionBar"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:layout_marginTop="#dimen/widget_action_bar_height"
>
<WebView
android:id="#+id/web_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</FrameLayout>

Trouble getting handle to TextView in android callback

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.

Categories

Resources