I tried to create managed user using UserManager instead of DevicePolicyManager.But the log is showing
Cannot add more managed profiles for user android 0
The below code (AOSP code) is returning always false (UserManagerService.java)
(https://android.googlesource.com/platform/frameworks/base/+/a029ea1/services/java/com/android/server/pm/UserManagerService.java)
"hasSystemFeature false"
#Override
public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) {
checkManageUsersPermission("check if more managed profiles can be added.");
Log.e(LOG_TAG, "isLowRamDeviceStatic check");
if (ActivityManager.isLowRamDeviceStatic()) {
return false;
}
Log.e(LOG_TAG, "isLowRamDeviceStatic false");
if (!mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_MANAGED_USERS)) {
Log.e(LOG_TAG, "hasSystemFeature false");
return false;
}
Log.e(LOG_TAG, "hasSystemFeature true");
// Limit number of managed profiles that can be created
final int managedProfilesCount = getProfiles(userId, false).size() - 1;
final int profilesRemovedCount = managedProfilesCount > 0 && allowedToRemoveOne ? 1 : 0;
if (managedProfilesCount - profilesRemovedCount >= getMaxManagedProfiles()) {
return false;
}
Log.e(LOG_TAG, "managedProfilesCount "+ managedProfilesCount);
synchronized(mUsersLock) {
UserInfo userInfo = getUserInfoLU(userId);
if (userInfo == null || !userInfo.canHaveProfile()) {
return false;
}
Log.e(LOG_TAG, "getUserInfoLU not null or userInfo.canHaveProfile()");
int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU()
- profilesRemovedCount;
// We allow creating a managed profile in the special case where there is only one user.
return usersCountAfterRemoving == 1
|| usersCountAfterRemoving < UserManager.getMaxSupportedUsers();
}
}
The feature is enabled using below configuration. But not working
https://android.googlesource.com/platform/frameworks/native/+/master/data/etc/android.software.managed_users.xml
<permissions>
<feature name="android.software.managed_users" />
</permissions>
Related
This issue is troubling me until 1 week. I want to take picture like bracketing but in Sony Camera API its not support. so I coded it like continuously take 5 pictures with different value (0,+2,-2,-4,+4) using loop. (using button for it, and when press the button it should take picture 5 times) U can see the code in below:
This code for set Shutter Speed on camera
This code for taking picture:
private void takePicture() {
if (mLiveviewSurface == null || !mLiveviewSurface.isStarted()) {
DisplayHelper.toast(getApplicationContext(), R.string.msg_error_take_picture);
return;
}
new Thread() {
#Override
public void run() {
try {
JSONObject replyJson = mRemoteApi.actTakePicture();
JSONArray resultsObj = replyJson.getJSONArray("result");
JSONArray imageUrlsObj = resultsObj.getJSONArray(0);
String postImageUrl = null;
if (1 <= imageUrlsObj.length()) {
postImageUrl = imageUrlsObj.getString(0); continousShottingWithDifferentShutterValue();
}
if (postImageUrl == null) {
Log.w(TAG, "takePicture: post image URL is null.");
DisplayHelper.toast(getApplicationContext(), //
R.string.msg_error_take_picture);
return;
}
// Show progress indicator
DisplayHelper.setProgressIndicator(SonyCameraActivity.this, false);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
and this is for loop:
int val, posVal = 0;
int currentShutterSpeed = 0;
private void continousShottingWithDifferentShutterValue() {
if (val == 0) {
currentShutterSpeed = -5;
setShutterSpeed(currentShutterSpeed);
val++;
} else if (val == 1) {
currentShutterSpeed = 5;
setShutterSpeed(currentShutterSpeed);
val++;
} else if (val == 2) {
currentShutterSpeed = -10;
setShutterSpeed(currentShutterSpeed);
val++;
} else if (val == 3) {
currentShutterSpeed = 10;
setShutterSpeed(currentShutterSpeed);
val++;
} else if (val == 4) {
setShutterSpeedVal0(0);
posVal++;
}
if (posVal == 3) {
posVal = 0;
val = 0;
}
}
But when I take picture sometimes shutterSpeed or takePicture is getting error and loop is stop.
Error types are: setShutterSpeed IOExeption error: 500; or setShutterSpeed is not set. Someone works with Sonycamera remote API and has any idea how to fix it or take picture 5 times with different value. will thankful for any idea. Thanks
I solved the problem. it was a shutter speed value error. As u know in Sony Camera Api there is not have the value of shutter speed and I wrote it as in camera settings. and JSON request and response is not match so its shows error 500. If someone wants to use shutter speed value: here it is:
String shutterValue[] = {"30\"", "25\"", "20\"", "15\"", "13\"", "10\"", "8\"", "6\"",
"5\"", "4\"", "3.2\"", "2.5\"", "2\"", "1.6\"", "1.3\"", "1\"", "0.8\"", "0.6\"", "0.5\"",
"0.4\"", "1/3", "1/4", "1/5", "1/6", "1/8", "1/10", "1/13", "1/15", "1/20", "1/25", "1/30",
"1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/200", "1/250", "1/320", "1/400",
"1/500", "1/640", "1/800", "1/1000", "1/1250", "1/1600", "1/2000", "1/2500", "1/3200", "1/4000"};
I have an Android app that is communicating with and arduino board via bluetooth
All the commands are going backward and forwards fine, until I wanted to send a comand of the type
"aT?bb"
from the android app, however when I print it in ardunio I am getting
"aT%3F"
I am logging the command in android and it is formed correctly My quesion is does c++/Arduino handle '?' differently then normal chars?
here is my arduino code->
while(bluetooth.available())
{
char toSend = (char)bluetooth.read();
if(toSend != '\0'){
if (toSend == 'a'){ i=0 ;}
inMsg[i] = toSend;
i++;
}
}
if(i == 5 )
{
// mock sending queries
if(inMsg[2] == '?'){
if(inMsg[1] == 'T'){
bluetooth.write("ty1");Serial.println("");
}else if(inMsg[1] == 'x'){ //normal cycle
bluetooth.write("xx1");
}else if(inMsg[1] == 'X'){ Serial.println(""); //booter
bluetooth.write("XX0");
}else if(inMsg[1] == 'N'){Serial.println(""); //On time
bluetooth.write("on1");
}else if(inMsg[1] == 'F'){ Serial.println(""); //Off time
bluetooth.write("of30");
}else if(inMsg[1] == 'S'){ Serial.println(""); //Speed percent
bluetooth.write("sp30");
}
}
// write to console
for(int j = 0; j < 5; j++){
Serial.write(inMsg[j]);
}
// new line
if(i == 5){Serial.println("");}
i = 0; // reset buffer
}
aT%3F <- this is mal formed
aS133 <- all the other are as I sent them from android
aN169
aF192
aS200
aXXXX
aYYYY
ayYYY
axXXX
my Android Code
...
command = "aT?bb";
writeCommand(command);
...
private void writeCommand(String command)
{
for (BluetoothGattCharacteristic characteristic : characteristics)
{
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) >0)
{
try {
characteristic.setValue(URLEncoder.encode(command, "utf-8"));
gatt.writeCharacteristic(characteristic);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
As pointed out in the comments above it was the URLEncoder that was changing the String. I have now changed this method to
private void writeCommand(String command)
{
for (BluetoothGattCharacteristic characteristic : characteristics)
{
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) >0)
{
characteristic.setValue(command);
gatt.writeCharacteristic(characteristic);
}else{
Log.i(TAG,"non write able");
}
}
}
I am using C++ Builder XE8. As the TOpenDialog doesn't work on Android, I am trying to make such thing myself. My logic is very simple. It'll start to check file and folders from "/storage" and show all items on TListView. If I touch a folder (name) it'll open that folder and if I touch a file, it should show the name on a label. So I assigned a function to TListView's OnItemClick event.
Here is code. fpath is String, Label1 is showing current folder and Label2 is showing selected file.
void __fastcall TForm1::lviewitemclck(TObject * const Sender, TListViewItem * const AItem)
{
if (AItem->Text == "<< BACK") {
if (!fpath.LastDelimiter("/") == 0) {
fpath = fpath.SubString(0, fpath.LastDelimiter("/"));
Label1->Text = fpath;
Form1->showfiles(fpath);
}
}
else if ( DirectoryExists(fpath+ AItem->Text)) {
fpath = fpath+ AItem->Text;
Label1->Text = fpath;
Form1->showfiles(fpath);
}
else if (FileExists(fpath+ AItem->Text)) {
Label2->Text ="File: "+ fpath+ AItem->Text;
}
}
Below is the code of function to scan for files & folders and show them. stringlist is TStringList.
void __fastcall TForm1::showfiles (String path)
{
TSearchRec sr; // for scaning files and folders
TSearchRec fr; // to check whether the folder is accessible or not.
if (FindFirst(path+"/*", faAnyFile, sr) == 0)
{
stringlist->Clear();
stringlist->Add("<< BACK"); // being used to replace the ".."
do{
if(sr.Name != "." && sr.Name != ".."){
if (DirectoryExists(path+"/"+sr.Name)) {
if (FindFirst(path+"/"+sr.Name+"/*", faAnyFile, fr) == 0) { // to check if the folder is accessible
stringlist->Add("/"+ sr.Name);
}
FindClose(fr);
}
else{
stringlist->Add("/"+ sr.Name);
}
}
} while (FindNext(sr) == 0);
}
FindClose(sr);
stringlist->Sort();
Form1->Item->Free();
Form1->ListView1->BeginUpdate();
Form1->ListView1->ClearItems();
for( int i =0;i< stringlist->Count; i++){
Form1->Item = Form1->ListView1->Items->Add();
Form1->Item->Text = stringlist->Strings[i];
}
Form1->ListView1->EndUpdate();
}
Here the problem is, if I use ListView1->ClearItems() in TForm1::showfiles it shows me an error saying "Access violation at address (random no), accessing address 00000009". And if I dont use ClearItems() it just add more lines with already existed lines. I am a beginer, so I dont know where I am doing wrong.
You should use:
ListView1->Items->Clear
The best way I have found so far is to dynamically create TListView and delete it each time you want to add new items( or calling showfiles function). I have written a small function (named it refresh) to release already created TListView and call another function(named it create_lview ) which can create an instance again then it calls the showfiles method.
void __fastcall TForm1::refresh()
{
if (!lview1->Released()) {
try{
lview1->Release();
Form1->create_lview();
Form1->showfiles(fpath);
}
catch(...){
Label2->Text = "error in cleaning";
}
}
}
Here is the code to create the TListView whenever you want.
void __fastcall TForm1::create_lview()
{
lview1 = new TListView(Form1);
lview1->Parent = Form1;
lview1->Height = 600;
lview1->Width = 400;
lview1->Position->X = 0;
lview1->Position->Y = 0;
lview1->Visible = true;
lview1->Enabled = true;
lview1->OnItemClick = lviewitemclck;
lview1->CanSwipeDelete = false;
}
Please comment if you find any mistake or you can do it more efficiently.
I have tried another way to avoid the error by replacing the Clear method with updating the Item Text, then deletes the unused last row of the ListView within the ListView1Change event.
void __fastcall TForm1::ListView1Change(TObject *Sender)
{
//Delete last item
while (ListView1->Items->Count>stringlist->Count){
ListView1->Items->Delete(ListView1->Items->Count-1);
}
}
void __fastcall TForm1::showfiles (String path)
{
TSearchRec sr; // for scaning files and folders
TSearchRec fr; // to check whether the folder is accessible or not.
//path+PathDelim+
if (FindFirst(path+PathDelim+'*', faAnyFile, sr) == 0)
{
stringlist->Clear();
stringlist->Add("<<--BACK"); // being used to replace the ".."
do{
if(sr.Name != "." && sr.Name != ".."){
if (DirectoryExists(path+PathDelim+sr.Name)) {
if (FindFirst(path+PathDelim+sr.Name+PathDelim+"*", faAnyFile, fr) == 0) { // to check if the folder is accessible
stringlist->Add(sr.Name);
}
FindClose(fr);
}
else{
stringlist->Add(sr.Name);
}
}
} while (FindNext(sr) == 0);
}
FindClose(sr);
stringlist->Sort();
for( int i =0;i< ListView1->Items->Count; i++){
ListView1->Items->Item[i]->Text="";
}
ListView1->BeginUpdate();
try {
for( int i =0;i< stringlist->Count; i++)
{
if (ListView1->Items->Count-1<i)
{
TListViewItem* Item=ListView1->Items->Add();
Item->Text=stringlist->Strings[i];
} else
{
TListViewItem* Item=ListView1->Items->Item[i];
Item->Text=stringlist->Strings[i];
}
}
}
catch (...) {
}
ListView1->EndUpdate();
/* */
}
i use different savegames in my app. "coins" , "levels" , ...
It works fine but if a conflict detected then its wrong result.
/**
* Conflict resolution for when Snapshots are opened. Must be run in an AsyncTask or in a
* background thread,
*/
Snapshots.OpenSnapshotResult processSnapshotOpenResult(Snapshots.OpenSnapshotResult result, int retryCount) {
retryCount++;
int status = result.getStatus().getStatusCode();
Log.i(TAG, "Load Result for saveGame<" + savedGame.getName() + "> status: " + status);
if (status == GamesStatusCodes.STATUS_OK) {
return result;
} else if (status == GamesStatusCodes.STATUS_SNAPSHOT_CONTENTS_UNAVAILABLE) {
return result;
} else if (status == GamesStatusCodes.STATUS_SNAPSHOT_CONFLICT) {
saveResolveConflictGameData = true;
Log.i(TAG, "Konflikt aufgetreten");
Snapshots.OpenSnapshotResult resolveResult = null;
Snapshot snapshot = result.getSnapshot();
Snapshot conflictSnapshot = result.getConflictingSnapshot();
Snapshot mResolvedSnapshot = null;
mResolvedSnapshot = snapshot;
SnapshotMetadata s1Meta = snapshot.getMetadata();
SnapshotMetadata cMeta = conflictSnapshot.getMetadata();
// resolveConflict and get new merged Parser Object
//
Parser conflictParserTemp = savedGame.resolveConflict(snapshot, conflictSnapshot);
if ( conflictParserTemp == null) {
Log.e(TAG, "savedGame.resolveConflict(snapshot,conflictSnapshot) Error");
return result;
}
//
// wurde schon ein conflict behandelt ?
//
if ( conflictParser != null ) {
// merge previous Conflict with this conflict
conflictParser.merge(conflictParserTemp);
} else {
// set first conflict Parser
conflictParser = conflictParserTemp;
}
Log.i(TAG, String.format("Games.Snapshots.resolveConflict() Step %d", retryCount));
resolveResult =
Games.Snapshots.resolveConflict(
activity.mGoogleApiClient, result.getConflictId(), mResolvedSnapshot).await();
if (retryCount < MAX_SNAPSHOT_RESOLVE_RETRIES) {
// Recursively attempt again
return processSnapshotOpenResult(resolveResult, retryCount);
} else {
// Failed, log error and show Toast to the user
String message = "Could not resolve snapshot conflicts";
Log.e(TAG, message);
Toast.makeText(activity.getBaseContext(), message, Toast.LENGTH_LONG).show();
return resolveResult;
}
}
// Fail, return null.
return null;
}
The Error is that if I load savegame "coins" I become all conflicts from other savegames.
I see it here.
SnapshotMetadata s1Meta = snapshot.getMetadata();
SnapshotMetadata cMeta = conflictSnapshot.getMetadata();
The Snapshot for korrekt coins savegame show this:
SnapshotMetadataEntity{Game=GameEntity{ApplicationId=520840013521,
DisplayName=Crush me, PrimaryCategory=Simulation,
SecondaryCategory=null, Description=hallo, DeveloperName=steffen
höhmann, IconImageUri=null, IconImageUrl=null, HiResImageUri=null,
HiResImageUrl=null, FeaturedImageUri=null, FeaturedImageUrl=null,
PlayEnabledGame=true, InstanceInstalled=true,
InstancePackageName=cherry.de.wubbleburst, AchievementTotalCount=0,
LeaderboardCount=0, RealTimeMultiplayerEnabled=false,
TurnBasedMultiplayerEnabled=false, AreSnapshotsEnabled=true,
ThemeColor=00456B, HasGamepadSupport=false},
Owner=PlayerEntity{PlayerId=113260033482974102226,
DisplayName=shoehmi, HasDebugAccess=false, IconImageUri=null,
IconImageUrl=null, HiResImageUri=null, HiResImageUrl=null,
RetrievedTimestamp=1454003980807, Title=Anfänger,
LevelInfo=com.google.android.gms.games.PlayerLevelInfo#1e1b36},
SnapshotId=drive://113260033482974102226/520840013521/coins,
CoverImageUri=null, CoverImageUrl=null, CoverImageAspectRatio=0.0,
Description=null, LastModifiedTimestamp=1454004003382, PlayedTime=-1,
UniqueName=coins, ChangePending=true, ProgressValue=-1}
drive://113260033482974102226/520840013521/coins
and the snapshotData:
timestamp;coins#1453929273252;100#1453929280956;-70#230179;70
but he shows me savegame snaphot from "level" savegame as conflicted Snapshot:
levelId;points#1;3241#2;9634
and the Conflict Snapshot Metadata say it is a "coins" savegame:
SnapshotMetadataEntity{Game=GameEntity{ApplicationId=520840013521,
DisplayName=Crush me, PrimaryCategory=Simulation,
SecondaryCategory=null, Description=hallo, DeveloperName=steffen
höhmann, IconImageUri=null, IconImageUrl=null, HiResImageUri=null,
HiResImageUrl=null, FeaturedImageUri=null, FeaturedImageUrl=null,
PlayEnabledGame=true, InstanceInstalled=true,
InstancePackageName=cherry.de.wubbleburst, AchievementTotalCount=0,
LeaderboardCount=0, RealTimeMultiplayerEnabled=false,
TurnBasedMultiplayerEnabled=false, AreSnapshotsEnabled=true,
ThemeColor=00456B, HasGamepadSupport=false},
Owner=PlayerEntity{PlayerId=113260033482974102226,
DisplayName=shoehmi, HasDebugAccess=false, IconImageUri=null,
IconImageUrl=null, HiResImageUri=null, HiResImageUrl=null,
RetrievedTimestamp=1454003980807, Title=Anfänger,
LevelInfo=com.google.android.gms.games.PlayerLevelInfo#1e1b36},
SnapshotId=drive://113260033482974102226/520840013521/coins,
CoverImageUri=null, CoverImageUrl=null, CoverImageAspectRatio=0.0,
Description=null, LastModifiedTimestamp=1454004003382, PlayedTime=-1,
UniqueName=coins, ChangePending=true, ProgressValue=-1}
drive://113260033482974102226/520840013521/coins
Why only if conflict occured and without conflicts its running correct and
save / load correct??
Please Help me???
sorry for my english ;)
I can use the code below with getEncryptionState to determine whether the phone is encrypted.
To proceed, I need to verify thet the user input password is correct or not.
So I tried the verifyEncryptionPassword(), but it doesn't work well: every time I call this method, I always get the same return value: 0.
That means it takes any string as a correct encryption password which is apparently wrong.
IMountService mountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
boolean isEncrypted;
try {
isEncrypted = (mountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE);
if (isEncrypted) {
int result = mountService.verifyEncryptionPassword(candidatePw);
if (result == 0) {
Log.d(TAG, "Pw verifies");
} else if (result != -2) {
Log.d(TAG, "Pw mismatch");
} else {
Log.e(TAG, "verified failed");
}
}
} catch (Exception e) {
}
How can you verify the encryption password?