2013-05-25 3 views
0

У меня есть этот пример распознавания голоса. Я добавил код для команды httppost. Я хочу, когда я говорю слово СОБАК, чтобы сделать httppost. Все работает отлично, но когда я говорю слово СОБАКА и когда он должен сделать мой HttpPost я получаю эти ошибки:android voice command сделать httppost

05-25 21:31:24.889: D/AndroidRuntime(15191): Shutting down VM 
05-25 21:31:24.889: W/dalvikvm(15191): threadid=1: thread exiting with uncaught exception (group=0x40aab300) 
05-25 21:31:24.909: E/AndroidRuntime(15191): FATAL EXCEPTION: main 
05-25 21:31:24.909: E/AndroidRuntime(15191): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1001, result=-1, data=Intent { (has extras) }} to activity {com.rakesh.voicerecognitionexample/com.rakesh.voicerecognitionexample.VoiceRecognitionActivity}: android.os.NetworkOnMainThreadException 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.app.ActivityThread.deliverResults(ActivityThread.java:3267) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3310) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.app.ActivityThread.access$1100(ActivityThread.java:142) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.os.Handler.dispatchMessage(Handler.java:99) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.os.Looper.loop(Looper.java:137) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.app.ActivityThread.main(ActivityThread.java:4931) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at java.lang.reflect.Method.invokeNative(Native Method) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at java.lang.reflect.Method.invoke(Method.java:511) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at dalvik.system.NativeStart.main(Native Method) 
05-25 21:31:24.909: E/AndroidRuntime(15191): Caused by: android.os.NetworkOnMainThreadException 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at java.net.InetAddress.getAllByName(InetAddress.java:214) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at com.rakesh.voicerecognitionexample.VoiceRecognitionActivity.cici(VoiceRecognitionActivity.java:157) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at com.rakesh.voicerecognitionexample.VoiceRecognitionActivity.onActivityResult(VoiceRecognitionActivity.java:113) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.app.Activity.dispatchActivityResult(Activity.java:5192) 
05-25 21:31:24.909: E/AndroidRuntime(15191): at android.app.ActivityThread.deliverResults(ActivityThread.java:3263) 
05-25 21:31:24.909: E/AndroidRuntime(15191): ... 11 more 

Вот мой код:

package com.rakesh.voicerecognitionexample; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 

import android.app.Activity; 
import android.app.SearchManager; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.content.pm.ResolveInfo; 
import android.os.Bundle; 
import android.speech.RecognizerIntent; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ListView; 
import android.widget.Spinner; 
import android.widget.Toast; 

public class VoiceRecognitionActivity extends Activity { 
    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1001; 

    private EditText metTextHint; 
    private ListView mlvTextMatches; 
    private Spinner msTextMatches; 
    private Button mbtSpeak; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_voice_recognition); 
     metTextHint = (EditText) findViewById(R.id.etTextHint); 
     mlvTextMatches = (ListView) findViewById(R.id.lvTextMatches); 
     msTextMatches = (Spinner) findViewById(R.id.sNoOfMatches); 
     mbtSpeak = (Button) findViewById(R.id.btSpeak); 
    } 

    public void checkVoiceRecognition() { 
     // Check if voice recognition is present 
     PackageManager pm = getPackageManager(); 
     List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(
       RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0); 
     if (activities.size() == 0) { 
      mbtSpeak.setEnabled(false); 
      Toast.makeText(this, "Voice recognizer not present", 
        Toast.LENGTH_SHORT).show(); 
     } 
    } 

    public void speak(View view) { 
     Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 
     // Specify the calling package to identify your application 
     intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass() 
       .getPackage().getName()); 

     // Display an hint to the user about what he should say. 
     intent.putExtra(RecognizerIntent.EXTRA_PROMPT, metTextHint.getText() 
       .toString()); 

     // Given an hint to the recognizer about what the user is going to say 
     intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, 
       RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); 

     // If number of Matches is not selected then return show toast message 
     if (msTextMatches.getSelectedItemPosition() == AdapterView.INVALID_POSITION) { 
      Toast.makeText(this, "Please select No. of Matches from spinner", 
        Toast.LENGTH_SHORT).show(); 
      return; 
     } 

     int noOfMatches = Integer.parseInt(msTextMatches.getSelectedItem() 
       .toString()); 
     // Specify how many results you want to receive. The results will be 
     // sorted where the first result is the one with higher confidence. 

     intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, noOfMatches); 

     startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == VOICE_RECOGNITION_REQUEST_CODE) 

      //If Voice recognition is successful then it returns RESULT_OK 
      if(resultCode == RESULT_OK) { 

       ArrayList<String> textMatchList = data 
       .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); 

       if (!textMatchList.isEmpty()) { 
        // If first Match contains the 'search' word 
        // Then start web search. 
        if (textMatchList.get(0).contains("search")) { 

         String searchQuery = textMatchList.get(0).replace("search", 
         " "); 
         Intent search = new Intent(Intent.ACTION_WEB_SEARCH); 
         search.putExtra(SearchManager.QUERY, searchQuery); 
         startActivity(search); 
        } else if (textMatchList.get(0).contains("dog")) { 
         postTo(); 
       } else { 
         // populate the Matches 
         mlvTextMatches 
         .setAdapter(new ArrayAdapter<String>(this, 
           android.R.layout.simple_list_item_1, 
           textMatchList)); 
        } 

       } 
      //Result code for various error.  
      }else if(resultCode == RecognizerIntent.RESULT_AUDIO_ERROR){ 
       showToastMessage("Audio Error"); 
      }else if(resultCode == RecognizerIntent.RESULT_CLIENT_ERROR){ 
       showToastMessage("Client Error"); 
      }else if(resultCode == RecognizerIntent.RESULT_NETWORK_ERROR){ 
       showToastMessage("Network Error"); 
      }else if(resultCode == RecognizerIntent.RESULT_NO_MATCH){ 
       showToastMessage("No Match"); 
      }else if(resultCode == RecognizerIntent.RESULT_SERVER_ERROR){ 
       showToastMessage("Server Error"); 
      } 
     super.onActivityResult(requestCode, resultCode, data); 
    } 
    void showToastMessage(String message){ 
     Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); 
    } 





    public void postTo() 
    { 

      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost("http://mysite.com/script.php"); 
     try { 
      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
      nameValuePairs.add(new BasicNameValuePair("message", "cracanel")); 
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
      httpclient.execute(httppost); 
     } catch (ClientProtocolException e) { 
      // TODO Auto-generated catch block 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
     } 



    } 

} 

ответ

4

Сво NetworkOnMainThread исключение. Вы не можете запускать работу, связанную с сетью, в основном потоке ui. Для этой цели вы должны использовать asynctask.

http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

Для AsyncTask

http://developer.android.com/reference/android/os/AsyncTask.html

Вы также можете создать свой собственный поток и выполнить HttpPost. Но убедитесь, что вы не обновляете ui в потоке backgroudn. Asyntask делает его более легким для вас

Пример:

class TheTask extends AsyncTask<Void,Void,Void> 
{ 
    @Override 
    protected void onPreExecute() { 
     // TODO Auto-generated method stub 
     super.onPreExecute(); 
        // invoked on the ui thread. 
        // display progress dialog  
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
        //invoked on the ui thread 
        // dismiss progress dialog 
        // result of doinbackground computation is a parameter to this 
        // can update ui here 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 
     // TODO Auto-generated method stub 
        //invoked on the background thread 
        // do not update ui 
        // execute http post here 
        postTo(); // call your post method here 
     return null; 
    } 
} 

Использование:

 new TheTask().execute(); // load on ui thread 

Может передать параметр в конструктор AsyncTask. Вы также можете напрямую передать параметр doinbackground.

2

Вам необходимо выполнить сетевые подключения в отдельном потоке или с помощью AsyncTask.

Вы можете увидеть, как я это сделал в этом коде здесь (AsyncTask + обратный вызов): https://github.com/nedwidek/Android-Rest-API

Или используйте поиск, чтобы найти много других примеров. Такие, как: - android wait asynctask to finish - Using wait in AsyncTask

AsyncTask предназначен для короткой продолжительности фоновых задач (например, доступ к сети).

0

Просто простой внешний поток, используйте AsyncTask, если вам необходимо обновить пользовательский интерфейс в процессе Попробуйте это в вашем коде:

else if (textMatchList.get(0).contains("dog")) { 
      Thread backgroundThread = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        postTo(); 
       } 
      }); 
      backgroundThread.start(); 
} 
0

Вы не можете сделать сети на UI потоке. Используйте AsyncTask.