2017-12-21 2 views
0

私はjavaとandroidを使い慣れていますが、学生が自分のコンテンツの一部私のクラス(私は次の学期までに彼らのために準備したいと思っています)。Googleがサインインやその他のネットワークアクティビティの前にインターネット接続を使用するかどうかをチェックするパブリッククラス

メールアドレス(Googleアカウント)でアプリにログインできるようにしたいと思っています。また、各部門のクイズが含まれています(パフォーマンスがメールで返信されます)。私はネットワーク関連のタスクが実行される前にアクティブな接続が利用可能であることを確認したいと思います。自分のコードを公式化しようとすると、多くのSO質問(Detect if android device is connected to the internet; Detect whether there is an Internet connection available on Android; How to check internet access on Android? InetAddress never times out;; How to check internet access on Android? InetAddress never times out; How to check internet access on Android? InetAddress never times out;など)を見てきましたが、ネットワーク要求を確実にするためにAsyncTaskの使い方を理解できませんNetworkOnMainThreadExceptionの発生を防ぐためにメインスレッドによって実行されていません。私のアプリでサインインまたはグレード送信アクションを実行する前に、AsycTaskまたはスレッドを使用してインターネットチェックを実行する正しい方法を教えてください。

signInButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      if (isNetworkAvailable(getApplicationContext())) { 
       progressDialog.show(); 
       Intent intent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 
       startActivityForResult(intent, LOGIN_GOOGLE_NUMBER); 
      } else { 
       Toast.makeText(getApplicationContext(), "Please ensure that you are connected to the Internet and then try again", Toast.LENGTH_LONG).show(); 
      } 
     } 
    }); 

メインサインインもクラスの一部であるインターネット接続をチェックするためのメソッドは次のようになります。私は次のように活動に記号を扱う私の活動から、私のisNetworkAvailableメソッドを呼び出しています現時点では

この:

// Check if the network is connected (and if Internet is working) 
private boolean isNetworkAvailable(Context context) { 
    //final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)); 
    //return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected(); 
    boolean connected = false; 
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED || 
      connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) { 
     //we are connected to a network 
     connected = true; 
    } else 
     connected = false; 
    if (connected) { 
     checkConnectivity isConnected = new checkConnectivity(); 
     if (isConnected.hasInternetAccess(getApplicationContext())) { 
      return true; 
     } else 
      return false; 
    } else 
     return false; 
} 

と私は別のパブリッククラスとしてアプリを通じてアクセス可能になりたかったAsyncTaskを参照する:

public class checkConnectivity extends AsyncTask<Activity, Void, Boolean> { 

private static final String TAG = "MyApplication Context"; 

protected Boolean doInBackground(Activity... activitys) { 
    return hasInternetAccess(activitys[0]); 
} 

// To check for internet before performing sign in activity 
public boolean hasInternetAccess(Context context) { 
    try { 
      HttpURLConnection urlc = (HttpURLConnection) 
        (new URL("http://clients3.google.com/generate_204") 
          .openConnection()); 
      urlc.setRequestProperty("User-Agent", "Android"); 
      urlc.setRequestProperty("Connection", "close"); 
      urlc.setConnectTimeout(1500); 
      urlc.connect(); 
      return (urlc.getResponseCode() == 204 && 
        urlc.getContentLength() == 0); 
    } catch (IOException e) { 
      Log.e(TAG, "Error checking internet connection", e); 
    } 
    return false; 
    } 
} 

私はこれを段階的にコーディングしています。ネットワーク接続をテストするセクションがあればうまく動作しますが、http urlリクエストを追加しようとすると問題が発生します。

インターネット接続があることを確認するためにアプリケーションのさまざまな場所で使用できるパブリッククラスを定義する正しい方法と、その特定のアクティビティでの呼び出し方法を教えてください。どんな助けでも大歓迎です。

+0

代のための1つのサンプル方法を

を呼び出すAPI前のイオンは、あなたが 'AsyncTask'に、アクティビティを渡しています。これは、あなたのアプリでメモリリークを引き起こす可能性がありますしてはいけません。また、キャッシングなどのネットワーキング関連のもののほとんどを処理するネットワーキングライブラリを使用することができます。 –

+0

https://stackoverflow.com/a/42229749/5610842 これをチェックして問題があれば教えてください。 – RaghavPai

答えて

0

多くのことをよく知っているPlaidアプリを紹介しています。これは、Googleの開発者がPlaidアプリケーションでネットワーク接続を処理する方法です。

boolean connected = true; 

@Override 
protected void onResume() { 
    super.onResume(); 
    checkConnectivity(); 
} 

@Override 
protected void onPause() { 
    if (monitoringConnectivity) { 
     final ConnectivityManager connectivityManager 
       = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
     connectivityManager.unregisterNetworkCallback(connectivityCallback); 
     monitoringConnectivity = false; 
    } 
    super.onPause(); 
} 

private void checkConnectivity() { 
    final ConnectivityManager connectivityManager 
       = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    final NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 
    connected = activeNetworkInfo != null && activeNetworkInfo.isConnected(); 

    if(!connected){ 
     // do some action when not connected 
     connectivityManager.registerNetworkCallback(
        new NetworkRequest.Builder() 
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build(), 
        connectivityCallback); 
      monitoringConnectivity = true; 
    } 

} 

// Network call back 
private ConnectivityManager.NetworkCallback connectivityCallback 
     = new ConnectivityManager.NetworkCallback() { 
    @Override 
    public void onAvailable(Network network) { 
     connected = true; 
     if (adapter.getDataItemCount() != 0) return; 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       // do stuff when connected 
      } 
     }); 
    } 

    @Override 
    public void onLost(Network network) { 
     connected = false; 
    } 
}; 

ここでは、メソッドcheckConnectivity()を呼び出すことができ、それがフィールドconnectedで結果が得られます。

メインスレッドで 'AsyncTask'が実行されることはなく、UIをフリーズさせずに長時間実行しても安全です。あなたがすべきことは、 'AsyncTask'のための別のパブリッククラス(内部クラスではない)を作成し、それからあなたが望むアクティビティからそのクラスを呼び出すことができることです。

また、ContextまたはActivityからAsyncTaskを渡すことはありません。メモリリークの原因となることがあります。

EDIT:OPのコメントに基づいて

は、それはスタートはあなたが受け入れるしようとしているパラメータのタイプを示し<Start,Progress,Result>

  • 3つのジェネリック型を取る方法AsyncTask作品です。これはパラメータとしてonPreExecute()として配信されます。
  • 進捗状況は、タスクの進捗状況(例えば、ファイルのダウンロード)の更新を担当するタイプを示します。これはパラメータとしてonProgressUpdate()に配信されます。
  • 結果は、タスクの終了後にどのような結果が得られたかを示します。これはパラメータとしてonPostExecute()に配信されます。

上記の3つの方法はすべてUIスレッド上にあり、ネットワーク操作を試みるとNetworkOnMainThreadExceptionとなります。ただし、doInBackground()は、バックグラウンドスレッドで実行される唯一のメソッドです。また、Resultと同じ型を返します(上記の説明)。

同じタスクを複数の場所で使いたいので、タスクを呼び出したアクティビティを呼び出すリスナインターフェイスを作成し、その結果をパラメータとしてアクティビティに渡すことができます。

+0

親愛なる@Saran、フィードバックいただきありがとうございます。コンテキストやアクティビティをAsyncTaskに渡さないことについての情報については、私はそれを知ってうれしいです。ネットワークを監視する機能も有用です。しかし、これはまだ私の主要な問題を解決しない、ネットワークがアクセス可能な場合、私はまだ(私はNetworkOnMainThreadエラーで問題を抱えている)インターネット接続を確認することができる必要があります。 – Conrad

+0

ネットワークの可用性をチェックするには、コンテキストが必要です。 'AsyncTask'にコンテキストを渡すことができないので、ネットワークをチェックしてネットワーク操作を開始することができます。また、 'NetworkOnMainThread'はメインスレッド上でネットワーク操作をしようとするとスローされるエラーです。したがって、私たちに残された唯一のオプションは、MainThreadのネットワークに接続されていて、接続されていればバックグラウンドスレッドでネットワーク操作を開始するかどうかをチェックすることです。 –

+0

複数の場所で同じことをしたくない場合は、コンテキストを受け入れる静的ヘルパーメソッドと、ネットワークコールに必要なすべてのパラメータを作成し、そのメソッドでネットワーク接続をチェックすることができます。その結果に基づいて、タスクを実行するかどうかを指定できます。 –

0

ネットワーク接続を確認するためのパブリッククラスを作成しました。

ConnectionChecker.java

public class ConnectionChecker { 

    private Context mContext; 

    public boolean isInternetAvailable() { 
     ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo networkInfo = cm.getActiveNetworkInfo(); 
     return networkInfo!=null && networkInfo.isConnected(); 
    } 
} 

でもどこでも、あなたがインターネット接続を確認する必要があり、単に、道に従うことによって、それは、インスタンスだ私はMainActivityで定義されている私のアプリで

を定義し、それを試してみてください.java

public class MainActivity extends BaseActivity { 

public ConnectionUtil connectionUtil; 

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     connectionUtil = new ConnectionUtil(); 
} 

ネットワーク接続を確認しました、以下は私が気づいたAPI

public static void callLikeUnlikeWishApi(final MainActivity mActivity,long wishId, long updateWishId, int type) { 

     if (mActivity.connectionUtil.isInternetAvailable()) { 

      // Here you define your Api code... 
     } else { 
     Toast.makeText(mActivity, "No network connection!!", Toast.LENGTH_SHORT).show(); 
    } 
} 
+0

親愛なる@Fenilに感謝します。残念ながら、それは私を助けません。私はネットワーク接続をチェックするために、私のコードでこの繰り返しを行ってきました。私がインターネット接続がエラティックな場所に住んでいるので、Wi-Fiルーターに接続することは可能ですが、インターネットに接続することはできません。そのため、私はhasInternetAccessメソッドを動作させようとしていました。 – Conrad

関連する問題