强制应用程序从第一个Activity重新启动(当权限被拒绝时)

时间:2016-08-29 10:31:11

标签: android android-activity android-6.0-marshmallow android-permissions activity-manager

众所周知,当我们在Android 6.0中 拒绝 权限时,以及 恢复 来自最近的菜单,应用程序进程被终止,应用程序 强制重新启动 。据称这是为了防止任何安全问题:

enter image description here

值得注意的是,当恢复时, 应用程序会从我们将其保留的最后一个Activity重新启动。 操作系统显然会跟踪上一个{ {1}}用户访问过。

不幸的是,这是一个问题,因为它打破了业务逻辑的流程。不允许用户以这种方式中途访问应用程序。

我的问题是,有没有办法强制应用程序从应用程序的第一个Activity重新启动,而不是用户将其保留的应用程序?

是否有与应用程序重启/进程终止/权限切换相关联的回调?

这是一种错误的做法吗?如果是这样,怎么样?什么是正确的方法?

这种行为当然在以前被发现:

1。 Android Preview M: activity recreates after permission grant

2。 Application is getting killed after enable/disable permissions from settings on Android M nexus 6

3。 Android Marshmallow: permissions change for running app

4。 All the permissions of my app are revoked after pressing “Reset app preferences”

5. Android 6 permission - Crashes when toggling permission in Setting and go back to app

5 个答案:

答案 0 :(得分:1)

你是说这个吗?

MainActivity:

public class MainActivity extends AppCompatActivity {

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

    txt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Intent intent = new Intent(MainActivity.this, ActivityB.class);
            intent.putExtra("from","MainActivity");
            startActivity(intent);
            finish();
        }
    });
}
}

ActivityB:

    public class ActivityB extends AppCompatActivity {

String intentTxt="";
final int MY_PERMISSIONS_REQUEST_PHONE_CALL = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    intentTxt = getIntent().getStringExtra("from");
}


@Override
protected void onResume() {
    super.onResume();
    if(intentTxt.equals("MainActivity")) {
        if (ContextCompat.checkSelfPermission(ActivityB.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(ActivityB.this, new String[]{android.Manifest.permission.CALL_PHONE},
                    MY_PERMISSIONS_REQUEST_PHONE_CALL);
        }
    }
        intentTxt = "";
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_PHONE_CALL: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "32434"));
                startActivity(intent);

            } else {

                Intent intent = new Intent(ActivityB.this,MainActivity.class);
                startActivity(intent);
                finish();
            }
            return;
        }
    }
}
}

您可以从ActivityB.Check的onRequestPermissionsResult启动splashActivity / HomeActivity以获取ActivityB的onResume的权限,以便在第一次调用ActivityB时以及恢复时调用ActivityB时出现权限对话框。

答案 1 :(得分:0)

您应该使用Activity提供的BundleonCreate保存的onSaveInstanceState(更多)here处理Bundle(重新)创建。

传入所有Activity,以便从先前的状态恢复并无缝恢复UI。您的jsonp可以由于多种原因而被重新创建,取消权限只是其中之一,屏幕旋转是另一个原因,因此,只要您能生存一个,就可以生存所有这些。

答案 2 :(得分:0)

我不知道是否有人还在寻找答案,但是我将通过反转逻辑来解决,而不是等待由于拒绝权限而导致指示重新启动/重新创建的标志,而是传递一个标志指示该活动是由另一个活动启动的,而不是由系统重新创建的。因此,如果没有FLAG,则必须破坏活动堆栈并启动第一个活动。

希望它可以帮助某人。

答案 3 :(得分:0)

您可以按照以下步骤操作。

  1. 创建一个扩展AppcompatActivity基础活动,用于维护所有权限和检查权限onResume()
  2. 从所有活动中扩展基础活动
  3. 如果任何权限被拒绝,您可以从基本活动中执行任何您想做的事情。

快乐编码! :)

答案 4 :(得分:0)

您应该在 onResume 回调中放置代码来检查权限状态。如果用户切换到系统设置权限活动,您的活动将被暂停。如果用户启用某个权限然后返回到您的 Activity,则 onResume 将被调用,您将有机会在此时检查新权限。然后,您可以执行任何需要重新启动 Activity 的操作,例如使用具有 startActivityFLAG_ACTIVITY_NEW_TASK 的 Intent 调用 FLAG_ACTIVITY_CLEAR_TASK 并再次启动您的 Activity。

override fun onResume() {
  super.onResume()

  // check for permission
  checkPermissionsAndRestartIfNecessary()
}

private fun checkPermissionsAndRestartIfNecessary() {
  if (ContextCompat.checkSelfPermission(...) {
    ...
  }
}