问题
My initial issue is being able to click a "PASTE" bubble that pops up when the a click is being held on a text field. Currently I have not found a way to get that action to happen using uiautomator script/code. So I started looking at directly accessing the clipboard. Now I am having issues accessing the clipboard on the android device. We are not using an app (apk), but are pushing a jar to the device and then using adb runtest to run the classes. So no activities are being started. I am guessing that is were all my issues are coming from. I have created a class file that I call trying to access the clipboard. But am currently getting this error message "java.lang.IllegalStateException: System services not available to Activities before onCreate()". I am new to android and uiautomator. Where/how do I add onCreate() to this code. I know the process we are using is odd at best. Any help at either getting the "PASTE" bubble clicked using uiautomator or getting the class to work would be appreciated. I tried the onCreate() in a few areas, as you can see, but no luck so far.
Here is my class so far:
import android.app.Activity;
import android.content.*;
import android.os.AsyncTask;
public class MyClipBoard extends Activity {
public String clip;
MyClipBoard() {
super.onCreate(null);
}
public void getClipBoard(){
new GetClipBoard().execute();
}
private class GetClipBoard extends AsyncTask<Void, Void, String> {
private String pMyClip;
@Override
protected String doInBackground(Void...params) {
try {
onCreate(null);
// ClipboardManager p = params[0];
String pasteData = "";
ClipboardManager myClipBoard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData.Item myClip = myClipBoard.getPrimaryClip().getItemAt(0);
CreateDeviceInfoFile.createInfoFile("Data from ClipBoard:", myClip.toString());
CreateDeviceInfoFile.createInfoFile("Number of Items:", String.valueOf(myClipBoard.getPrimaryClip().getItemCount()));
pMyClip = myClip.toString();
}catch (Exception e){
CreateDeviceInfoFile.createInfoFile("ERROR",e.toString());
}
// Gets the clipboard as text.
return pMyClip;
}
@Override
protected void onPostExecute(String result) {
clip = result;
CreateDeviceInfoFile.createInfoFile("Data from PostExecute:", result);
}
}
}
---------Edited added class-------------------
public class MiApp extends Application {
public MiClipBoard newBoard;
private static Context appContext;
MiApp(){
this.onCreate();
Looper.prepare();
newBoard = new MiClipBoard();
}
public MiClipBoard appClipBoard(){
return newBoard;
}
@Override
public void onCreate(){
super.onCreate();
}
public static Context getContext(){
return appContext.getApplicationContext();
}
}
public class MiClipBoard extends Activity {
private ClipboardManager clipboard;
MiClipBoard(){
Context context = MiApp.getContext();
clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
}
public void writeToClipBoard(String clipText){
try {
ClipData clip = ClipData.newPlainText("simple text", "Hello, World!");
clipboard.setPrimaryClip(clip);
CreateDeviceInfoFile.createInfoFile("Writing to ClipBoard", "Hello World");
} catch (Exception e){
CreateDeviceInfoFile.createInfoFile("Write Error", e.toString());
}
}
public void readClipBoard(){
String pasteData = "";
try {
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
pasteData = item.getText().toString();
CreateDeviceInfoFile.createInfoFile("From ClipBoard", pasteData);
} catch (Exception e){
CreateDeviceInfoFile.createInfoFile("Read Error", e.toString());
}
}
}
回答1:
Android system only allow us to activate one Activity
at a time, and the others are in onPause()
state. Starting an activity should have a layout.xml
, and must call startActivity(Intent)
.
From the logcat:
"java.lang.IllegalStateException: System services not available to Activities before onCreate()".
We can know that getSystemService()
only available after super.onCreate(Bundle)
, which triggers the activity to be created.
A good practice to call getSystemService()
in non-activity class is by passing Context
parameter to GetClipBoard
's constructor and make it as public
:
public class GetClipBoard extends AsyncTask<Void, Void, String> {
private Context context;
public GetClipBoard(Context context){
this.context = context;
}
private String pMyClip;
@Override
protected String doInBackground(Void...params) {
try {
// ClipboardManager p = params[0];
String pasteData = "";
ClipboardManager myClipBoard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
...
}catch (Exception e){
...
}
// Gets the clipboard as text.
return pMyClip;
}
...
}
So once you executing AsyncTask
, call the class from Android components that has Context
, e.g. Activity
, Service
, BroadcastReceiver
, etc.
new GetClipBoard(this).execute(); // 'this' > context
回答2:
I believe that is my issue, currently I don't think I have a component that has Context. This is the class I am making the call from (part of it) and the first class that is being called by adb runtest.
public class SetupApp extends UiAutomatorTestCase {
public void testAppSetup() throws UiObjectNotFoundException, RemoteException
{
//other code here
MyClipBoard myBoard = new MyClipBoard();
myBoard.getClipBoard();
来源:https://stackoverflow.com/questions/33160517/how-to-access-the-clipboard-on-android-device