有一个代码:
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.firebase.analytics.FirebaseAnalytics;
import tanat.androidtesttask.R;
import tanat.androidtesttask.errorreporter.GetLogs;
import tanat.androidtesttask.utils.LoadLocalData;
import tanat.androidtesttask.utils.SendEMail;
public class MainActivity extends Activity {
private FirebaseAnalytics mFirebaseAnalytics;
public Context context;
@Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
// Obtain the FirebaseAnalytics instance.
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
context = MainActivity.this;
super.onCreate(savedInstanceState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
public String LOG_FILE_NAME = "logs";
@Override
public boolean onOptionsItemSelected(MenuItem item) {
String action = "";
int i = item.getItemId();
//
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
if (i == R.id.save_logs) {
if (isCheckPermission(1)) {
saveLogs();
}
} else if (i == R.id.send_logs) {
if (isCheckPermission(2)) {
new SendEMail(MainActivity.this).send(LOG_FILE_NAME);
tanat.androidtesttask.errorreporter.Log.d("Permission granted, file sending");
} else {
///
}
}
} else {
action = "Insert a memory card";
}
Toast.makeText(this, action, Toast.LENGTH_SHORT).show();
return super.onOptionsItemSelected(item);
}
private boolean isCheckPermission(int i) {
if (i == 1) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showMessageOKCancel("Requires write permission to save logs to file");
return false;
}
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST);
return false;
// MY_PERMISSIONS_REQUEST is an
// app-defined int constant. The callback method gets the
// result of the request.
}
return true;
} else if (i == 2) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
showMessageOKCancel("Requires read permission to transfer file");
return false;
}
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST);
return false;
}
return true;
}
return false;
}
private void showMessageOKCancel(String message) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", listener)
.setNegativeButton("Cancel", listener)
.create()
.show();
}
final private int PERMISSIONS_REQUEST = 7;
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
final int BUTTON_NEGATIVE = -2;
final int BUTTON_POSITIVE = -1;
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case BUTTON_NEGATIVE:
// int which = -2
dialog.dismiss();
break;
case BUTTON_POSITIVE:
// int which = -1
ActivityCompat.requestPermissions(
MainActivity.this, new String[]{
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST);
dialog.dismiss();
break;
}
}
};
/* Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
LoadLocalData loadSD = new LoadLocalData(MainActivity.this);
loadSD.writeFileSD(LOG_FILE_NAME, GetLogs.get());
Toast.makeText(MainActivity.this, "Logs save", Toast.LENGTH_SHORT).show();
}
};*/
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted!
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(this, "Permission on write storage granted", Toast.LENGTH_SHORT).show();
saveLogs();
}
if (grantResults[1] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission on read storage granted.", Toast.LENGTH_SHORT).show();
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
//метод который сохраняет логи
public void saveLogs (){
LoadLocalData loadSD = new LoadLocalData(MainActivity.this);
loadSD.writeFileSD(LOG_FILE_NAME, GetLogs.get());
Toast.makeText(this, "Logs save", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
// Log.d("Logs","Logs: " + GetLogs.get());
super.onDestroy();
}
}
在第一次尝试保存日志时,它会请求将数据写入存储卡的权限,如果获得,它会写入文件,然后立即崩溃并出现错误:
E/UncaughtException: java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=7, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {tanat.androidtesttask/tanat.androidtesttask.activity.MainActivity}: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at tanat.androidtesttask.activity.MainActivity.onRequestPermissionsResult(Unknown Source)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6553)
at android.app.Activity.dispatchActivityResult(Activity.java:6432)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E/AndroidRuntime: FATAL EXCEPTION: main
Process: tanat.androidtesttask, PID: 2022
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=7, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {tanat.androidtesttask/tanat.androidtesttask.activity.MainActivity}: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at tanat.androidtesttask.activity.MainActivity.onRequestPermissionsResult(Unknown Source)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6553)
at android.app.Activity.dispatchActivityResult(Activity.java:6432)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
在随后的发射中(当已经获得许可时)没有问题。如果您删除数据保存方法,只需放一个 toast - 它可以工作(更准确地说,它是这样工作的,但它不会随着 toast 而退出)。我读到权限对话框似乎在一个单独的线程中,我试图通过hander保存它(虽然这也是废话,然后toast也不起作用),但无济于事。请告诉我如何解决这个问题?
总的来说,经过深思熟虑,我明白了。有这样一个细微差别:如果您允许组中的一个元素,那么它适用于整个组。也就是说,当我授予将数据写入文件的权限时,它也立即被授予读取,因此我在 grantResults 数组中只有 1 个元素,当检查第二个时,应用程序崩溃了。改变方法: