2014-11-22 119 views
0

我有一个自定义类来检查网络连接和显示对话框,如果没有连接。然而,无论何时它没有连接它崩溃在alertDialog.show();不知道我在哪里错了。从自定义助手类显示警报对话框

下面是自定义类。

package com.garciaericn.goodeats.helpers; 

import android.app.AlertDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.provider.Settings; 

public class CheckConnection { 

    Context mContext; 
    ConnectivityManager connectivityManager; 

    public CheckConnection(Context context) { 
     mContext = context; 
     connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    } 

    public boolean isConnected() { 

     NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 

     if (networkInfo != null && networkInfo.isConnected()) { 
      // Return true if connected 
      return true; 
     } else { 
      // Display dialog for user to connect, with intent to wifi settings 
      showConnectionFailedDialog(); 
     } 
     // Return false by default 
     return false; 
    } 

    private void showConnectionFailedDialog() { 
     // Display dialog for user to connect, with intent to wifi settings 
     AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext) 
       .setTitle("No Network Connection") 
       .setMessage("Please enable wifi data from."); 

     alertDialogBuilder.setPositiveButton("Wifi Settings", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       Intent mobileSettingsIntent = new Intent(Settings.ACTION_WIRELESS_SETTINGS); 
       mContext.startActivity(mobileSettingsIntent); 
       dialog.dismiss(); 
      } 
     }); 

     alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.dismiss(); 
      } 
     }); 

     alertDialogBuilder.setNeutralButton("Mobile Network", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       Intent mobileSettingsIntent = new Intent(Settings.ACTION_WIRELESS_SETTINGS); 
       mContext.startActivity(mobileSettingsIntent); 
       dialog.dismiss(); 
      } 
     }); 

     AlertDialog alertDialog = alertDialogBuilder.create(); 
     alertDialog.show(); 
    } 
} 

错误堆栈我得到的是:

11-22 17:29:15.895 19326-19326/com.garciaericn.goodeats E/AndroidRuntime﹕ FATAL EXCEPTION: main 
     Process: com.garciaericn.goodeats, PID: 19326 
     android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 
     at android.view.ViewRootImpl.setView(ViewRootImpl.java:566) 
     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:272) 
     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 
     at android.app.Dialog.show(Dialog.java:298) 
     at com.garciaericn.goodeats.helpers.CheckConnection.showConnectionFailedDialog(CheckConnection.java:76) 
     at com.garciaericn.goodeats.helpers.CheckConnection.isConnected(CheckConnection.java:35) 
     at com.garciaericn.goodeats.login.LoginFragment.onConnectionFailed(LoginFragment.java:185) 
     at com.google.android.gms.common.internal.e.b(Unknown Source) 
     at com.google.android.gms.common.api.b.gn(Unknown Source) 
     at com.google.android.gms.common.api.b.d(Unknown Source) 
     at com.google.android.gms.common.api.b$4.onConnectionFailed(Unknown Source) 
     at com.google.android.gms.common.internal.e.b(Unknown Source) 
     at com.google.android.gms.common.internal.d$h.b(Unknown Source) 
     at com.google.android.gms.common.internal.d$h.g(Unknown Source) 
     at com.google.android.gms.common.internal.d$b.gU(Unknown Source) 
     at com.google.android.gms.common.internal.d$a.handleMessage(Unknown Source) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:135) 
     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) 

它正在从名为:

包com.garciaericn.goodeats.login;

import android.app.Activity; 
import android.app.Fragment; 
import android.content.Intent; 
import android.content.IntentSender; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

import com.garciaericn.goodeats.R; 
import com.garciaericn.goodeats.helpers.CheckConnection; 
import com.garciaericn.goodeats.main.FavoritesActivity; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.SignInButton; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.plus.Plus; 

public class LoginFragment extends Fragment implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{ 

    public static final String TAG = "com.garciaericn.goodeats.login.LoginFragment.TAG"; 

    /* Request code used to invoke sign in user interactions. */ 
    private static final int RC_SIGN_IN = 0; 
    private static final int RC_LOGGED_IN = 1034553; 
    public static final int RC_SIGN_OUT = 34458392; 
    /* Client used to interact with Google APIs. */ 
    private GoogleApiClient mGoogleApiClient; 
    /* A flag indicating that a PendingIntent is in progress and prevents 
    * us from starting further intents. 
    */ 
    private boolean mIntentInProgress; 
    /* Store the connection result from onConnectionFailed callbacks so that we can 
    * resolve them when the user clicks sign-in. 
    */ 
    private ConnectionResult mConnectionResult; 
    private boolean mSignInClicked; 
    private boolean mSignedIn; 
    private CheckConnection checkConnection; 

    public LoginFragment() { 
    } 

    public static LoginFragment getInstance() { 
     return new LoginFragment(); 
    } 

    private void signOut() { 
     if (mGoogleApiClient.isConnected()){ 
      Plus.AccountApi.clearDefaultAccount(mGoogleApiClient); 
      mGoogleApiClient.disconnect(); 
      mGoogleApiClient.connect(); 
      mIntentInProgress = false; 
      mSignInClicked = false; 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

//  checkConnection = new CheckConnection(getActivity().getApplicationContext()); 
     setHasOptionsMenu(true); 

     mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(Plus.API) 
       .addScope(Plus.SCOPE_PLUS_LOGIN) 
       .build(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_login, container, false); 

     checkConnection = new CheckConnection(getActivity().getApplicationContext()); 

     SignInButton signInButton = (SignInButton) view.findViewById(R.id.g_plus_login); 
     signInButton.setSize(SignInButton.SIZE_WIDE); 
     signInButton.setOnClickListener(this); 

     return view; 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     if (mGoogleApiClient.isConnected()) { 
      mGoogleApiClient.disconnect(); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.action_sign_out: 
       if (mGoogleApiClient.isConnected()) { 
        Plus.AccountApi.clearDefaultAccount(mGoogleApiClient); 
        mGoogleApiClient.disconnect(); 
        mGoogleApiClient.connect(); 
       } 
       return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onClick(View v) { 
     checkConnection.isConnected(); 
     switch (v.getId()) { 
      case R.id.g_plus_login: 
       if (!mGoogleApiClient.isConnected()) { 
        mSignInClicked = true; 
        resolveSignInError(); 
       } 
       break; 
      default: 
       // If default action is needed. 
       break; 
     } 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     mSignInClicked = false; 
     mSignedIn = true; 
     // User is connected 


     String accountName = Plus.AccountApi.getAccountName(mGoogleApiClient); 
     Toast.makeText(getActivity(), accountName, Toast.LENGTH_SHORT).show(); 
//  String accountID = GoogleAuthUtil.getAccountId(getActivity(), accountName); 
//  try { 
//   accountID = GoogleAuthUtil.getAccountId(getActivity().getApplicationContext(),accountName); 
//  } catch (GoogleAuthException e) { 
//   e.printStackTrace(); 
//  } catch (IOException e) { 
//   e.printStackTrace(); 
//  } 

//  if (accountID != null) { 
//   // TODO: createLocalAccount() = Store account name and id with DB of restaurants 
//  } 


     // Launch main activity 
     Intent intent = new Intent(getActivity(), FavoritesActivity.class); 
     intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
     startActivity(intent); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     if (!mIntentInProgress) { 
      // Store the ConnectionResult so that we can use it later when the user clicks 
      // 'sign-in'. 
      mConnectionResult = connectionResult; 

      if (mSignInClicked) { 
       resolveSignInError(); 
      } 

     } 
     checkConnection.isConnected(); 
//  if (!checkConnection.isConnected()) { 
//   Toast.makeText(getActivity(), "No network connection", Toast.LENGTH_SHORT).show(); 
//  } 

    } 

    public void resolveSignInError() { 
     if (mConnectionResult.hasResolution()) { 
      try { 
       mIntentInProgress = true; 
       getActivity().startIntentSenderForResult(mConnectionResult.getResolution().getIntentSender(), RC_SIGN_IN, null, 0, 0, 0); 
      } catch (IntentSender.SendIntentException e) { 
       // The intent was canceled before it was sent. Return to the default 
       // state and attempt to connect to get an updated ConnectionResult. 
       mIntentInProgress = false; 
       mGoogleApiClient.connect(); 
      } 
     } 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == RC_SIGN_IN) { 
      if (resultCode != Activity.RESULT_OK) { 
       mSignInClicked = false; 
      } 

      mIntentInProgress = false; 

      if (!mGoogleApiClient.isConnected()) { 
       mGoogleApiClient.connect(); 
      } 
     } else if (requestCode == RC_LOGGED_IN) { 
      if (resultCode == RC_SIGN_OUT) { 
       signOut(); 
      } 
     } 

    } 
} 
+1

变化mContext更改为你有充气父视图的上下文。 – 2014-11-22 22:38:06

+0

你是从UI线程调用这个吗?你可以从函数被调用的地方显示吗? – 2014-11-22 22:44:05

+0

这是我移动它的位置...仍然崩溃@Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){ View view = inflater.inflate(R.layout.fragment_login,container,false); checkConnection = new CheckConnection(getActivity()。getApplicationContext()); SignInButton signInButton =(SignInButton)view.findViewById(R.id.g_plus_login); signInButton.setSize(SignInButton.SIZE_WIDE); signInButton.setOnClickListener(this); return view; }' – ENG618 2014-11-22 22:47:59

回答

3

如果您使用应用程序上下文而不是活动上下文来初始化对话框,则最有可能发生此异常。

你是否初始化CheckConnection对象getApplicationContext()或类似?如果是这样,你应该传递一个Activity作为你的上下文。

编辑:从您的评论以你的代码,你只需要

checkConnection = new CheckConnection(getActivity().getApplicationContext()); 

checkConnection = new CheckConnection(getActivity());