【问题标题】:java.lang.SecurityException: Permission Denial with revoked permission android.permijava.lang.SecurityException:权限被撤销,权限被撤销 android.permi
【发布时间】:2025-12-13 06:30:01
【问题描述】:

我已经添加了要显示的权限,但仍然没有工作,(不在棉花糖下),请帮助将代码版本更新为有效代码的新版本。整个错误是:java.lang.SecurityException:Permission Denial:starting Intent { act=android.intent.action.CALL dat=tel:xxxxx flg=0x10000000 cmp=com.android.server.telecom/.components.UserCallActivity } 来自 ProcessRecord{80edffb 11112:kg.o.assist/u0a86} (pid=11112 , uid=10086) 撤销权限 android.permission.CALL_PHONE

public class OApp extends Application {

private static final String PREF_LOCALE = "locale";

private SharedPreferences prefs;
private String defaultLocale;

@Override
public void onCreate() {
    super.onCreate();
    prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    defaultLocale = getString(R.string.default_locale);
    doRegisterReceiver();
    doBindService();
}

@Override
public void onTerminate() {
    doUnregisterReceiver();
    doUnbindService();
    super.onTerminate();
}

public String getLocale() {
    return prefs.getString(PREF_LOCALE, defaultLocale).toLowerCase();
}

public void setLocale(String locale) {
    SharedPreferences.Editor prefsEditor = prefs.edit().putString(PREF_LOCALE, locale.toLowerCase());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
        prefsEditor.apply();
    } else {
        prefsEditor.commit();
    }
}

public enum ServiceStatus {
    UNKNOWN, READY, NOT_INSTALL, NOT_RUN, BINDING, UNBIND, BIND, NOT_SUPPORT
}

public interface OnRequestReceiver {
    void onReceive(Context paramContext, Item item);
}

private IExtendedNetworkService ussdService;
private ServiceStatus serviceStatus = ServiceStatus.UNKNOWN;
private OnRequestReceiver onRequestReceiver;
private Item lastItem;

private ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        ussdService = IExtendedNetworkService.Stub.asInterface(service);
        serviceStatus = ServiceStatus.BIND;

        Intent initIntent = new Intent(USSDService.ACTION_INIT);
        initIntent.putExtra(USSDService.EXT_RUNNING_STRING, getString(R.string.executing_ussd));
        sendBroadcast(initIntent);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        ussdService = null;
        serviceStatus = ServiceStatus.UNBIND;
    }
};

private BroadcastReceiver ussdReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (onRequestReceiver != null) {
            lastItem.result = intent.getStringExtra(USSDService.EXT_RESULT);
            onRequestReceiver.onReceive(context, lastItem);
        }
    }
};

private ServiceStatus checkService() {
    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo info : am.getRunningServices(Integer.MAX_VALUE)) {
        if (USSDService.class.getName().equals(info.service.getClassName())) {
            if (info.pid == 0) {
                return ServiceStatus.NOT_RUN;
            }
            return ServiceStatus.READY;
        }
    }
    return ServiceStatus.NOT_INSTALL;
}

private void doRegisterReceiver() {
    registerReceiver(ussdReceiver, new IntentFilter(USSDService.ACTION_USSD_RECEIVED));
}

private void doUnregisterReceiver() {
    unregisterReceiver(ussdReceiver);
}

private void doBindService() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        serviceStatus = ServiceStatus.NOT_SUPPORT;
    }
    if (serviceStatus == ServiceStatus.BIND) return;
    serviceStatus = checkService();
    if (serviceStatus == ServiceStatus.READY) {
        serviceStatus = ServiceStatus.BINDING;
        bindService(new Intent("com.android.ussd.IExtendedNetworkService"), serviceConnection, 0);
    }
    Log.i("OApp", "Service status: " + serviceStatus);
}

private void doUnbindService() {
    if (serviceStatus == ServiceStatus.BIND) {
        unbindService(serviceConnection);
        serviceStatus = ServiceStatus.UNBIND;
    }
}

public boolean sendCommand(Item item, OnRequestReceiver onRequestReceiver) {
    if (item == null) return false;
    lastItem = item;
    try {

        if (serviceStatus == ServiceStatus.BIND) {
            ussdService.getUserMessage(USSDService.MAGIC_ON);
            this.onRequestReceiver = onRequestReceiver;
        }

        String number = item.number;
        if (number.contains("???") && !TextUtils.isEmpty(item.addNumber)) {
            number = number.replace("???", item.addNumber);
        }

        String uriString = "";
        if (!number.startsWith("tel:")) uriString += "tel:";
        for (char c : number.toCharArray()) uriString += c == '#' ? Uri.encode("#") : c;

        Intent ussdIntent = new Intent(Intent.ACTION_CALL, Uri.parse(uriString));
        ussdIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(ussdIntent);
        return true;

    } catch (RemoteException e) {
        e.printStackTrace();
    }
    return false;
}

}

【问题讨论】:

    标签: android service numbers command ussd


    【解决方案1】:
                Intent intent = new Intent(Intent.ACTION_DIAL);
                intent.setData(Uri.parse("tel:" + "phone_number"));
    
                if (Build.VERSION.SDK_INT > 23) {
                    startActivity(intent);
                } else {
    
                    if (ActivityCompat.checkSelfPermission(PurchaseItemDetails.this,
                            Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                        Toast.makeText(YourActivity.this, "Permission Not Granted ", Toast.LENGTH_SHORT).show();
                    } else {
                        final String[] PERMISSIONS_STORAGE = {Manifest.permission.CALL_PHONE};
                        ActivityCompat.requestPermissions(YourActivity.this, PERMISSIONS_STORAGE, 9);
                        startActivity(intent);
                    }
                }
    

    【讨论】:

      【解决方案2】:

      android.permission.CALL_PHONE 是危险的权限,所以应该在运行时请求 https://developer.android.com/reference/android/Manifest.permission#CALL_PHONE。详情请查看https://developer.android.com/training/permissions/requesting.html

      【讨论】:

        【解决方案3】:

        将 CALL 更改为 DIAL,现在可以正常工作了。

        【讨论】: