2015-06-01 41 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