Android API-versioner. "Robot Heart": Hur man använder Android-systemets API för personliga ändamål



Vänligen dela ditt tomma projekt, redo för publicering för TV-enheter.
Jag verkar inte kunna publicera något, och nu har det avvisats med följande fel:
APK:8
Ingen avisering som spelas nu"
Din app innehåller ingen "Spelar nu"-avisering för när användaren har valt HEM-knappen i appen. Se dokumentationen om att visa ett kort som spelas nu för mer information.
APK:8
Spela/Paus nyckelhändelse respekteras inte under uppspelning
Dina medieappar som spelar upp video- eller musikinnehåll måste respektera uppspelnings-/pausknappen under uppspelning. Se vår Media Play/Pause-dokumentation och Uppdatera uför mer information.
Saknar DPad-funktionalitet
Din app kräver användarinteraktion för menyer eller appnavigering. Se till att alla menyer och appnavigering är fullt fungerande med en DPad. Se vår dokumentation för DPAD-kontroll och hårdvarudeklaration.
Nåväl, jag bifogade inte banderollen
Ingen appbanner i full storlek
Din app innehåller ingen appbanner i full storlek eller är den inte synlig i startprogrammet. Vi siktar på 1080P, som vi anser vara xhdpi. Appar bör inkludera bannern i mappen xhdpi (320 dpi) drawables med en storlek på (320px × 180px). Se vår dokumentation för hemskärmsbanner och UI-mönster.
Titeln ska hjälpa användare att identifiera appar i startprogrammet. Se vår dokumentation för visuell design och användarinteraktion för mer information.
Jag skulle vara väldigt tacksam för ett fungerande tomt skelett med ett manifest.

Från

Under utvecklingsprocessen stötte jag på en mycket märklig situation, vars rötter fortfarande är oklara, men en lösning hittades.
Så. Delphi 10.3.3. Ren ansökan - töm blankett och knapp. Fungerar utmärkt på olika enheter förutom Samsung Galaxy Tab A (2016). Android 5.1.1
Programmet kraschar innan det ens hinner ladda. Några. Samtidigt startar den, kompilerad på en annan dator, normalt. Och även efter att ha ändrat SDK/NDK på den, kraschar ingenting.
LogCat ger en extremt märklig bild
java.lang.IllegalArgumentException: Det går inte att ladda inbyggt bibliotek: /data/app-lib/com.embarcadero.Project1-1/libProject1.so
Vi börjar experimentera med SDK, NDK, etc. Jag installerade även snabbkorrigeringar för 10.3.3.
Jag ska genast säga att SDK/NDK installerades separat via Android studio och laddades inte ner tillsammans med Delphi. Skynda dig inte att sluta läsa nu!)) På en annan dator, där allt fungerar, installerades allt på exakt samma sätt.
Kort sagt, många kombinationer av SDK/NDK-versioner har testats.
Resultatet är detta. Med den gradvisa nedgraderingen av NDK tog allt fart med NDK v22.

Samtidigt har SDK-versionen tydligen inte så stor inverkan, eftersom det här alternativet fungerar bra

Jag repeterar. Allt fungerade på andra enheter och på nyare Ndk. Xiaomi Mi Pad4, Samsung Galaxy Tab A (2019), Xiaomi Redmi 5 och 5Plus

Tack för ditt deltagande och hjälp med att reda ut spillrorna @Andrey Efimov

Från

Jag har två applikationer i mitt arbete, och båda är inte avsedda för Play-marknaden, eftersom de har ett begränsat användningsområde, faktiskt rent företagsinterna. Så det är inte önskvärt att lägga upp dem på alternativa butiker applikationer.
Uppdateringsfrågan uppstår automatiskt. Om vi ​​för första gången kan installera applikationen själva med hjälp av administratörer, är det inte så lätt att uppdatera dem. Och kontingenten av användare kan inte klara av att "ladda ner APK-filen från länken, hitta var webbläsaren laddade ner den och starta den senast nedladdade manuellt, och inte vilken som helst"...
Det enklaste sättet är att låta applikationen ladda ner en ny kopia från webbplatsen och köra systeminstallationsprogrammet på den resulterande filen.
Men färska Andoirds förbjuder direkt att göra detta. Behöver filepropvider. Jag tillbringade hela dagen med att leta runt med manualer och YT,
Detta är vad som hände som ett resultat.
Om du har 10.3.3 som jag behöver du inte gå in ... i manifestet och din fil file_paths.xml (eller vad du nu rekommenderas att kalla det på Internet) under driftsättning.
Nu görs allt detta, om än något konstigt och ensidigt, men automatiskt, genom att markera kryssrutan Säker fildelning

Efter detta kommer manifestet automatiskt att inkludera ett av filplaceringsalternativen som du kan hitta på Internet. Alias ​​extern-sökväg används
Filen som visas i figuren skapas automatiskt av Delphi själv.

Nu återstår bara att gissa vilken väg som faktiskt kommer att ersätta "."
Som praktiken har visat ser inte alla vägar ut som de ser ut, baserat på sunt förnuft. En hel dag med att använda GetHomeDir och andra användbara TPath-metoder fick mig att bli helt överraskad.
Det visade sig vara enklare (?)
st:TMemoryStream; OutputDir: JFile; ApkFile: JFile; ApkUri: Jnet_Uri; sökväg, filnamn: sträng; ... OutputDir:= TAndroidHelper.Context.getExternalCacheDir(); sökväg:= JStringToString(OutputDir.getAbsolutePath); filnamn:= sökväg+"/ASDroid2.apk"; ApkFile:= TJfile.JavaClass.init(StringToJstring(filnamn)); FApkUri:= TAndroidHelper.JFileToJURI(ApkFile); st.Position:= 0; st.SaveToFile(filnamn); Observera att i provider_paths ställer vi in ​​externa-sökvägar, och i koden letar vi efter ExternalCacheDir.!!! (För.Otroligt.Kreativa.Känner!)
Då är allt enkelt. FApkUri skickas till avsikten och lanseras
Den sista koden är ungefär så här. (nedladdning i en ström med ett litet anpassat API, men inget viktigt där, du kan ignorera det)
procedure TasdSettingsFrame.bDownloadClick(Avsändare: TObject); begin ($IFDEF ANDROID) bDownload.Enabled:= False; DownloadAndRun(); ($ENDIF) slut; ($IFDEF ANDROID) procedur TasdSettingsFrame.DownloadAndRun(); begin ttask.Run(procedur var aapi:TasdAPI; st:TMemoryStream; OutputDir: JFile; ApkFile: JFile; ApkUri: Jnet_Uri; sökväg, filnamn: sträng; start st:= TMemoryStream.Create; aapi:= TasdAPI.Clone(_ ; prova aapi.OnReceiveData; om aapi.Err.Code=0 börjar OutputDir:= TAndroidHelper.Context.getExternalCacheDir(JStringToString(OutputDir.getAbsolutePath2); "; ApkFile:= TJfile.JavaClass.init(StringToJstring(filnamn)); (noll, proceduren börjar bDownload.Enabled:= true; StartActivity(FApkUri); slut; slutligen st.Free; end; slutet; procedure StartActivity(ApkUri: Jnet_Uri); var Intent: JIntent; begin Intent:= TJIntent.Create(); Intent.setAction(TJIntent.JavaClass.ACTION_VIEW); Intent.addFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK eller TJIntent.JavaClass.FLAG_ACTIVITY_CLEAR_TOP eller TJIntent.JavaClass.FLAG_GRANT_WRITE_URI_PERMISSION eller TJIntent.FLAG_GRANTIPERMISSIONREM_GRANTIPERMISSION); Intent.setDataAndType(apkuri, StringToJString("application/vnd.android.package-archive")); TAndroidHelper.Activity.startActivity(Intent); slutet; procedure TasdSettingsFrame.OnReceiveData(const Avsändare: TObject; ACContentLength: Int64; AReadCount: Int64; var Abort: Boolean); begin tthread.Synchronize(noll, procedur börjar pb1.Max:= ACContentLength; pb1.Value:= AReadCount; end); slutet; ($ENDIF) Frågor kvarstår naturligtvis om varför det är så konstigt med kataloger, men det finns ingen önskan att ta reda på det ännu. Det fungerar – rör det inte.
Lycka till allihopa.
UPD.
För att systeminstallationsprogrammet ska starta måste du komma ihåg att markera ytterligare en ruta

Från

Hälsningar. På Internet hittade jag ett BASS-bibliotek för Android och följaktligen ett omslag för det för Delphi.

Allt verkar fungera bra, men när du ställer in biblioteket med metoderna
BASS_GetConfigPtr, BASS_SetConfigPtr för att arbeta med strängparametrar det finns ett problem.
På Windows arbetade jag lätt med detta, där räcker det att använda denna konstruktion

PAnsiChar(BASS_GetConfigPtr(configId)) och hämta värdet. BASS_SetConfigPtr(configId, PAnsiChar(value)) och ställ in värdet. Men den här metoden fungerar inte under Android, av åtminstone en anledning - den förstår inte vad PAnsiChar är. På docwiki.emarcadero.com finns en sådan artikel. Vilket säger att PAnsiChar måste ersättas med en av tre: System.String, System.MarshalledString eller System.SysUtils.TStringBuiler
Först nu, om du använder MarshalledString, då när du försöker få värdet, fryser applikationen bara och det är allt.
Då tänkte jag, eftersom biblioteket är skrivet i Java (förmodligen), kan det vara värt att försöka använda JNI för att arbeta med det, som i Java-filen som följde med biblioteket. Där hittade jag deklarationer av dessa funktioner och märkte att returtypen var Object (ja, utan att kunna Java, jag antog bara att detta också bara var en referens till ett värde, till exempel som PAnsiChar i Delphi på Windows).

Men när jag försöker använda detta på något sätt stöter jag på problem i form av ett kompileringsfel eller att en annan applikation fryser.
Eftersom Object returneras, bestämde jag mig för att prova alternativet med JObject och JString, men inget av alternativen vill fungera, återigen fel i kompileringsstadiet eller applikationen fryser. Jag kanske gör något fel.

Generellt sett skulle jag uppskatta din hjälp!

Från

Bra tid!
Det finns en idé att göra det möjligt att säkerhetskopiera applikationsdata till Google Drive under det aktuella användarkontot. Jag hittade inget liknande på forumet, kanske någon redan har försökt lösa ett liknande problem? Jag är först och främst intresserad av att arbeta med Gdrive.

Från

Tja, allt är i princip detsamma som alltid, antingen är jag ett lamm eller så fungerar inte skidorna)
Och allt är enkelt - jag vill att medan data laddas ner från servern genom att klicka på en knapp, kommer användaren helt enkelt att få ett svar i form av något slags snurrande skräp och han kommer att se att processen pågår och att programmet fryser inte och petar inte någonstans igen.
Hittills, för att testa, har jag helt enkelt gjort en Uppdatera-knapp (hastighetsknapp med bild), data laddas helt enkelt och visas i GridPanel, och ovanpå den, så att användaren inte kan peka någonstans, har jag banat den med en panel med en bild, roterad av en timer (det hela är ovanpå Visible: =falskt). Och när vi klickar på knappen Uppdatera visar vi panelen längst upp i rutnätet och startar timern, sedan laddar samma hanterare/procedur in data, och i slutet stoppar vi timern och döljer det genomskinliga, för övrigt, panel. Alya så här:
procedure TForm1.SB_DataUpdateClick(Avsändare: TObject); börja //visa laddningslogotypen P_showLoad.Visible:= true; Timer_load_rotate.Enabled:= sant; //starta timern GetDeD_List(DE_set.Date); //proceduren för att ladda och visa det vi behöver, vilket tar mycket lång tid att slutföra //och döljer laddningslogotypen Timer_load_rotate.Enabled:= false; //i omvänd ordning P_showLoad.Visible:= false; slutet;
aaand... ingen jäkla sak händer som jag vill(
I slutändan visas inte denna logotyp alls, och om vi tar bort dess gömställe, kommer den att visas först när allt är laddat. Logiken började berätta för mig att jag borde ha visat det på något sätt genom att köra det i en parallell asynkron tråd, så här:

Från

procedure TForm1.SB_DataUpdateClick(Avsändare: TObject); begin TThread.Queue(TThread.Current, //TThread.Queue TThread.Synchronize ForceQueue procedure() start P_showLoad.Visible:= true; Timer_load_rotate.Enabled:= true; end); GetDeD_List(DE_set.Date); //proceduren för att ladda och visa vad vi behöver, vilket tar mycket lång tid att slutföra; Och igen, det visas först efter att allt har laddats och hela proceduren har fungerat. Och jag har redan provat allt, Synchronize och ForceQueue; och genom TTask.Run och |task:= TTask.Create(procedur () ... etc.| ingenting fungerar, för mitt liv kommer hela den här grejen att visas först efter att klickproceduren är helt klar. Kanske jag Jag gräver i riktningen i allmänhet och görs det annorlunda kanske jag fortfarande felsöker på Win32, och inte allt på Android, men det finns ett par alternativ och regler som fungerar på det? kan jag inte förstå vad som är vad... Det borde vara något enkelt, men jag kan bara inte lista ut hur(
Google Play kommer inte längre att stödja 32-bitars Android-appar från och med den 1 augusti 2019.
Och du kan inte lägga upp nya på Google Play längre.
Den senaste Delphi XE tillåter dig inte att skapa 64-bitars Android-applikationer.

  • Vem vet när en ny version med 64-bitars stöd kommer att dyka upp? De sa att det var slutet på sommaren, men sommaren är över Senaste besökare

    0 användare online

  • Ingen registrerad användare tittar på denna sida Alla som har skrivit mer eller mindre seriösa program för olika mobiloperativsystem vet att Android är det mest öppna operativsystemet för utvecklare. Tillgänglig för tredje part det är mycket bredare, systemet i sig är mer flexibelt och reglerna för att släppa ut applikationer på marknaden är mycket liberala. Android har dock också ett antal system-API:er som är dolda från tredjepartsapplikationer och är endast tillgängliga för lagerprogramvara. I den här artikeln kommer vi att försöka ta reda på hur man kommer åt dessa API:er och vilka möjligheter de öppnar.

    Lite teori

    Som vi alla vet finns det ett sådant koncept i Android - applikationsbehörigheter(behörigheter, behörigheter). Behörigheter skrivs in i varje applikations Manifest.xml-fil och bestämmer vilka API-funktioner applikationen har åtkomst till. Om du vill arbeta med kameran, lägg till raden i Manifest.xml . Du behöver tillgång till minneskortet - android.permission.READ_EXTERNAL_STORAGE. Allt är enkelt och logiskt, och alla krafter som är tillgängliga för applikationer är väldokumenterade.

    Det finns dock en mycket viktig detalj i detta harmoniska schema, som skaparna av Android själva kallar åtkomstnivå(skyddsnivå). För att förstå vad detta är, försök att lägga till följande rad i Manifest.xml för något av dina program:

    I teorin, denna myndighet bör öppna åtkomst till ett API som låter dig sätta din smartphone i flygplansläge, slå på/av GPS och göra andra användbara saker. Men IDE tycker inte det och markerar därför omedelbart raden som ett fel med formuleringen "Tillstånd ges endast till systemappar". Detta är en varning om ett brott mot just den åtkomstnivån. IDE verkar säga till oss: ja, du kan försöka ge din applikation behörigheten WRITE_SECURE_SETTINGS, men Android kommer fortfarande inte att tillåta dig att använda API:et som tilldelats den förrän du gör din applikation till ett system. Vad betyder "systemisk" i detta fall? Det betyder: du kommer att underteckna den med samma digital nyckel, hur själva firmwaren är signerad (försök att få tag på en sådan nyckel från någon Samsung eller LG!).

    Officiellt har Android fyra åtkomstnivåer:

    • vanligt- "normala" behörigheter, som ger applikationen tillgång till ofarliga funktioner som inte kan användas med uppsåt (exempel: SET_ALARM, ACCESS_NETWORK_STATE, VIBRATE). Systemet berättar inte ens att programmet använder dem alls;
    • farlig- "farliga" krafter, användaren kommer att informeras om dem när applikationen installeras eller kommer att se ett varningsfönster i Android 6.0 (exempel: READ_SMS, SEND_SMS, CALL_PHONE, READ_CALL_LOG);
    • signatur- endast tillgängligt för applikationer signerade med firmware-nyckeln (exempel: GET_TASKS, MANAGE_USERS, WRITE_SETTINGS, MOUNT_UNMOUNT_FILESYSTEMS);
    • privilegierad- tillgängligt för applikationer som finns i katalogen /system/priv-app.

    I de flesta fall är signaturnivåer och privilegierade åtkomstnivåer likvärdiga. Till exempel, för att erhålla behörigheten MANAGE_USERS, måste en applikation antingen vara signerad med en firmwarenyckel eller placerad i katalogen /system/priv-app. Men det finns undantag: t.ex. behörigheten MANAGE_DEVICE_ADMIN har signaturåtkomstnivån, det vill säga det enda sättet att få det är att signera applikationen med firmwarenyckeln.

    Det finns också en uppsättning interna åtkomstnivåer införda i Android för att lösa vissa problem: installatör, utveckling, förinstallerad, appop, före 23. I huvudsak är dessa kryckor, och i det här skedet kanske du inte tänker på dem, men vi kommer att återgå till utvecklingsåtkomstnivån, och det kommer att vara mycket användbart för oss. Under tiden, låt oss prata om hur vi får de åtkomstnivåer vi behöver och vad de ger.

    privilegierad åtkomstnivå

    Privileged är inte den högsta åtkomstnivån och tillåter dig inte att använda hela Android API. Men i de flesta fall visar det sig vara ganska tillräckligt, eftersom det låter dig installera och ta bort applikationer och användare (INSTALL_PACKAGES, DELETE_PACKAGES, MANAGE_USERS), hantera statusfältet (STATUS_BAR), hantera vissa energiinställningar (WRITE_SECURE_SETTINGS), läsa och ändra Wi-Fi-inställningar (READ_WIFI_CREDENTIAL , OVERRIDE_WIFI_CONFIG), inaktivera applikationer och deras komponenter (CHANGE_COMPONENT_ENABLED_STATE) och mycket mer.

    För att ett program ska få den privilegierade åtkomstnivån måste det installeras i katalogen /system/priv-app, vilket innebär att det måste vara förinstallerat som en del av firmware. Men med root kan vi lägga in vår applikation denna katalog använder två funktioner:

    // En verktygsfunktion som helt enkelt kör ett skalkommando static public boolean runCommandWait(String cmd, boolean needsu) ( try ( String su = "sh"; if (needsu) ( su = "su"; ) Process process = Runtime.getRuntime ().exec(ny sträng(su, "-c", cmd)); catch (InterruptedException e) ( throw new RuntimeException(e); ) ) // Funktionen gör den angivna applikationen till en systemapplikation och skickar smarttelefonen till en mjuk omstart static public void makeAppSystem(String appName) ( String systemPrivAppDir = "/system/ priv-app/" ; String systemAppDir = "/system/app/"; String appPath = "/data/app/" + appnamn; // Anslut /system i läs-skrivläge om (!runCommandWait("mount -o remount ,rw /system" , true)) ( Log.e(TAG, "makeAppSystem: Kan inte montera /system"); return; ) int api = Build.VERSION.SDK_INT; String appDir = systemPrivAppDir; till /system/priv- app eller /system/app beroende på Android-versionen if (api >= 21) (runCommandWait("cp -R " + appPath + "* " + appDir, true); runCommandWait("chown -R 0:0 " + appDir + appName + "*", true); runCommandWait("rm -Rf " + appPath + "*", true); ) annat ( if (api< 20) { appDir = systemAppDir; } runCommandWait("cp " + appPath + "* " + appDir, true); runCommandWait("chown 0:0 " + appDir + appName + "*", true); runCommandWait("rm -f " + appPath + "*", true); } // Отправляем смартфон в мягкую перезагрузку Shell.runCommand("am restart", true); }

    Jag kommer inte att beskriva runCommandWait-funktionen, den kör helt enkelt ett skalkommando och väntar på att det ska slutföras (läs mer i min artikel om att skriva applikationer med roträttigheter). MakeAppSystem-funktionen accepterar i sin tur fullständiga namn applikation (detta är samma com.example.app som du anger när du skapar ett nytt projekt i Android Studio) och överför det till /system/priv-app eller /system/app, beroende på vilken version av Android du använder. Koden kan verka lite konstig för dig, men i själva verket är den helt korrekt och tar hänsyn till två faktorer:

    • före Android 4.4 (API-nivå: 20) fanns inte katalogen /system/priv-app och alla systemapplikationer fanns i /system/app;
    • Från och med Android 5.0 (API-nivå: 21), lagras applikationspaket inte bara i /data/app och /system/priv-app, utan placeras i sina egna separata underkataloger.

    Hur använder man denna kod? Det är väldigt enkelt: du definierar i Manifest.xml för din applikation alla privilegierade krafter som den behöver, oavsett IDE-fel. Sedan, alldeles i början av applikationskoden, infogar du ett anrop till makeAppSystem med namnet på själva applikationen som argument, kompilerar och kör. Efter start flyttar applikationen sig själv till /system/priv-app, startar om smarttelefonen och alla privilegierade API:er öppnas för den.

    Listan över privilegierade befogenheter finns i Android-källorna. Sök bara på ordet privilegierad. Mer om hur du använder dem lite senare.

    Signaturåtkomstnivå

    Genom att signera med en firmwarenyckel kan du få den högsta nivån av åtkomst till API:t - signatur. En applikation med sådan åtkomst kan göra nästan vad som helst: manipulera alla Android-inställningar (WRITE_SETTINGS, WRITE_SECURE_SETTINGS), ge applikationer administratörsrättigheter (MANAGE_DEVICE_ADMINS), trycka programiskt på knappar och ange data i valfritt fönster (INJECT_EVENTS) och mycket mer.

    Det är nästan omöjligt att få denna nivå av åtkomst på lagerfirmware. Ingen smartphonetillverkare kommer att ge dig en nyckel för att signera sin firmware. Men om vi pratar om om anpassad firmware, då blir allt lite lättare. Till exempel, nattliga versioner av samma CyanogenMod (och låt mig påminna dig om att den har fler användare än användare av alla versioner Windows-telefon, tillsammans) är signerade med en testnyckel, och dess egenhet är att den är allmänt tillgänglig.

    Men det är inte allt, CyanogenMod har en säkerhetsmekanism som till skillnad från ren Android, låter dig erhålla signaturåtkomstnivån inte för absolut alla applikationer signerade med firmwarenyckeln, utan bara för de som finns i /system/priv-app . Därför, för att få signaturåtkomstnivån i CyanogenMod (inte i Cyanogen OS, betonar jag), måste du:

    1. Lägg till de nödvändiga behörigheterna i programmets Manifest.xml.
    2. Lägg till ett anrop till applikationen till funktionen makeAppSystem() som beskrivs i föregående avsnitt.
    3. Signera releaseversionen av applikationen med plattformsnyckeln från CyanogenMod-förvaret.

    Utveckling av åtkomstnivå

    Android har en speciell utvecklingsåtkomstnivå, vars skillnad är att applikationer inte får den genom att placera den i /system/priv-app eller använda en digital signatur av firmware, utan dynamiskt. Det vill säga, systemet kan ge denna nivå av åtkomst till vilken applikation som helst, eller så kan den återkalla den. Men det viktigaste är att, med root-rättigheter, kan applikationen ge sig själv denna nivå av åtkomst oberoende.

    För att göra detta, använd bara kod så här:

    RunCommandWait("pm grant " + appName + " android.permission.WRITE_SECURE_SETTINGS", true);

    I det här fallet kommer appName-applikationen att få tillståndet WRITE_SECURE_SETTINGS, oavsett var den är värd och vilken nyckel den är signerad med. Häftigt? Utan tvekan, men WRITE_SECURE_SETTINGS är faktiskt den enda användbara behörigheten med utvecklingsåtkomstnivån. De återstående fjorton är befogenheter för felsökning och testning (läsa loggar, minnesdumpar och så vidare).

    Hur använder man systemets API?

    Det största problemet du kommer att stöta på när du arbetar med systemets API är den fullständiga (med några få undantag) bristen på dokumentation. Du hittar nästan inget omnämnande av detta varken i officiella eller inofficiella manualer. Information kommer att behöva samlas in bit för bit, genomsöka hundratals sidor i forum och läsa tusentals sidor med Android-källkod. Dock om än liten, men en utgångspunkt i form av ett par användbara exempel vi ger dig den.

    WRITE_SECURE_SETTINGS

    WRITE_SECURE_SETTINGS-tillståndet introducerades i Android 4.2 för att skydda vissa kritiska Android-inställningar. Dessa inställningar inkluderar: slå på/stänga av flygplansläge, hantering av plats och dataöverföringsinställningar. Den är skyddad av tre åtkomstnivåer: signatur, privilegierad och utveckling. Det vill säga, du kan använda någon av ovanstående metoder för att erhålla en åtkomstnivå för att ge din applikation behörigheten WRITE_SECURE_SETTINGS.

    Hur använder man de nya möjligheterna? Till exempel, så här:

    // Läs det aktuella inställningsvärdet boolean isEnabled = Settings.System.getInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1; // Växla inställningen Settings.System.putInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, isEnabled ? 0: 1); // Skicka en avsikt att byta Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); intent.putExtra("tillstånd", !isEnabled); skickaBroadcast(avsikt);

    Detta är en mycket enkel kod som dumt växlar smarttelefonen till flygplansläge eller vice versa beroende på det aktuella tillståndet. Allt är enkelt och koncist.

    INSTALL_PACKAGES

    Som namnet antyder tillåter INSTALL_PACKAGES-behörigheten dig att "tyst" installera APK-paket på systemet. Den här funktionen kan användas antingen av applikationer signerade med en firmwarenyckel (signatur) eller installerade i /system/priv-app . I det här fallet är det inte ens nödvändigt att använda Java API, ring bara kommandot pm (Package Manager) från konsolen med nödvändiga parametrar:

    RunCommandWait("pm install " + apkPath, false);

    Efter att kommandot har bearbetats kommer apkPath-paketet att installeras på systemet. Du kan hävda att samma sak kan göras med root-rättigheter, och du skulle ha rätt: i det här fallet räcker det att ändra det sista argumentet för runCommandWait()-funktionen till true. Det är dock värt att komma ihåg att applikationer med roträttigheter för det första leder till att ett fönster dyker upp som ber användaren om lämpliga behörigheter, och för det andra loggas de av samma SuperSU. Annars räcker det att registrera din programvara en gång i /system/priv-app, och den kommer att kunna installera så mycket programvara du vill utan några frågor.

    Istället för slutsatser

    Det är allt. Att komma åt det privata API:et i Android är inte så svårt att uppnå. Å andra sidan, med legitim programvara, är det i de flesta fall ingen mening att använda det enklare att få root-rättigheter och anropa lämpliga konsolkommandon: inställningar för att ändra inställningar, kl för att installera/avinstallera applikationer, setprop för att ändra lågnivåinställningar och så vidare. Men om vi pratar om inte helt vanlig programvara...

    Android SDK innehåller en mängd olika bibliotek, dokumentation och verktyg som hjälper till att utveckla mobila applikationer för Android-plattformen.

    • API Android SDK - Android API-bibliotek tillhandahålls för applikationsutveckling.
    • SDK-dokumentation - innehåller omfattande referensinformation som beskriver vad som ingår i varje paket och klass och hur man använder det när man utvecklar applikationer.
    • AVD (Android Virtuell enhet) är en interaktiv emulator av en Android-mobilenhet. Med hjälp av en emulator kan du köra och testa applikationer utan att använda en riktig Android-enhet.
    • Utvecklingsverktyg - SDK innehåller flera utvecklingsverktyg som låter dig kompilera och felsöka de applikationer du skapar.
    • Exempelkod - Android SDK tillhandahåller exempelapplikationer som visar några av Android-funktioner, och enkla program som visar hur du använder specifika API-funktioner i din kod.

    SDK- och Android API-nivåversioner

    Innan början Android applikationsutveckling Det är till hjälp att förstå plattformens övergripande tillvägagångssätt för att hantera API-förändringar. Det är också viktigt att förstå Android API-nivå (API Layer Identifier) ​​och dess roll för att göra din app kompatibel med de enheter som den kommer att installeras på.

    API-nivå- ett heltalsvärde som unikt identifierar Android-plattformens API-version. Plattformen tillhandahåller API-strukturer som applikationer kan använda för att interagera med Android-system. Varje efterföljande version av Android-plattformen kan innehålla API-uppdateringar.

    Uppdateringar av API-strukturen är utformade för att säkerställa att det nya API:et förblir kompatibelt med tidigare versioner av API:et. De flesta ändringar i API:t är alltså kumulativa och introducerar ny funktionalitet eller fixar tidigare. Eftersom vissa av API:erna uppdateras ständigt, rekommenderas inte föråldrade API:er för användning, men tas inte bort på grund av kompatibilitet med befintliga applikationer.

    API-nivån som en Android-applikation använder bestäms av en heltalsidentifierare som anges i konfigurationsfilen för varje Android-applikation.

    Tabellen bestämmer överensstämmelsen mellan API-nivån och Android-plattformsversionen.

    Överensstämmelse med plattformsversion och API-nivå

    Verktyg för applikationsutveckling och felsökning

    Utöver emulatorn innehåller SDK även många andra verktyg för att felsöka och installera de applikationer du skapar. Om du utvecklar Android-appar med Eclipse IDE, används många av kommandoradsverktygen som ingår i SDK redan när du bygger och kompilerar ditt projekt. Men förutom dem innehåller SDK:n ett antal användbara verktyg för att utveckla och felsöka applikationer:

    • android- ett viktigt utvecklingsverktyg lanserat från kommandoraden som låter dig skapa, ta bort och konfigurera virtuella enheter, skapa och uppdatera Android-projekt (när du arbetar utanför Eclipse-miljön) och uppdatera Android SDK med nya plattformar, tillägg och dokumentation;
    • Dalvik Debug Monitor Service (DDMS)- integrerad med Dalvik Virtual Machine, standard virtuell maskin Android-plattformen, det här verktyget låter dig hantera processer på både emulatorn och enheten, och hjälper också till att felsöka applikationer. Du kan använda den här tjänsten för att avsluta processer, välja en specifik process för felsökning, generera spårningsdata, se heap- eller trådinformation, ta emulator- eller enhetsskärmdumpar och mycket mer;
    • Hierarchy Viewer- ett visuellt verktyg som låter dig felsöka och optimera användargränssnitt applikation som utvecklas. Den visar ett visuellt träd i vyhierarkin, analyserar prestandan för att rita om grafik på skärmen och kan utföra många andra analysfunktioner GUI applikationer;
    • Layoutoptär ett kommandoradsverktyg som hjälper till att optimera uppmärkningsscheman och uppmärkningshierarkier i programmet du skapar. Nödvändigt för att lösa problem när man skapar komplexa grafiska gränssnitt som kan påverka applikationsprestanda;
    • Dra 9-patc h- grafikredigerare, som låter dig enkelt skapa NinePath-grafik för det grafiska gränssnittet för utvecklade applikationer;
    • sqlite3- ett verktyg för åtkomst till SQLite-datafiler som skapats och används av Android-applikationer;
    • Traceview- Detta verktyg ger en grafisk analys av spårningsloggar som kan genereras från applikationer;
    • mksdcardär ett diskavbildningsverktyg som du kan använda i en emulator för att simulera närvaron av ett externt minneskort (som ett SD-kort).
    • Den viktigaste av dem är mobil enhet emulator , dock innehåller SDK även andra verktyg för felsökning, paketering och installation av dina applikationer på emulatorn.

    Android virtuell enhet

    Android virtuell enhet (Android virtuell enhet) är en emulator som körs på vanlig dator. Emulatorn används för att designa, felsöka och testa applikationer i en verklig runtime-miljö.

    Innan du kan köra en Android-enhetsemulator måste du skapa Android virtuell enhet (AVD) . AVD Definierar systembilden och enhetsinställningarna som används av emulatorn.

    Det finns två sätt att skapa en enhetsemulator:

    1. På kommandoraden med hjälp av Android-verktyget, tillgängligt i katalogen där du installerade Android SDK, i verktygsmappen.
    2. Visuellt använder Android SDK och AVD Manager i IDE Eclipse genom att välja menyalternativet Fönster | Android SDK och AVD Manager. Fönstret Android SDK och AVD Manager visas, med vilket du kan skapa och konfigurera emulatorer för mobila enheter, samt ladda ner Android SDK-uppdateringar.

    Fönstret Android SDK och AVD Manager kommer också att visas om du anropar android.exe utan parametrar på kommandoraden.

    iAndroid SDK och AVD Manager

    Android SDK och AVD Manager-fönster

    På höger sida av panelen Lista över befintliga virtuella Android-enheter klickar du på knappen Ny, som öppnar fönstret Skapa ny AVD.

    I det här fönstret ställer du in önskad konfiguration för enhetsemulatorn som skapas:

    • namn- namnet på enheten som skapas;
    • Mål- Android SDK-version som stöds av enheten. Enheten har bakåtkompatibel med äldre SDK-versioner, d.v.s. om Android 2.0 väljs, kommer emulatorn att stödja SDK-versionerna 1.6, 1.5, 1.1;
    • SD-kort- installerar ett virtuellt SD-kort;
    • Hud-enhets skärmtyp. Den nedladdningsbara plattformen innehåller ett antal emulatorskinn som kan användas för att simulera appens prestanda på enheter med olika skärmstorlekar och upplösningar. En uppsättning skal för emulatorn, beroende på den installerade SDK-versionen som anges i fältet Mål, innehåller Olika typer och skärmstorlekar, till exempel:
    • HVGA(Halvstorlek VGA Video Graphics Array), storlek 320x480, medium densitet, normal skärm;
    • WVGA800 (Bred videografikuppsättning), storlek 480x800, hög densitet, normal skärm;
    • WVGA854 (Bred videografikuppsättning), 480x854, hög densitet, normal skärm;
    • QVGA (Quarter Video Graphics Array), storlek 240x320, låg densitet, liten skärm;
    • WQVGA (Wide Quarter Video Graphics Array), storlek 240x400, låg densitet, normal skärm;

    • Hårdvara- imitation av utrustning installerad på enheten. Om det behövs, genom att klicka på knappen Ny, kan du öppna ett fönster för att lägga till ytterligare virtuell utrustning.

    Fönster för att lägga till ytterligare virtuell hårdvara

    Efter att ha ställt in konfigurationen och klickat på knappen Skapa AVD kommer chefen att skapa en ny virtuell enhet, vars namn och API-version kommer att visas i listan Lista över befintliga virtuella Android-enheter.

    För mer finjustering är det bättre att använda kommandoradsverktyget andnoid.exe. Den har fler funktioner än Map9ers visuella AVD och är bekväm för att konfigurera nätverket, portarna och den virtuella hårdvaran för emulatorn. Tyvärr, på grund av bokens begränsade utrymme, är det inte möjligt att överväga detta verktyg mer i detalj.

    Beroende på stöds API-versioner Utseendet på den virtuella enheten kommer att vara annorlunda.

    Emulatorfönstret är utformat i form av en telefon med ett extra tangentbord. När systemet har startats visas det Hemskärm - Android skrivbord. För att komma åt den, använd knappen med husikonen. Emulatorn imiterar även pekskärmen på en riktig mobil enhet – i emulatorn trycker du på vänster musknapp på skärmen.

    Emulatorn har två virtuella skrivbord, som kan navigeras med hjälp av pilknapparna på navigeringsfält enhet eller genom att flytta markören samtidigt som du håller ned vänster musknapp (på en riktig enhet genom att flytta fingret över skärmen). Förutom programgenvägar kan du placera widgets på skrivbordet.

    Utseende av AVD version 1.5

    Utseende av AVD version 2.0

    För att testa utseendet på applikationen som skapas på olika skärmpositioner med hjälp av en tangentkombination +Du kan ändra skärmlayouten från vertikal till horisontell och vice versa.

    Baren längst upp på skärmen är Statusfältet. Den innehåller systemmeddelandeikoner: stationssignalstyrka mobil kommunikation, batteriladdning och aktuell tid. Panel Statusfältet är också utformad för att visa (i form av ikoner som visas på vänster sida av panelen) användaraviseringar för missade samtal, olästa text- och multimediameddelanden, mottagen e-post och systemaviseringar från tjänster som körs i bakgrunden. Om i Statusfältet välj aviseringsikonen och dra ned markören som visas, en utökad meddelandepanel öppnas med mer detaljerad information och en knapp för att stänga aviseringen.

    Markören längst ner på skärmen låter dig öppna ett fönster för att starta program installerade på systemet - Programstartare. Fönstret förlängs när du klickar på markören.

    Emulatorn stöder dock inte vissa funktioner som är tillgängliga på riktiga enheter:

    • inkommande och utgående meddelanden. Du kan dock simulera telefonsamtal via emulatorgränssnittet;

    Startplatta installerade applikationerProgramstartare

    • USB-anslutning;
    • videokamera (dock finns det en videokamerasimulator);
    • ansluta hörlurar;
    • bestämning av anslutningsstatus;
    • bestämma batteriladdningsnivån; D upptäckt av isättning eller borttagning av SD-kort;
    • Bluetooth-anslutning.

    Säkert, riktiga telefoner något annorlunda än emulatorn, men generellt AVD designad mycket hög kvalitet och nära den verkliga enhetens funktionalitet.

    Mer information om hur API-nivåer fungerar finns i Vad är API-nivå?

    Appkomponenter

    Isolerade tjänster

    Appstacknavigering

    Android 4.1 gör det mycket lättare att implementera rätt designmönster för Up-navigering. Allt du behöver göra är att lägga till android:parentActivityName till varje element i din manifestfil. Systemet använder denna information för att öppna lämplig aktivitet när användaren trycker på Upp-knappen i åtgärdsfältet (samtidigt som den pågående aktiviteten avslutas). Så om du deklarerar android:parentActivityName för varje aktivitet behöver du inte metoden onOptionsItemSelected() för att hantera klickhändelser på åtgärdsfältets appikon – systemet hanterar nu den händelsen och återupptar eller skapar lämplig aktivitet.

    Detta är särskilt kraftfullt för scenarier där användaren går in i en av din apps aktiviteter genom en "djupdykning" avsikt, till exempel från en avisering eller en avsikt från en annan app (som beskrivs i designguiden för att navigera mellan appar). användaren anger din aktivitet på det här sättet, din app kanske inte har en backstack med aktiviteter som kan återupptas när användaren navigerar uppåt. Men när du anger attributet android:parentActivityName för dina aktiviteter känner systemet av om din. appen innehåller redan en backstack med föräldraaktiviteter och, om inte, konstruerar en syntetisk backstack som innehåller alla föräldraaktiviteter.

    Notera: När användaren anger en djup aktivitet i din app och den skapar en ny uppgift för din app, infogar systemet faktiskt stapeln med föräldraaktiviteter i uppgiften. Som sådan, genom att trycka på Tillbaka-knappen navigerar du också tillbaka genom stapeln av föräldraaktiviteter.

    När systemet skapar en syntetisk backstack för din app, bygger det en grundläggande avsikt att skapa en ny instans av varje överordnad aktivitet. Så det finns inget sparat tillstånd för överordnade aktiviteter på det sätt som du hade förväntat dig om användaren naturligt navigerade genom varje aktivitet. Om någon av de överordnade aktiviteterna normalt visar ett användargränssnitt som är beroende av användarens sammanhang, kommer den sammanhangsinformationen att saknas och du bör leverera den när användaren navigerar tillbaka genom stacken. Om användaren till exempel tittar på ett album i en musikapp kan navigering uppåt leda till en aktivitet som listar alla album i en vald musikgenre. I det här fallet, om stacken måste skapas, är det nödvändigt att du informerar föräldraaktiviteten vilken genre det aktuella albumet tillhör så att föräldern kan visa den korrekta listan som om användaren faktiskt kom från den aktiviteten. För att leverera en sådan information till en syntetisk överordnad aktivitet, måste du åsidosätta metoden. Detta ger dig ett TaskStackBuilder-objekt som systemet skapade för att syntetisera de överordnade aktiviteterna. ) , kan du ändra lämplig avsikt för att lägga till extra data som den överordnade aktiviteten kan använda för att bestämma lämplig kontext och visa lämpligt användargränssnitt.

    Om din appstruktur är mer komplex finns det flera andra API:er tillgängliga som låter dig hantera beteendet hos Up-navigering och helt anpassa den syntetiska backstacken. Några av API:erna som ger dig ytterligare kontroll inkluderar:

    onNavigateUp() Åsidosätt detta för att utföra en anpassad åtgärd när användaren trycker på Upp-knappen. navigateUpTo(Intent) Anrop detta för att avsluta den aktuella aktiviteten och gå till aktiviteten som anges av den medföljande avsikten . Om aktiviteten finns i den bakre stapeln, men inte är den närmaste föräldern, avslutas också alla andra aktiviteter mellan den aktuella aktiviteten och aktiviteten som anges med avsikten. getParentActivityIntent() Anrop detta för att få den avsikt som kommer att starta den logiska föräldern för den aktuella aktiviteten. shouldUpRecreateTask(Intent) Anrop detta för att fråga om en syntetisk backstack måste skapas för att navigera upp. Returnerar sant om en syntetisk stack måste skapas, false om lämplig stack redan finns. finishAffinity() Anropa detta för att avsluta den aktuella aktiviteten och alla överordnade aktiviteter med samma uppgiftsaffinitet som är kopplade till den aktuella aktiviteten. Om du åsidosätter standardbeteenden som onNavigateUp() , bör du anropa den här metoden när du skapar en syntetisk backstack vid Up-navigering. onCreateNavigateUpTaskStack Åsidosätt detta om du helt behöver kontrollera hur den syntetiska uppgiftsstacken skapas. Om du helt enkelt vill lägga till lite extra data till avsikterna för din backstack, bör du istället åsidosätta onPrepareNavigateUpTaskStack()

    De flesta appar behöver dock inte använda dessa API:er eller implementera onPrepareNavigateUpTaskStack() , utan kan uppnå rätt beteende helt enkelt genom att lägga till android:parentActivityName till varje element.

    Multimedia

    Mediekoder

    Du kan hantera krypterad mediadata i codecs genom att ringa queueSecureInputBuffer() i kombination med MediaCrypto API:er, istället för den vanliga queueInputBuffer() .

    För mer information om hur man använder codecs, se MediaCodec-dokumentationen.

    Spela in ljud på kö

    Ljudeffekter

    Notera: Det är inte garanterat att alla enheter stöder dessa effekter, så du bör alltid först kontrollera tillgängligheten genom att ringa isAvailable() på motsvarande ljudeffektklass.

    Uppspelning utan luckor

    Du kan nu utföra gapfri uppspelning mellan två separata MediaPlayer-objekt. När som helst innan din första MediaPlayer är klar kan du anropa setNextMediaPlayer() och Android försöker starta den andra spelaren i samma ögonblick som den första stannar.

    Mediarouter. De nya API:erna MediaRouter, MediaRouteActionProvider och MediaRouteButton tillhandahåller standardmekanismer och användargränssnitt för att välja var media ska spelas upp.

    Kamera

    Autofokusrörelse

    Anslutningsmöjligheter

    Android Beam

    Android Beam™ stöder nu stora nyttolastöverföringar via Bluetooth. När du definierar vilken data som ska överföras med antingen Den nya setBeamPushUris()-metoden eller det nya callback-gränssnittet NfcAdapter.CreateBeamUrisCallback , Android lämnar över dataöverföringen till Bluetooth eller annan alternativ transport för att uppnå snabbare överföringshastigheter. Detta är särskilt användbart för stora nyttolaster som bild- och ljudfiler och kräver ingen synlig parning mellan enheterna. Inget extra arbete krävs av din app för att dra fördel av överföringar via Bluetooth.

    När du använder återuppringningsgränssnittet anropar systemet gränssnittets createBeamUris()-metod när användaren kör en delning med Android Beam så att du kan definiera de URI:er som ska delas vid delningstillfället. Detta är användbart om URI:erna som ska delas kan variera beroende på användarkontexten inom aktiviteten, medan anropet av setBeamPushUris() är användbart när URI:erna som ska delas är oförändrade och du säkert kan definiera dem i förväg.

    Upptäckt av nätverkstjänster

    Android 4.1 lägger till stöd för multicast DNS-baserad tjänstupptäckt, vilket gör att du kan hitta och ansluta till tjänster som erbjuds av peer-enheter via Wi-Fi, såsom mobila enheter, skrivare, kameror, mediaspelare och andra som är registrerade på den lokala nätverk.

    Innan du kan börja upptäcka tjänster på lokala enheter måste du också anropa addServiceRequest() . När WifiP2pManager.ActionListener som du skickar till den här metoden får ett framgångsrikt återuppringning, kan du sedan börja upptäcka tjänster på lokala enheter genom att anropa discoverServices() .

    När lokala tjänster upptäcks kommer du att få ett återuppringning till antingen WifiP2pManager.DnsSdServiceResponseListener eller WifiP2pManager.UpnpServiceResponseListener , beroende på om du registrerade dig för att använda Bonjour eller Upnp. Återuppringningen som tas emot i båda fallen innehåller ett WifiP2pDevice-objekt som representerar Pevice-objektet.

    Nätverksanvändning

    Tillgänglighetstjänster kan också utföra åtgärder på uppdrag av användaren, inklusive att klicka, rulla och stega igenom text med performAction och setMovementGranularities. Metoden performGlobalAction() tillåter även tjänster att utföra åtgärder som Tillbaka, Hem och öppna Senaste appar och aviseringar.

    Anpassningsbar appnavigering

    När du bygger en Android-app kan du nu anpassa navigeringsscheman genom att hitta fokuserbara element och inmatningswidgets med findFocus() och focusSearch() , och ställa in fokus med setAccessibilityFocused() .

    Mer tillgängliga widgets

    Den nya klassen android.view.accessibility.AccessibilityNodeProvider låter dig visa komplexa anpassade vyer till tillgänglighetstjänster så att de kan presentera informationen på ett mer tillgängligt sätt. Med android.view.accessibility.AccessibilityNodeProvider kan en användarwidget med avancerat innehåll, till exempel ett kalenderrutnät, presentera en logisk semantisk struktur för tillgänglighetstjänster som är helt skild från widgetens layoutstruktur. Denna semantiska struktur tillåter tillgänglighetstjänster att presentera en mer användbar interaktionsmodell för användare som är synskadade.

    Kopiera och klistra

    Kopiera och klistra in med avsikter

    Renderscript

    Renderscript-beräkningsfunktionaliteten har förbättrats med följande funktioner:

    • Stöd för flera kärnor inom ett skript.
    • Stöd för läsning från allokering med filtrerade samplers från compute i ett nytt skript API rsSample.
    • Stöd för olika nivåer av FP-precision i #pragma .
    • Stöd för att söka efter ytterligare information från RS-objekt från ett beräkningsskript.
    • Många prestandaförbättringar.

    Nya pragmor finns också tillgängliga för att definiera den flyttalsprecision som krävs av dina beräkningsrenderingsskript. Detta låter dig aktivera NEON-liknande operationer som snabba vektormatematiska operationer på CPU-vägen som annars inte skulle vara möjliga med full IEEE 754-2008-standard.

    Notera: Den experimentella Renderscript-grafikmotorn är nu utfasad.

    Animation

    Aktivitetsstartsanimationer

    Avlägsna vyer

    • "sans-serif" för vanliga Roboto
    • "sans-serif-light" för Roboto Light
    • "sans-serif-condensed" för Roboto Condensed

    Vibrera för ingångskontroller

    Om anslutna indataenheter har sina egna vibrationsfunktioner kan du nu styra vibrationerna för dessa enheter med hjälp av befintliga Vibrator API:er helt enkelt genom att anropa getVibrator() på InputDevice .

    Behörigheter

    ...

    Den här funktionen definierar "tv" som en typisk TV-upplevelse i vardagsrummet: visas på en stor skärm, där användaren sitter långt borta och den dominerande formen av inmatning är något som en d-pad, och i allmänhet inte genom beröring eller en mus/pekare.





    

    2024 gtavrl.ru.