我正在构建一个通过将短信转换为语音来读取短信的应用。 安装apk后,它会运行,但是当我关闭它并尝试再次打开它时,它会崩溃。 它给出一条错误消息,指出该应用程序继续关闭。 当我将其设置为仅在单击按钮后才能读取时,它工作正常,但是在将其更改为在初始化时读取后,就出现了此问题。 请帮忙。
package com.example.receiver3;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.speech.tts.TextToSpeech;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Button;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
ListView listView;
Button btConvert, btNext;
private static final int PERMISSION_REQUEST_READ_CONTACTS = 100;
ArrayList<String> smsList;
TextToSpeech textToSpeech;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.idList);
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);
if (permissionCheck == PackageManager.PERMISSION_GRANTED){
initializeTextToSpeech(); //edit
showContact();
}
else{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, PERMISSION_REQUEST_READ_CONTACTS);
}
btConvert = findViewById(R.id.bt_stop);
btNext = findViewById(R.id.bt_next);
btConvert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//get list value
for (String s : smsList) {
textToSpeech.stop();
}
}
});
Button button = (Button) findViewById(R.id.bt_next);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openActivity();
}
});
}
private void initializeTextToSpeech() { //edit
textToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
@Override
public void onInit(int i) {
if (i == TextToSpeech.SUCCESS){
int lang = textToSpeech.setLanguage(Locale.UK);
}
}
});
}
public void openActivity(){
Intent intent = new Intent(this, Main2Activity.class);
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_READ_CONTACTS){
showContact();
initializeTextToSpeech(); //edit
}
else {
Toast.makeText(this, "Permission Required", Toast.LENGTH_SHORT).show();
}
}
private void showContact() {
Uri inboxUri = Uri.parse("content://sms/inbox");
smsList = new ArrayList<>();
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(inboxUri,null, null, null, null);
while (cursor.moveToNext()){
String number = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString();
String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString();
smsList.add("Number: "+number+ "\n" + "Body: "+body);
}
for (String s : smsList) {
textToSpeech.speak(s,TextToSpeech.QUEUE_ADD, null);
}
cursor.close();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,smsList);
listView.setAdapter(adapter);
}
public void speak() { //edit
for (String s : smsList) {
textToSpeech.speak(s,TextToSpeech.QUEUE_ADD, null);
}
}
@Override
protected void onPause() { //edit
super.onPause();
textToSpeech.stop();
}
@Override
protected void onStop() {
super.onStop();
textToSpeech.stop();
}
@Override
protected void onResume() { //edit
super.onResume();
showContact();
initializeTextToSpeech();
}
}
答案 0 :(得分:1)
您现在要调用showContact()
,然后依次调用textToSpeech.speak()
和textToSpeech
初始化textToSpeech = new TextToSpeech()
对象。
由于用户尚未授予请求的权限并且showContact()
未被调用,因此代码在第一次运行时效果很好。
您需要更改onCreate:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.idList);
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);
// *** MOVE THIS UP HERE. ***
textToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
@Override
public void onInit(int i) {
if (i == TextToSpeech.SUCCESS){
int lang = textToSpeech.setLanguage(Locale.UK);
return;
}
}
});
if (permissionCheck == PackageManager.PERMISSION_GRANTED){
showContact();
return;
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, PERMISSION_REQUEST_READ_CONTACTS);
}
btConvert = findViewById(R.id.bt_convert);
btNext = findViewById(R.id.bt_next);
btConvert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//get list value
for (String s : smsList) {
textToSpeech.stop();
}
}
});
Button button = (Button) findViewById(R.id.bt_next);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openActivity();
}
});
}
但是,仅仅因为TTS还没有立即准备好,这还不够。仅在运行onInit()
回调并且在那里收到TextToSpeech.SUCCESS
状态后,该功能才可用。
因此,如果您想在应用程序启动时尽快说点什么,则需要从onInit()
中触发。
也许您可以想到这样的东西:
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);
if (permissionCheck != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, PERMISSION_REQUEST_READ_CONTACTS);
}
然后:
textToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
@Override
public void onInit(int i) {
if (i == TextToSpeech.SUCCESS){
int lang = textToSpeech.setLanguage(Locale.UK);
if (permissionCheck == PackageManager.PERMISSION_GRANTED){
showContact();
}
}
}
});
我完全不知道为什么您会接到return;
电话。实际上,在原始代码中,return;
退出了onCreate()
,甚至在已经授予许可的情况下尝试初始化TTS之前。