我正在处理一个需要READ_PHONE_STATE权限的小应用。我在manifest.xml
上添加了权限请求
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mobile.stoq.stoqpay">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.INTERNET" />
<application
...
然而,在阅读时,我发现我必须向用户提出实际请求才能获得该权限,因此我尝试使用以下代码段进行操作
public class ValidationActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_validation);
//TODO: Fix this permission request. It sort of works but not really
int REQUEST_RPS = 0;
if (ContextCompat.checkSelfPermission(ValidationActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(ValidationActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_RPS);
}
List<UserModel> listOfUser = StoneStart.init(this);
if (listOfUser == null) {
List<String> stoneCodeToActiveList = new ArrayList<>();
String STONE_PRODUCTION_KEY = "846873720";
stoneCodeToActiveList.add(STONE_PRODUCTION_KEY);
ActiveApplicationProvider activeApplicationProvider = new ActiveApplicationProvider(this, stoneCodeToActiveList);
activeApplicationProvider.setDialogMessage("Activating");
activeApplicationProvider.setDialogTitle("Please wait");
activeApplicationProvider.setWorkInBackground(false);
activeApplicationProvider.setConnectionCallback(new StoneCallbackInterface() {
public void onSuccess() {
Toast.makeText(getApplicationContext(), "Activation successful", Toast.LENGTH_SHORT).show();
continueApplication();
}
public void onError() {
Toast.makeText(getApplicationContext(), "Activation failed", Toast.LENGTH_SHORT).show();
}
});
activeApplicationProvider.execute();
} else {
continueApplication();
}
}
private void continueApplication() {
int SPLASH_DISPLAY_LENGTH = 3500;
new Handler().postDelayed(new Runnable() {
public void run() {
Intent mainIntent = new Intent(ValidationActivity.this, MainActivity.class);
ValidationActivity.this.startActivity(mainIntent);
ValidationActivity.this.finish();
}
}, SPLASH_DISPLAY_LENGTH);
}
}
当我的应用程序运行时,它将崩溃或冻结,并且在我重新启动它之后,我拥有正确的权限,并且它运行良好。这就是logcat向我展示的内容:
03-13 19:49:57.938 6682-6714/com.mobile.stoq.stoqpay W/System.err: java.lang.SecurityException: getDeviceId: Neither user 10068 nor current process has android.permission.READ_PHONE_STATE.
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at android.os.Parcel.readException(Parcel.java:1620)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at android.os.Parcel.readException(Parcel.java:1573)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at com.android.internal.telephony.ITelephony$Stub$Proxy.getDeviceId(ITelephony.java:4207)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java:706)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at stone.providers.ActiveApplicationProvider.doInBackground(ActiveApplicationProvider.java:102)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
03-13 19:49:57.954 6682-6714/com.mobile.stoq.stoqpay W/System.err: at java.lang.Thread.run(Thread.java:818)
我做错了什么?我该如何解决这个问题?
答案 0 :(得分:2)
// Muaz Khan - www.MuazKhan.com
// MIT License - www.WebRTC-Experiment.com/licence
// Documentation - github.com/muaz-khan/RTCMultiConnection
module.exports = exports = function(app, socketCallback) {
var io = require('socket.io').listen(app, {
log: false,
origins: '*:*'
});
io.set('transports', [
'websocket', // 'disconnect' EVENT will work only with 'websocket'
'xhr-polling',
'jsonp-polling'
]);
var listOfUsers = {};
var shiftedModerationControls = {};
var ScalableBroadcast;
io.sockets.on('connection', function(socket) {
var params = socket.handshake.query;
var socketMessageEvent = params.msgEvent || 'RTCMultiConnection-Message';
if (params.enableScalableBroadcast) {
if (!ScalableBroadcast) {
ScalableBroadcast = require('./Scalable-Broadcast.js');
}
var singleBroadcastAttendees = params.singleBroadcastAttendees;
ScalableBroadcast(socket, singleBroadcastAttendees);
}
socket.userid = params.userid;
listOfUsers[socket.userid] = {
socket: socket,
connectedWith: {},
isPublic: false, // means: isPublicModerator
extra: {}
};
socket.on('extra-data-updated', function(extra) {
try {
if (!listOfUsers[socket.userid]) return;
listOfUsers[socket.userid].extra = extra;
for (var user in listOfUsers[socket.userid].connectedWith) {
listOfUsers[user].socket.emit('extra-data-updated', socket.userid, extra);
}
} catch (e) {}
});
socket.on('become-a-public-moderator', function() {
try {
if (!listOfUsers[socket.userid]) return;
listOfUsers[socket.userid].isPublic = true;
} catch (e) {}
});
socket.on('get-public-moderators', function(userIdStartsWith, callback) {
try {
userIdStartsWith = userIdStartsWith || '';
var allPublicModerators = [];
for (var moderatorId in listOfUsers) {
if (listOfUsers[moderatorId].isPublic && moderatorId.indexOf(userIdStartsWith) === 0 && moderatorId !== socket.userid) {
var moderator = listOfUsers[moderatorId];
allPublicModerators.push({
userid: moderatorId,
extra: moderator.extra
});
}
}
callback(allPublicModerators);
} catch (e) {}
});
socket.on('changed-uuid', function(newUserId) {
try {
if (listOfUsers[socket.userid] && listOfUsers[socket.userid].socket.id == socket.userid) {
if (newUserId === socket.userid) return;
var oldUserId = socket.userid;
listOfUsers[newUserId] = listOfUsers[oldUserId];
listOfUsers[newUserId].socket.userid = socket.userid = newUserId;
delete listOfUsers[oldUserId];
return;
}
socket.userid = newUserId;
listOfUsers[socket.userid] = {
socket: socket,
connectedWith: {},
isPublic: false,
extra: {}
};
} catch (e) {}
});
socket.on('set-password', function(password) {
try {
if (listOfUsers[socket.userid]) {
listOfUsers[socket.userid].password = password;
}
} catch (e) {}
});
socket.on('disconnect-with', function(remoteUserId, callback) {
try {
if (listOfUsers[socket.userid] && listOfUsers[socket.userid].connectedWith[remoteUserId]) {
delete listOfUsers[socket.userid].connectedWith[remoteUserId];
socket.emit('user-disconnected', remoteUserId);
}
if (!listOfUsers[remoteUserId]) return callback();
if (listOfUsers[remoteUserId].connectedWith[socket.userid]) {
delete listOfUsers[remoteUserId].connectedWith[socket.userid];
listOfUsers[remoteUserId].socket.emit('user-disconnected', socket.userid);
}
callback();
} catch (e) {}
});
function onMessageCallback(message) {
try {
if (!listOfUsers[message.sender]) {
socket.emit('user-not-found', message.sender);
return;
}
if (!listOfUsers[message.sender].connectedWith[message.remoteUserId] && !!listOfUsers[message.remoteUserId]) {
listOfUsers[message.sender].connectedWith[message.remoteUserId] = listOfUsers[message.remoteUserId].socket;
listOfUsers[message.sender].socket.emit('user-connected', message.remoteUserId);
if (!listOfUsers[message.remoteUserId]) {
listOfUsers[message.remoteUserId] = {
socket: null,
connectedWith: {},
isPublic: false,
extra: {}
};
}
listOfUsers[message.remoteUserId].connectedWith[message.sender] = socket;
if (listOfUsers[message.remoteUserId].socket) {
listOfUsers[message.remoteUserId].socket.emit('user-connected', message.sender);
}
}
if (listOfUsers[message.sender].connectedWith[message.remoteUserId] && listOfUsers[socket.userid]) {
message.extra = listOfUsers[socket.userid].extra;
listOfUsers[message.sender].connectedWith[message.remoteUserId].emit(socketMessageEvent, message);
}
} catch (e) {}
}
var numberOfPasswordTries = 0;
socket.on(socketMessageEvent, function(message, callback) {
if (message.remoteUserId && message.remoteUserId === socket.userid) {
// remoteUserId MUST be unique
return;
}
try {
if (message.remoteUserId && message.remoteUserId != 'system' && message.message.newParticipationRequest) {
if (listOfUsers[message.remoteUserId] && listOfUsers[message.remoteUserId].password) {
if (numberOfPasswordTries > 3) {
socket.emit('password-max-tries-over', message.remoteUserId);
return;
}
if (!message.password) {
numberOfPasswordTries++;
socket.emit('join-with-password', message.remoteUserId);
return;
}
if (message.password != listOfUsers[message.remoteUserId].password) {
numberOfPasswordTries++;
socket.emit('invalid-password', message.remoteUserId, message.password);
return;
}
}
}
if (message.message.shiftedModerationControl) {
if (!message.message.firedOnLeave) {
onMessageCallback(message);
return;
}
shiftedModerationControls[message.sender] = message;
return;
}
if (message.remoteUserId == 'system') {
if (message.message.detectPresence) {
if (message.message.userid === socket.userid) {
callback(false, socket.userid);
return;
}
callback(!!listOfUsers[message.message.userid], message.message.userid);
return;
}
}
if (!listOfUsers[message.sender]) {
listOfUsers[message.sender] = {
socket: socket,
connectedWith: {},
isPublic: false,
extra: {}
};
}
// if someone tries to join a person who is absent
if (message.message.newParticipationRequest) {
var waitFor = 120; // 2 minutes
var invokedTimes = 0;
(function repeater() {
invokedTimes++;
if (invokedTimes > waitFor) {
socket.emit('user-not-found', message.remoteUserId);
return;
}
if (listOfUsers[message.remoteUserId] && listOfUsers[message.remoteUserId].socket) {
onMessageCallback(message);
return;
}
setTimeout(repeater, 1000);
})();
return;
}
onMessageCallback(message);
} catch (e) {}
});
socket.on('disconnect', function() {
try {
var message = shiftedModerationControls[socket.userid];
if (message) {
delete shiftedModerationControls[message.userid];
onMessageCallback(message);
}
} catch (e) {}
try {
// inform all connected users
if (listOfUsers[socket.userid]) {
for (var s in listOfUsers[socket.userid].connectedWith) {
listOfUsers[socket.userid].connectedWith[s].emit('user-disconnected', socket.userid);
if (listOfUsers[s] && listOfUsers[s].connectedWith[socket.userid]) {
delete listOfUsers[s].connectedWith[socket.userid];
listOfUsers[s].socket.emit('user-disconnected', socket.userid);
}
}
}
} catch (e) {}
delete listOfUsers[socket.userid];
});
if (socketCallback) {
socketCallback(socket);
}
});
};
是异步的。它会立即将控制权返回给您。 您还没有权限。
将ActivityCompat.requestPermissions()
调用后显示的所有内容移动到单独的方法(我将在此处调用ActivityCompat.requestPermissions()
)。然后:
如果foo()
表明您有权限,请致电checkSelfPermission()
如果foo()
显示您没有权限,则在checkSelfPermission()
方法中,如果您现在拥有该权限,请致电onRequestPermissionsResult()
如果在foo()
中,您仍然没有权限(例如,用户拒绝了您的请求),请以某种方式处理