2017-03-07 67 views
1

我正在构建一个应用程序,它记录用户的语音,然后将其转换为文本格式。我试图在用户单击录制按钮后立即获得许可提示以访问麦克风。但是,在演讲录制完成后,我正在获得许可。我哪里出错了?获得录制语音后访问麦克风的权限提示

以下是的JavaXML文件

MainActivity.java

package com.ika.speechtotext; 

import android.Manifest; 
import android.content.ActivityNotFoundException; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.speech.RecognizerIntent; 
import android.os.Bundle; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.TextView; 
import android.widget.Toast; 
import java.util.ArrayList; 
import java.util.Locale; 

public class MainActivity extends AppCompatActivity{ 

    private static final int MY_PERMISSIONS_REQUEST_RECORD_AUDIO = 1; 
    private TextView text; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     text = (TextView)findViewById(R.id.myText); 
    } 

    public void onBtnClick(View view) { 


     if (view.getId() == R.id.imageRecBtn) { 

      // Here, 'this' is the current activity i.e; MainActivity 
      if (ContextCompat.checkSelfPermission(this, 
        Manifest.permission.READ_CONTACTS) 
        != PackageManager.PERMISSION_GRANTED) { 

       // Should we show an explanation? 
       if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
         Manifest.permission.RECORD_AUDIO)) { 

        // Show an explanation to the user *asynchronously* -- don't block 
        // this thread waiting for the user's response! After the user 
        // sees the explanation, try again to request the permission. 

       } else { 

        // No explanation needed, we can request the permission. 

        ActivityCompat.requestPermissions(this, 
          new String[]{Manifest.permission.RECORD_AUDIO}, 
          MY_PERMISSIONS_REQUEST_RECORD_AUDIO); 

        // MY_PERMISSIONS_REQUEST_RECORD_AUDIO is an 
        // app-defined int constant. The callback method gets the 
        // result of the request. 
       } 
      } 

      promptSpeechInput(); 
     } 
    } 

    //recognize the speech 
    public void promptSpeechInput() { 
     Intent i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 
     i.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); 
     i.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()); 
     i.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak something!"); 

     try { 
      startActivityForResult(i, 100); 
     } catch (ActivityNotFoundException a) { 
      Toast.makeText(MainActivity.this, "Your device doesn't support speech recognition.", 
        Toast.LENGTH_SHORT).show(); 
     } 
    } 

    //display the speech in text format 
    public void onActivityResult (int request_code, int result_code, Intent i) { 
     super.onActivityResult(request_code, result_code, i); 

     switch (request_code) { 

      case 100: 
       if (result_code == RESULT_OK && i != null) { 
        ArrayList<String> result = i.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); 
        text.setText(result.get(0)); 
       } 
       break; 
     } 
    } 


    //a toast for fun 
    public void onTextClick(View view){ 
     Toast.makeText(MainActivity.this, "You are a Genius! ;-)", Toast.LENGTH_SHORT).show(); 
    } 

} 

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.ika.speechtotext"> 

    <uses-permission android:name="android.permission.RECORD_AUDIO"/> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/myTheme"> 
     <activity android:name=".MainActivity"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

个更新的代码行(MainActivity.java):

public void onBtnClick(View view) { 


    if (view.getId() == R.id.imageRecBtn) { 

     //New code lines BEGIN*************************************************************************************************** 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      //checking the permission status 
      if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != 
        PackageManager.PERMISSION_GRANTED) { 
       //request the permission 
       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.RECORD_AUDIO}, 
         REQUEST_CODE_RECORD_AUDIO); 

      } else { 

       promptSpeechInput(); 
      } 
     } 
     //New code lines END*************************************************************************************************** 

    } 


} 
+1

看来,你正在检查其他权限:Manifest.permission.READ_CONTACTS – DmitryArc

+0

@DmitryArc是正确的,你正在寻找READ_CONTACT,并且如果您尝试检查音频许可是否被授予,但是您不输入该IF语句,那么在该范围内。 –

回答

1

有几个与代码问题,其涉及到您所看到的问题:

  1. 无论您的应用程序是否已授予的录制音频的权限,但它仍然呼吁promptSpeechInput()。除非获得许可,否则不应该发生这种情况。这意味着只有在此处调用PERMISSION_GRANTED或调用onRequestPermissionResult()才能调用该请求。
  2. 该应用正在检查READ_CONTACTS,然后请求RECORD_AUDIO
  3. ActivityCompat.shouldShowRequestPermissionRationale()的结果可能不是您所期望的,如果该应用程序以前从未请求过该权限。只有在应用程序请求并被拒绝权限后才能使用此方法。它提供了关于是否应该通知用户为什么需要许可的信息(以及是否需要获得许可)。

较新的权限模型可能很难处理。您可能会发现这种对新模型的讨论很有帮助:https://youtu.be/WGz-alwVh8A

您也可能会发现此权限帮助程序库更易于使用。它将处理用户推荐的条件下,提示以及调用相关的“受保护”的代码时,应用程序有权限:https://github.com/hiqes/andele

+1

谢谢你的回答。教程链接非常有帮助。我解决了权限提示问题,但我希望应用程序在授予权限后立即开始录制语音(现在,我必须再次单击rec按钮)。 _提供了更新的'MainActivity.java'片段._ – dzenvikas

+0

您仍然需要添加一个'onRequestPermissionsResult()'回调函数,如果权限被授权,调用'promptSpeechInput()'。 –

0

我没有我的工作电脑所以我现在不能发布的代码,但我给你的步骤去做。

  1. 当用户点击录制按钮检查是否记录授予许可。如果是,则调用promptSpeechInput()方法,否则请求记录权限。

  2. 覆盖您的活动中的void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults)方法。在这个检查里面,如果requestCode等于你请求的记录权限的requestCode。如果是,则检查是否授予许可。如果被授予,则调用promptSpeechInput()方法,否则不做任何事或返回或退出。理由不是必需的,因为要求记录音频的记录许可显然是可以理解的。 我希望这很清楚。随意问任何有关步骤的问题。