2015-06-01 40 views
0

我正在獲取AsyncTask類中的設備的GPS協調(通過getLocation方法),但是,如果GPS被禁用,我會打開一個對話框,讓用戶能夠轉移到「設置」區域並將GPS打開或取消。在用戶甚至按下其中一個按鈕之前,每當對話警報打開時,應用程序崩潰。我該如何解決它?Android應用程序崩潰與對話框

public class StarTask extends AsyncTask<Void,Void,ArrayList<Song>>{ 

    final int k_ThreadSleepTime = 3000; 
    final int k_MaxThreadTries = 7; 
    double latitude = 0; 
    double longitude = 0; 
    GPSTracker gps; 
    TestMain client; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     gps = new GPSTracker(getApplication()); 
    } 

    @Override 
    protected ArrayList<Song> doInBackground(Void... params) { 
     ArrayList<Song> list = new ArrayList(); 
     client = new TestMain(); 
     int tries = 0; 
     String o; 
     getLocation(); 
     String url = builtURL(); 
     try { 
      String jsonPageStr = client.doGetRequest(url); 
      JSONObject obj = new JSONObject(jsonPageStr); 
      userId = obj.getJSONObject("info").getInt("user_id"); 
      isWait = (wait.equals("true")); 

      while (isWait && tries < k_MaxThreadTries) { 
       url = builtURL(); 
       jsonPageStr = client.doGetRequest(url); 
       obj = new JSONObject(jsonPageStr); 
       if (!(obj.equals("") || obj.equals(null))) { 
        isWait = (wait.equals("true")); 
       } 
       tries++; 
       try { 
        Thread.sleep(k_ThreadSleepTime); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      if(tries == k_MaxThreadTries) { 
       //exit the App 
       onMyDestroy(); 
      } 
    } 

    private String builtURL() {} 

    private void getLocation() { 
     if (gps.canGetLocation()) { 
      latitude = gps.getLatitude(); 
      longitude = gps.getLongitude(); 

     } else { 
      // can't get location 
      // GPS or Network is not enabled 
      // Ask user to enable GPS/network in settings 

      //gps.showSettingsAlert(); 

      showSettingsAlert(); 
     } 
     gps.stopUsingGPS(); 
    } 

    public void showSettingsAlert(){ 

     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       final AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this); 

       // Setting Dialog Title 
       alertDialog.setTitle("GPS is settings"); 

       // Setting Dialog Message 
       alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?"); 

       // On pressing Settings button 
       alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog,int which) { 
         Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
         MainActivity.this.startActivity(intent); 
         hasBeenNoGps = true; 
        } 
       }); 

       // on pressing cancel button 
       alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         dialog.cancel(); 
         hasBeenNoGps = true; 
         onMyDestroy(); 
        } 
       }); 

       // Showing Alert Message 
       alertDialog.show(); 
      } 
     }); 
    } 

    @Override 
    protected void onPostExecute(ArrayList<Song> aVoid) { 
     super.onPostExecute(aVoid); 

回答

0

你在showSettingsAlert()這期間你AsyncTaskdoInBackground()稱爲做UI操作。允許的方法是將涉及UI的所有操作保持在doInBackground()之外。在這裏,您可以從getLocation()中刪除其他條件,而將其實施爲onPreExecute()。與此類似,

public class StarTask extends AsyncTask<Void,Void,ArrayList<Song>>{ 

    final int k_ThreadSleepTime = 3000; 
    final int k_MaxThreadTries = 7; 
    double latitude = 0; 
    double longitude = 0; 
    GPSTracker gps; 
    TestMain client; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     gps = new GPSTracker(getApplication()); 
     if (!gps.canGetLocation()) { 
      showSettingsAlert(); 
     } 
    } 

    @Override 
    protected ArrayList<Song> doInBackground(Void... params) { 
     ArrayList<Song> list = new ArrayList(); 
     client = new TestMain(); 
     int tries = 0; 
     String o; 
     getLocation(); 
     String url = builtURL(); 
     try { 
      String jsonPageStr = client.doGetRequest(url); 
      JSONObject obj = new JSONObject(jsonPageStr); 
      userId = obj.getJSONObject("info").getInt("user_id"); 
      isWait = (wait.equals("true")); 

      while (isWait && tries < k_MaxThreadTries) { 
       url = builtURL(); 
       jsonPageStr = client.doGetRequest(url); 
       obj = new JSONObject(jsonPageStr); 
       if (!(obj.equals("") || obj.equals(null))) { 
        isWait = (wait.equals("true")); 
       } 
       tries++; 
       try { 
        Thread.sleep(k_ThreadSleepTime); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

      if(tries == k_MaxThreadTries) { 
       //exit the App 
       onMyDestroy(); 
      } 
    } 

    private void getLocation() { 
     if (gps.canGetLocation()) { 
      latitude = gps.getLatitude(); 
      longitude = gps.getLongitude(); 

     } 
     gps.stopUsingGPS(); 
    } 
+0

嗨@siris_cac,我試過,但它仍然暗戀。我有這個例外:E/AndroidRuntime:致命例外:主 進程:maimon.milab.blenders,PID:25999 android.os.NetworkOnMainThreadException –

+0

看起來像你正在其他地方在主線程上運行的其他操作。顯示你的日誌。 – siriscac

+0

現在它告訴我:android.view.WindowManager $ BadTokenException:無法添加窗口 - 標記null不適用於應用程序 –

0

您正在嘗試運行在後臺線程UI線程(你的AsyncTask內),你所能做的就是在你的AsyncTask類中創建一個全球性的對話,並顯示在 doInBackground方法然後關閉它 onPostExecute()。您的對話需要上下文

+0

謝謝@EdgarMarcoPolo,我應該在運行內部構建showSettingsAlert()方法嗎?我應該讓alertDialog.show()在裏面運行嗎? –

+0

你不需要使用你的runOnUiThread,你可以刪除那個部分,你只需要你的上下文(MainActivity.this)來顯示對話框,你需要理解的是doInBackground是一個線程在後臺它被做成不在UI Thread中運行的東西),並且你正在後臺線程中使用runOnUiThread。 – EdgarMarcoPolo