I am using reflection to called a method in my NumberPicker, here is my code:
try {
// reflection call for
method = numberPicker.getClass().getDeclaredMethod("changeValueByOne", boolean.class);
method.setAccessible(true);
method.invoke(numberPicker, increment);
//TODO: Before finalizing should there be back-up code in one of these cases?
} catch (final NoSuchMethodException e) {
e.printStackTrace();
} catch (final IllegalArgumentException e) {
e.printStackTrace();
} catch (final IllegalAccessException e) {
e.printStackTrace();
} catch (final InvocationTargetException e) {
e.printStackTrace();
}
In case the changeValueByOne method does not exist in the NumberPicker (I'm under the impression it doesn't exist in older APIs) can I put some code like numberPicker.setValue(numberPicker.getValue() - 1); and remove the e.printStackTrace(); from the NoSuchMethodException catch block to make it handle this gracefully?
In other words, instead of using the changeValueByOne method if it doesn't exist it will default to the setValue. I'd rather use changeValueByOne if it is available because it plays the rotation animation of the NumberPicker where I don't believe setValue does.
Here is my AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.skytbest.intervaltrainer.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
and my build.gradle
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard- rules.txt'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
NumberPicker requires an API >=11 and your minimum required is greater than that. Therefore, you don't get a compile error for NumberPicker because devices with API < 11 can't install it. So you shouldn't need to worry.
If you wanted to change that minimum API then you would do something like
if (android.os.Build.VERSION.SDK_INT<= android.os.Build.VERSION_CODES.HONEYCOMB)
{
// use this method
}
else
{
// use this method
}
Related
I'm developing an android application where I'm using a JsonObjectRequest and Android's Volley.
My app seems to runs perfectly fine on Android's Pixel XL API 30(printing out the desired output), but doesn't work with Android's Pixel 2 API 29, even though I've defined minSdkVersion 16 in build.gradle
This is my build.gradle:
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.krish.parsedata"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.android.volley:volley:1.2.0'
}
This is my MainActivity.java:
public class MainActivity extends AppCompatActivity {
RequestQueue queue;
String url = "https://www.google.com";
String apiUrl = "https://jsonplaceholder.typicode.com/todos";
String getApiUrl = "https://jsonplaceholder.typicode.com/todos/1";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
queue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,
getApiUrl, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("url", "onCreate: " + response.getString("title"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("url2", "There was an error");
}
});
queue.add(jsonObjectRequest);
}
}
Thank you!
Update: This keeps on showing up:
Android Studio is using the following JDK location when running Gradle:
/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home
Using different JDK locations on different processes might cause Gradle to
spawn multiple daemons, for example, by executing Gradle tasks from a terminal
while using Android Studio.
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.krish.parsedata">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.ParseData">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
UPDATE: It works on all API 30 level devices, but not on anything lower, I've tryed changing min sdk version, complie sdk version, and build sdk version, no luck. Not sure what to do. Help would be appreciated a lot. Thank you.
I have found out the error. The problem had nothing to do with my code or build configuration, it was the emulator itself. I deleted/re-installed the emulator, and things are working normal.
Hope this helps anyone struggling with the same problem.
The application runs but when i try to use the camera only a disturbed grey screen appears and the logs tab gives me two errors:
E/libc: Access denied finding property "vendor.camera.aux.packagelist"
Access denied finding property "vendor.camera.aux.packagelist2"
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
build.gradle (Module:app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 22
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
}
build.gradle(Project:camera)
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
First, check your Android version. If it is running on Android 6.0 and higher (API level 23+), then you need to :
Declare a permission in the app manifest. Make sure to insert the permission above the application tag.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<application ...>
...
</application>
Then, request that the user approve each permission at runtime
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA},
50); }
I had this in my android manifest that prevented the app from using the camera.
android:hardwareAccelerated="false"
Removing it helped me.
Firstly, to check if it is a permission problem, go to the application manager of your phone, find your programme's name, and check the permission list. See if it is allowed to use the camera.
Secondly, open the XML of the layout where your "SurfaceView" resides, check if the "SurfaceView" node has the property "android:background". You must remove it if it is there. No idea why this is never mentioned.
<SurfaceView
android:layout_width="0dp"
android:layout_height="300dp" android:id="#+id/cameraPreview"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" android:background="#3F51B5"/>
Pay attention to the "android:background" in the above snippet. Remove it if you see it.
Thirdly, make sure you start the camera in the "surfaceCreated" event handler rather than anywhere else. You can't directly start the camera in "onViewCreated"!
Sample code just in case:
public void onViewCreated(#NonNull final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final CameraSource cameraSource = new CameraSource.Builder(getContext(), barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setRequestedFps(10)
.setAutoFocusEnabled(true).build();
((SurfaceView) view.findViewById(R.id.cameraPreview)).getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, 1);
}
try {
cameraSource.start(holder);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
}
Reason: FileNotFoundException open failed: XXXXXXX EPERM (Operation not permitted)
Adding all the permissions still reports an error, mainly because the permissions requirements of the Android system are very strict.
It is recommended to change to:
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
File file = new File(directory, "something" + ".MP3");
public static String DIRECTORY_MUSIC = "Music";
public static String DIRECTORY_ALARMS = "Alarms";
public static String DIRECTORY_NOTIFICATIONS = "Notifications";
public static String DIRECTORY_PICTURES = "Pictures";
public static String DIRECTORY_MOVIES = "Movies";
public static String DIRECTORY_DOWNLOADS = "Download";
public static String DIRECTORY_DCIM = "DCIM";
public static String DIRECTORY_DOCUMENTS = "Documents";
If you are using a firebase plugin in your project, remove it. I was using the firebase crashlytics that camera prevents opening.
I am also seeing same error in my console when I am trying to open camera. However, it does not cause any other side effects.
I think it's best to ignore this error unless it stops app from running. or limits any functionality.
Found a post here that claims to resolve the issue by adding
<application>
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>
However, this did not work in my case. Testing on Mi Note 7
I too faced same error while implementing video capture option, this in my case due to missing Storage and Camera permissions.
Resolved using below code
if ((checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
Log.d(TAG, "No camera and storage permission");
requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_CODE);
}
In my case, you must be following an android jetpack for a camera course in here [https://developer.android.com/codelabs/camerax-getting-started#0][1]
After that, change the companion object like this.
companion object {
private const val TAG = "CameraXBasic"
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}
Don't forget to add permission to access storage in the manifest.xml
In my case, the cause of the problem is that the surfaceTexture is available before the ui is not ready. To solve it, i add some delay (i don't know whether it is the correct solution or not, but it's working).
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int arg1, int arg2) {
mSurfaceTexture = surfaceTexture;
try {
Thread.sleep(200); // add some delay
} catch (InterruptedException e) {
e.printStackTrace();
}
cameraHelper.openCamera(mSurfaceTexture);
}
Android Studio 2.3.3 (LATEST)
Cocos2d-x 3.15.1 (LATEST)
I tested on Debug.
It's my first experience with Cocos2d-x Game Engine, I developed an Android Game using Cocos2d-x, all it's fine but when I tried to show the achievements it shows me an error like this :
java.lang.NullPointerException
at sonar.systems.framework.SonarFrameworkFunctions.showAchievements(SonarFrameworkFunctions.java:432)
at org.cocos2dx.lib.Cocos2dxRenderer.nativeTouchesEnd(Native Method)
at org.cocos2dx.lib.Cocos2dxRenderer.handleActionUp(Cocos2dxRenderer.java:129)
at org.cocos2dx.lib.Cocos2dxGLSurfaceView$10.run(Cocos2dxGLSurfaceView.java:311)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1486)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1263)
My Code when I click to show the achievements :
SonarCocosHelper::GooglePlayServices::showAchievements();
When I want To sign In :
java.lang.NullPointerException
at sonar.systems.framework.SonarFrameworkFunctions.isSignedIn(SonarFrameworkFunctions.java:277)
at org.cocos2dx.lib.Cocos2dxRenderer.nativeRender(Native Method)
at org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame(Cocos2dxRenderer.java:105)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1557)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1263)
My Code for Sign In :
if(!SonarCocosHelper::GooglePlayServices::isSignedIn())
SonarCocosHelper::GooglePlayServices::signIn();
My Manifest File :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ilyo.test"
android:installLocation="auto">
<supports-screens android:anyDensity="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"/>
<uses-feature android:glEsVersion="0x00020000" />
<!-- Basic permission for Internet and don't allow turn of the screen -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:label="#string/app_name"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#mipmap/ic_launcher">
<!-- Tell Cocos2dxActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="MyGame" />
<!-- Required for Google Play Services -->
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="#string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<activity
android:name="org.cocos2dx.cpp.AppActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Build Gradle File :
Cocos Helper Frameworks Used :
My Google Play Achievement (I removed the ID from this photo):
I searched already for solutions in relationship with Android Studio but the results are very rare, I don't know what is the solution and what this the reason for this error.
Thank you,
I founded a solution but now I guess it's just a dirty fix, first the problem is in the GooglePlayServices.java and exactly in onStart method : Null pointer Exception because mHelper is Null.
#Override
public void onStart()
{
mHelper.onStart((Activity) ctx);
}
Let us a little further why it generates null, so :
1. SonarFrameworkFunctions.java
when we want to call GooglePlayServices constructor from SonarFrameworkFunctions.java :
//GOOGLE PLAY SERVICES
if (SonarFrameworkSettings.USE_GOOGLE_PLAY_GAME_SERVICES)
{
String packageName = "sonar.systems.frameworks.GooglePlayServices.GooglePlayServices";
googlePlayServices = (InstantiateFramework(packageName) != null) ? InstantiateFramework(packageName) : new Framework();
}
2. Method : InstantiateFramework in SonarFrameworkFunctions.java
public static Framework InstantiateFramework(String packageName)
{
Framework tmp = null;
try
{
tmp = (Framework) Class.forName(packageName).getConstructor().newInstance();
tmp.SetActivity(((SonarFrameworkActivity) app));
} catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
Log.e("Class not found", "class doesn't exist or bad package name " + packageName);
}
return tmp;
}
The constructor is empty so there is only a method called onCreate that instantiate and prepare the mHelper to access to all functionalities of Google Play Services.
Solution (Dirty Fix):
GooglePlayServices.java
public GooglePlayServices()
{
mHelper=getGameHelper();
mHelper.setup(this);
}
One of my application suddenly fails on startup, with the following error message :
java.lang.VerifyError: Rejecting class
com.sample.BufferManagerImpl because it failed
compile-time verification (declaration of
'com.sample.BufferManagerImpl' appears in
/data/app/com.sample.myapp-1/base.apk)
It only fails on devices using the ART virtual machine, but not on Dalvik
The issue is due to having a synchronized block inside a try-catch block, for example :
try {
synchronized (mLock) {
updateState();
}
} catch (IllegalStateException e) {
}
Apparently this is not a good practice, but as soon as I change it like this it works :
synchronized(mLock) {
try {
updateState();
} catch (IllegalStateException e) {
}
}
in android studio 2.1 ,the instant run will cause this problem,just run after close the instant run function.
File -> Preferences > Build Execution -> Deployment -> Instant Run
Disable the first checkbox:
Enable Instant Run to hot swap.....
If you are building with Jack, make sure it's turned off from build.gradle
defaultConfig {
...
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
jackOptions {
enabled false
}
}
This error also might happen due to usage of Mockito within an Android InstrumentationTest. If the error appears on mocking objects then you have to add this lines to you gradle-file:
androidTestCompile "com.crittercism.dexmaker:dexmaker:1.4"
androidTestCompile "com.crittercism.dexmaker:dexmaker-dx:1.4"
androidTestCompile "com.crittercism.dexmaker:dexmaker-mockito:1.4"
This works for me with Mockito 1.10.15 and 1.10.19.
i had this problem to with android 5. my app did correctly on 4 or below but on android 5 devices i had crash.
i broke my codes with multiple Threads and it fixed.
if your code wants to change the UI use handler .
Thread Thread = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
handler.post(new Runnable() {
#Override
public void run() {
use this if your codes will change the Ui
.
.
.
.
.
I want to set up a project in Android Studio. However, I don't want an Android App, just the test project.
Following the lastest release of UiAutomator, I was trying to set a class extending ActivityInstrumentationTestCase2 and start my tests from there.
However, I've stumbled in one thing: I can't figure out how to create the project without making it an app.
The options for creating a new project are:
Start a new Android Studio Project
Open existing projects
Import projects
I did:
Start a new project, give it a name, set minSDK and choose "No activity"
Open build.gradle (under app) and add the dependencies and instrumentation information mentioned in the end of Testing Support Library
Opened androidTest under src and changed the main file: changed to ActivityInstrumentationTestCase2, added setUp and tearDown; defined RunWith Junit4 (as indicated in Testing Support Library)
I build the project (build successful) - Press the green arrow next to build in the "action bar"
My problems are:
How do I install this in the device?
How do I run it in the device?
Do I need to do anything in the AndroidManifest?
Am I editing in the right place? Should I do anything under src/main?
I'd appreciate that the install and run instructions would be both for how to do it through Android Studio and using the command line (if you only know one of them post it anyway please).
Note: this is the first time I'm using Android Studio
Thanks in advance.
EDIT:
Right now I can build and run but it tells me I have no tests to run (empty test suite). Here are my graddle and my code.
My build.graddle is as follows:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "androidexp.com.ceninhas"
minSdkVersion 21
targetSdkVersion 22
versionCode 1
versionName "1.0"
testInstrumentationRunner="android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'LICENSE.txt'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.0.0'
}
My source code (under src/androidTest/java/package) is:
#RunWith(AndroidJUnit4.class)
public class ApplicationTest extends ActivityInstrumentationTestCase2<Activity> {
public final static String ACTIVITY_NAME = "com.calculator.Main";
public final static Class<?> autActivityClass;
static {
try {
autActivityClass = Class.forName(ACTIVITY_NAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public ApplicationTest(){
super((Class<Activity>)autActivityClass);
}
#Before
public void setUp() throws Exception{
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
}
#After
public void tearDown() throws Exception{
super.tearDown();
}
#Test
public void cenas(){
assertTrue(true);
}
}
The run log on the console was:
Testing started at 18:06 ...
Waiting for device.
Target device: lge-nexus_5-08e506c10ddef123
Uploading file
local path: C:\Users\Ines\workspace\Ceninhas\app\build\outputs\apk\app-debug.apk
remote path: /data/local/tmp/androidexp.com.ceninhas
No apk changes detected. Skipping file upload, force stopping package instead.
DEVICE SHELL COMMAND: am force-stop androidexp.com.ceninhas
Uploading file
local path: C:\Users\Ines\workspace\Ceninhas\app\build\outputs\apk\app-debug-androidTest-unaligned.apk
remote path: /data/local/tmp/androidexp.com.ceninhas.test
No apk changes detected. Skipping file upload, force stopping package instead.
DEVICE SHELL COMMAND: am force-stop androidexp.com.ceninhas.test
Running tests
Test running startedFinish
Empty test suite.
What am I doing wrong?
I am also using uiautomator 2.0 from AndroidStudio. Here are some answers to your questions.
How do I install this in the device?
How do I run it in the device?
Make sure your device is connected using
adb devices
if not, you must connect it using
adb kill-server
adb connect xxx.xxx.xxx.xxx
Then from AndroidStudio, right click on your test class and click on "Run YourTestCase".
Do I need to do anything in the AndroidManifest?
I have nothing special in my manifest, but be sure you add
android {
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
in your build.gradle
Am I editing in the right place? Should I do anything under src/main?
Yes, you are editing at the right place. But you can move your code to src/main. To do so, you will need to change androidTestCompile to compile in your build.gradle file.
I did not try to run test from command line yet, but you can see AndroidStudio commands, maybe it can help.
I hope it helped you.
EDIT 1
I use this code
build.gradle (projectRoot)
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.0"
lintOptions {
abortOnError false
}
packagingOptions {
exclude 'NOTICE'
exclude 'LICENSE.txt'
}
defaultConfig {
minSdkVersion 19
targetSdkVersion 22
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'com.android.support.test:testing-support-lib:0.1'
compile 'com.android.support.test.uiautomator:uiautomator-v18:2.0.0'
compile project(':aiccore')
}
LoginTestCase (projectRoot/src/main/LoginTestCase.java)
public class LoginTestCase extends InstrumentationTestCase {
protected UiDevice device = null;
protected String appName;
public LoginTestCase() {
this("YourAppName")
}
public LoginTestCase(String appName) {
this.appName = appName;
}
public void runApp(String appName) throws UiObjectNotFoundException, RemoteException {
device = UiDevice.getInstance(getInstrumentation());
device.pressHome();
device.waitForWindowUpdate("", 2000);
UiObject2 allAppsButton = device.findObject(By.desc("Apps"));
allAppsButton.click();
device.waitForWindowUpdate("", 2000);
UiScrollable appViews = new UiScrollable(new UiSelector().scrollable(true));
appViews.setAsHorizontalList();
UiObject settingsApp = appViews.getChildByText(new UiSelector().className(TextView.class.getName()), appName);
settingsApp.clickAndWaitForNewWindow();
assertTrue("Unable to detect app", settingsApp != null);
}
#Override
public void setUp() throws RemoteException, UiObjectNotFoundException {
this.runApp(appName);
}
#Override
public void tearDown() throws RemoteException, UiObjectNotFoundException {
//Empty for the moment
}
public void testUS1() {
UiObject2 usernameLabel = device.findObject(By.clazz(TextView.class.getName()).text("Username"));
assertTrue("Username label not found", usernameLabel != null);
}
Well, actually, you should not write test code that way. Just keep your code under the src/androidTest folder, and write test code like this:
#RunWith(AndroidJUnit4.class)
#SdkSuppress(minSdkVersion = 18)
public class ChangeTextBehaviorTest {
private static final String BASIC_SAMPLE_PACKAGE
= "com.example.android.testing.uiautomator.BasicSample";
private static final int LAUNCH_TIMEOUT = 5000;
private static final String STRING_TO_BE_TYPED = "UiAutomator";
private UiDevice mDevice;
#Before
public void startMainActivityFromHomeScreen() {
// Initialize UiDevice instance
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
// Start from the home screen
mDevice.pressHome();
// Wait for launcher
final String launcherPackage = mDevice.getLauncherPackageName();
assertThat(launcherPackage, notNullValue());
mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)),
LAUNCH_TIMEOUT);
// Launch the app
Context context = InstrumentationRegistry.getContext();
final Intent intent = context.getPackageManager()
.getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
// Clear out any previous instances
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
// Wait for the app to appear
mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
LAUNCH_TIMEOUT);
}
#Test
public void checkPreconditions() {
assertThat(mDevice, notNullValue());
}
#Test
public void testChangeText_sameActivity() {
// Type text and then press the button.
mDevice.findObject(By.res(BASIC_SAMPLE_PACKAGE, "editTextUserInput"))
.setText(STRING_TO_BE_TYPED);
mDevice.findObject(By.res(BASIC_SAMPLE_PACKAGE, "changeTextBt"))
.click();
// Verify the test is displayed in the Ui
UiObject2 changedText = mDevice
.wait(Until.findObject(By.res(BASIC_SAMPLE_PACKAGE, "textToBeChanged")),
500 /* wait 500ms */);
assertThat(changedText.getText(), is(equalTo(STRING_TO_BE_TYPED)));
}
}
For detail please look out: UIAutomator Test sample