Android-如何在没有用户交互的情况下授予运行时权限?

Android-How Can I grant Runtime Permission with NO user interaction?

我制作了一个应用程序,用于在没有用户交互的情况下测试各种 phone 功能,但它在某些设备上无法运行,尽管它之前运行良好。我的理论是它需要 运行t-time 权限,我是对的。当我将 运行 时间权限放在 activity 中时,它工作得很好。问题是它请求用户的权限,而我无法进行用户交互。有没有办法在没有用户交互的情况下授予 activity 权限?

我将包括一个 activity,我让记录器 activity 工作,但这取决于用户授予权限。请帮忙!!

    public static final int RECORD_AUDIO_PERMISSION_REQUEST = 3;



    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                /*
         * API's to launch the application when the tablet is locked or
         * display is turned off
         */
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
        setContentView(R.layout.activity_recorder);

        //Check to see if the device has a microphone
        PackageManager pm = getPackageManager();
        boolean micPresent = pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
        if (!micPresent) {
            Log.i(log_tag, "There is no microphone present in this device.");
            exit_function();
        } else {
            createTempFile(status_tag, "INPROGRESS");

            //Create the file to write the recording
            try {
                FileOutputStream fOut = openFileOutput("audio_test.3gp", MODE_WORLD_READABLE);
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(log_tag, "FAILED TO CREATE THE FILE OUTPUT STREAM");
                exit_function();
            }

//            if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, RECORD_AUDIO_PERMISSION_REQUEST);

            //start_recording();
        }
    }




    //Start the Recording
    private void start_recording() {
        if (recorder != null) {
            recorder.stop();
            recorder.reset();
            recorder.release();
            recorder = null;
        }
        //Setting for the Recorder
        try {
            Log.i(log_tag, "Setting the recorder");
            //This is the path that the file will be saved
            path = getFilesDir().getAbsolutePath() + "/audio_test.3gp";
            recorder = new MediaRecorder();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            recorder.setOutputFile(path);

        } catch (Exception e) {
            Log.e(log_tag, "Recording Settings Failed");
            exit_function();
        }
        //Prepare the Recorder
        try {
            Log.i(log_tag, "Preparing the Recorder");
            recorder.prepare();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(log_tag, "Recording failed");
            exit_function();
        }

        //Start the Recorder
        try {
            Log.i(log_tag, "Starting the recorder");
            title_text = ((TextView) findViewById(R.id.textView));
            title_text.setTextColor(Color.RED);
            title_text.setText("RECORDING");
            recorder.start();

            //The recording lasts as long as he timer and then stops
            mHandler.postDelayed(new Runnable() {
                public void run() {
                    if (recorder != null) {
                        recorder.stop();
                        recorder.reset();
                        recorder.release();
                        recorder = null;
                    }
                    Log.e(log_tag, "First Delay");
                    exit_function();
                }
            }, timer);
            createTempFile(status_tag, "Complete");


        } catch (Exception e) {
            e.printStackTrace();
            Log.e(log_tag, "Recorder start failed");
            exit_function();
        }
    }
        @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case  RECORD_AUDIO_PERMISSION_REQUEST:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    start_recording();
                } else {
                    onDestroy();
                }
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

不幸的是,这不能完成,因为那样会否定权限的目的。

也许如果你 had/wrote 一个可以物理点击权限框的允许按钮的应用程序,即。可以覆盖其他应用程序并与屏幕上的内容交互的东西。但是这种事情,我帮不了你了。

如评论中所述,出于明显的安全原因,普通 Android 应用无法做到这一点。

通常,对于 "testing various phone functions",我们不编写应用程序,而是使用仪器测试编写测试套件。 在那里,您可以使用 UiAutomator 自动点击权限对话框。但是,这只会 运行 作为测试套件的一部分,来自 Android SDK 安装。

或者,在您的情况下,将 targetSdkVersion 设置为 23 以下,您将不需要处理 运行 时间权限。最终,有些事情会迫使你的手牌 targetSdkVersion 高于此,但你可能 "kick the can down the road" 并在未来应对这一挑战。

这可能不是您想要的,但从技术上讲,用户可以在不与您的应用交互的情况下授予权限。在 Android 中,6+ 用户可以通过 phone 设置 -> 应用 -> 权限授予和拒绝个人权限。 从技术上讲 这会在不与应用交互的情况下授予权限。

是的,这是可能的,但它有一些限制。

1) 你必须使用 sdk 22 或以下,如果你使用 sdk 高于 22 它会问你 运行时间许可。

  • 转到应用级别 gradle 并放置 targetSdkVersion 22 .

我试过这个方法很管用!

此处示例项目 link :-https://github.com/kdblue/PermissionGranted