i don't know what i did

This commit is contained in:
hyb1996 2017-09-22 16:12:07 +08:00
parent 23cd6ba6cd
commit 601019cab2
26 changed files with 2354 additions and 13 deletions

View File

@ -9,8 +9,8 @@ android {
applicationId "com.stardust.scriptdroid"
minSdkVersion 17
targetSdkVersion 23
versionCode 200
versionName "3.0.0 Alpha1"
versionCode 201
versionName "3.0.0 Alpha2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
@ -132,6 +132,8 @@ dependencies {
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//Picasso
compile 'com.squareup.picasso:picasso:2.5.2'
// Tasker Plugin
compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:[4.0.2, 5.0['
compile 'com.flurry.android:analytics:7.0.0@aar'

View File

@ -82,6 +82,7 @@
<activity android:name=".ui.help.LocalWebViewActivity"/>
<activity android:name=".external.tasker.TaskerScriptEditActivity_"/>
<activity android:name=".ui.edit.ViewSampleActivity"/>
<activity android:name=".ui.login.LoginActivity_"/>
<activity android:name=".external.widget.ScriptWidgetSettingsActivity_">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>

View File

@ -0,0 +1,41 @@
package com.stardust.scriptdroid.network;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.stardust.scriptdroid.network.util.WebkitCookieManagerProxy;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Stardust on 2017/9/20.
*/
public class NodeBB {
private static final NodeBB sInstance = new NodeBB();
private Retrofit mRetrofit;
NodeBB() {
mRetrofit = new Retrofit.Builder()
.baseUrl("http://www.autojs.org/")
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder()
.setLenient()
.create()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(new OkHttpClient.Builder()
.cookieJar(new WebkitCookieManagerProxy())
.build())
.build();
}
public static NodeBB getInstance() {
return sInstance;
}
public Retrofit getRetrofit() {
return mRetrofit;
}
}

View File

@ -0,0 +1,47 @@
package com.stardust.scriptdroid.network;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.TokenResponse;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Stardust on 2017/9/20.
*/
public class UserService {
private static final UserService sInstance = new UserService();
private final Retrofit mRetrofit;
UserService() {
mRetrofit = NodeBB.getInstance().getRetrofit();
}
public Observable<TokenResponse> login(String userName, final String password) {
final UserApi userApi = mRetrofit.create(UserApi.class);
return userApi.verify(userName, password)
.subscribeOn(Schedulers.io())
.flatMap(new Function<VerifyResponse, ObservableSource<TokenResponse>>() {
@Override
public ObservableSource<TokenResponse> apply(@NonNull VerifyResponse verifyResponse) throws Exception {
if (verifyResponse.isSuccessful()) {
return userApi.generateToken(verifyResponse.getUid(), password);
} else {
return Observable.error(new Exception(verifyResponse.getMessage()));
}
}
});
}
}

View File

@ -0,0 +1,34 @@
package com.stardust.scriptdroid.network.api;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import com.stardust.scriptdroid.network.entity.TokenResponse;
import com.stardust.scriptdroid.network.entity.User;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
/**
* Created by Stardust on 2017/9/20.
*/
public interface UserApi {
@GET("/api/me")
Observable<User> me();
@FormUrlEncoded
@POST("/api/ns/login")
Observable<VerifyResponse> verify(@Field("username") String userName, @Field("password") String password);
@FormUrlEncoded
@POST("/api/v2/{uid}/tokens")
Observable<TokenResponse> generateToken(@Path("uid") String uid, @Field("password") String password);
}

View File

@ -0,0 +1,253 @@
package com.stardust.scriptdroid.network.entity;
import com.google.gson.annotations.SerializedName;
public class GroupsItem{
@SerializedName("createtimeISO")
private String createtimeISO;
@SerializedName("createtime")
private String createtime;
@SerializedName("private")
private boolean jsonMemberPrivate;
@SerializedName("hidden")
private boolean hidden;
@SerializedName("userTitleEnabled")
private boolean userTitleEnabled;
@SerializedName("displayName")
private String displayName;
@SerializedName("memberCount")
private String memberCount;
@SerializedName("icon")
private String icon;
@SerializedName("description")
private String description;
@SerializedName("labelColor")
private String labelColor;
@SerializedName("userTitle")
private String userTitle;
@SerializedName("deleted")
private String deleted;
@SerializedName("system")
private boolean system;
@SerializedName("cover:position")
private String coverPosition;
@SerializedName("name")
private String name;
@SerializedName("cover:url")
private String coverUrl;
@SerializedName("cover:thumb:url")
private String coverThumbUrl;
@SerializedName("disableJoinRequests")
private boolean disableJoinRequests;
@SerializedName("slug")
private String slug;
@SerializedName("nameEncoded")
private String nameEncoded;
public void setCreatetimeISO(String createtimeISO){
this.createtimeISO = createtimeISO;
}
public String getCreatetimeISO(){
return createtimeISO;
}
public void setCreatetime(String createtime){
this.createtime = createtime;
}
public String getCreatetime(){
return createtime;
}
public void setJsonMemberPrivate(boolean jsonMemberPrivate){
this.jsonMemberPrivate = jsonMemberPrivate;
}
public boolean isJsonMemberPrivate(){
return jsonMemberPrivate;
}
public void setHidden(boolean hidden){
this.hidden = hidden;
}
public boolean isHidden(){
return hidden;
}
public void setUserTitleEnabled(boolean userTitleEnabled){
this.userTitleEnabled = userTitleEnabled;
}
public boolean isUserTitleEnabled(){
return userTitleEnabled;
}
public void setDisplayName(String displayName){
this.displayName = displayName;
}
public String getDisplayName(){
return displayName;
}
public void setMemberCount(String memberCount){
this.memberCount = memberCount;
}
public String getMemberCount(){
return memberCount;
}
public void setIcon(String icon){
this.icon = icon;
}
public String getIcon(){
return icon;
}
public void setDescription(String description){
this.description = description;
}
public String getDescription(){
return description;
}
public void setLabelColor(String labelColor){
this.labelColor = labelColor;
}
public String getLabelColor(){
return labelColor;
}
public void setUserTitle(String userTitle){
this.userTitle = userTitle;
}
public String getUserTitle(){
return userTitle;
}
public void setDeleted(String deleted){
this.deleted = deleted;
}
public String getDeleted(){
return deleted;
}
public void setSystem(boolean system){
this.system = system;
}
public boolean isSystem(){
return system;
}
public void setCoverPosition(String coverPosition){
this.coverPosition = coverPosition;
}
public String getCoverPosition(){
return coverPosition;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setCoverUrl(String coverUrl){
this.coverUrl = coverUrl;
}
public String getCoverUrl(){
return coverUrl;
}
public void setCoverThumbUrl(String coverThumbUrl){
this.coverThumbUrl = coverThumbUrl;
}
public String getCoverThumbUrl(){
return coverThumbUrl;
}
public void setDisableJoinRequests(boolean disableJoinRequests){
this.disableJoinRequests = disableJoinRequests;
}
public boolean isDisableJoinRequests(){
return disableJoinRequests;
}
public void setSlug(String slug){
this.slug = slug;
}
public String getSlug(){
return slug;
}
public void setNameEncoded(String nameEncoded){
this.nameEncoded = nameEncoded;
}
public String getNameEncoded(){
return nameEncoded;
}
@Override
public String toString(){
return
"GroupsItem{" +
"createtimeISO = '" + createtimeISO + '\'' +
",createtime = '" + createtime + '\'' +
",private = '" + jsonMemberPrivate + '\'' +
",hidden = '" + hidden + '\'' +
",userTitleEnabled = '" + userTitleEnabled + '\'' +
",displayName = '" + displayName + '\'' +
",memberCount = '" + memberCount + '\'' +
",icon = '" + icon + '\'' +
",description = '" + description + '\'' +
",labelColor = '" + labelColor + '\'' +
",userTitle = '" + userTitle + '\'' +
",deleted = '" + deleted + '\'' +
",system = '" + system + '\'' +
",cover:position = '" + coverPosition + '\'' +
",name = '" + name + '\'' +
",cover:url = '" + coverUrl + '\'' +
",cover:thumb:url = '" + coverThumbUrl + '\'' +
",disableJoinRequests = '" + disableJoinRequests + '\'' +
",slug = '" + slug + '\'' +
",nameEncoded = '" + nameEncoded + '\'' +
"}";
}
}

View File

@ -0,0 +1,17 @@
package com.stardust.scriptdroid.network.entity;
/**
* Created by Stardust on 2017/9/21.
*/
public class TokenResponse {
public String code;
public static class Payload {
public String token;
}
}

View File

@ -0,0 +1,746 @@
package com.stardust.scriptdroid.network.entity;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class User{
@SerializedName("websiteLink")
private String websiteLink;
@SerializedName("reputation")
private String reputation;
@SerializedName("sso")
private List<Object> sso;
@SerializedName("icon:text")
private String iconText;
@SerializedName("isGlobalModerator")
private boolean isGlobalModerator;
@SerializedName("joindate")
private String joindate;
@SerializedName("profile_links")
private List<Object> profileLinks;
@SerializedName("reputation:disabled")
private boolean reputationDisabled;
@SerializedName("isAdmin")
private boolean isAdmin;
@SerializedName("moderationNote")
private String moderationNote;
@SerializedName("ips")
private List<String> ips;
@SerializedName("aboutme")
private String aboutme;
@SerializedName("isTargetAdmin")
private boolean isTargetAdmin;
@SerializedName("email:confirmed")
private boolean emailConfirmed;
@SerializedName("isAdminOrGlobalModerator")
private boolean isAdminOrGlobalModerator;
@SerializedName("emailClass")
private String emailClass;
@SerializedName("downvote:disabled")
private boolean downvoteDisabled;
@SerializedName("topiccount")
private String topiccount;
@SerializedName("isSelf")
private boolean isSelf;
@SerializedName("status")
private String status;
@SerializedName("birthday")
private String birthday;
@SerializedName("showHidden")
private boolean showHidden;
@SerializedName("yourid")
private int yourid;
@SerializedName("lastposttime")
private String lastposttime;
@SerializedName("isModerator")
private boolean isModerator;
@SerializedName("signature")
private String signature;
@SerializedName("icon:bgColor")
private String iconBgColor;
@SerializedName("canEdit")
private boolean canEdit;
@SerializedName("groupTitle")
private String groupTitle;
@SerializedName("followingCount")
private int followingCount;
@SerializedName("lastonlineISO")
private String lastonlineISO;
@SerializedName("email:disableEdit")
private boolean emailDisableEdit;
@SerializedName("uid")
private String uid;
@SerializedName("canChangePassword")
private boolean canChangePassword;
@SerializedName("profileviews")
private String profileviews;
@SerializedName("cover:url")
private String coverUrl;
@SerializedName("banned")
private boolean banned;
@SerializedName("userslug")
private String userslug;
@SerializedName("followerCount")
private int followerCount;
@SerializedName("email")
private String email;
@SerializedName("website")
private String website;
@SerializedName("isFollowing")
private boolean isFollowing;
@SerializedName("uploadedpicture")
private String uploadedpicture;
@SerializedName("passwordExpiry")
private String passwordExpiry;
@SerializedName("canBan")
private boolean canBan;
@SerializedName("lastonline")
private String lastonline;
@SerializedName("disableSignatures")
private boolean disableSignatures;
@SerializedName("groups")
private List<GroupsItem> groups;
@SerializedName("username:disableEdit")
private boolean usernameDisableEdit;
@SerializedName("picture")
private String picture;
@SerializedName("joindateISO")
private String joindateISO;
@SerializedName("isSelfOrAdminOrGlobalModerator")
private boolean isSelfOrAdminOrGlobalModerator;
@SerializedName("websiteName")
private String websiteName;
@SerializedName("isAdminOrGlobalModeratorOrModerator")
private boolean isAdminOrGlobalModeratorOrModerator;
@SerializedName("cover:position")
private String coverPosition;
@SerializedName("postcount")
private String postcount;
@SerializedName("location")
private String location;
@SerializedName("fullname")
private String fullname;
@SerializedName("age")
private int age;
@SerializedName("theirid")
private String theirid;
@SerializedName("username")
private String username;
public void setWebsiteLink(String websiteLink){
this.websiteLink = websiteLink;
}
public String getWebsiteLink(){
return websiteLink;
}
public void setReputation(String reputation){
this.reputation = reputation;
}
public String getReputation(){
return reputation;
}
public void setSso(List<Object> sso){
this.sso = sso;
}
public List<Object> getSso(){
return sso;
}
public void setIconText(String iconText){
this.iconText = iconText;
}
public String getIconText(){
return iconText;
}
public void setIsGlobalModerator(boolean isGlobalModerator){
this.isGlobalModerator = isGlobalModerator;
}
public boolean isIsGlobalModerator(){
return isGlobalModerator;
}
public void setJoindate(String joindate){
this.joindate = joindate;
}
public String getJoindate(){
return joindate;
}
public void setProfileLinks(List<Object> profileLinks){
this.profileLinks = profileLinks;
}
public List<Object> getProfileLinks(){
return profileLinks;
}
public void setReputationDisabled(boolean reputationDisabled){
this.reputationDisabled = reputationDisabled;
}
public boolean isReputationDisabled(){
return reputationDisabled;
}
public void setIsAdmin(boolean isAdmin){
this.isAdmin = isAdmin;
}
public boolean isIsAdmin(){
return isAdmin;
}
public void setModerationNote(String moderationNote){
this.moderationNote = moderationNote;
}
public String getModerationNote(){
return moderationNote;
}
public void setIps(List<String> ips){
this.ips = ips;
}
public List<String> getIps(){
return ips;
}
public void setAboutme(String aboutme){
this.aboutme = aboutme;
}
public String getAboutme(){
return aboutme;
}
public void setIsTargetAdmin(boolean isTargetAdmin){
this.isTargetAdmin = isTargetAdmin;
}
public boolean isIsTargetAdmin(){
return isTargetAdmin;
}
public void setEmailConfirmed(boolean emailConfirmed){
this.emailConfirmed = emailConfirmed;
}
public boolean isEmailConfirmed(){
return emailConfirmed;
}
public void setIsAdminOrGlobalModerator(boolean isAdminOrGlobalModerator){
this.isAdminOrGlobalModerator = isAdminOrGlobalModerator;
}
public boolean isIsAdminOrGlobalModerator(){
return isAdminOrGlobalModerator;
}
public void setEmailClass(String emailClass){
this.emailClass = emailClass;
}
public String getEmailClass(){
return emailClass;
}
public void setDownvoteDisabled(boolean downvoteDisabled){
this.downvoteDisabled = downvoteDisabled;
}
public boolean isDownvoteDisabled(){
return downvoteDisabled;
}
public void setTopiccount(String topiccount){
this.topiccount = topiccount;
}
public String getTopiccount(){
return topiccount;
}
public void setIsSelf(boolean isSelf){
this.isSelf = isSelf;
}
public boolean isIsSelf(){
return isSelf;
}
public void setStatus(String status){
this.status = status;
}
public String getStatus(){
return status;
}
public void setBirthday(String birthday){
this.birthday = birthday;
}
public String getBirthday(){
return birthday;
}
public void setShowHidden(boolean showHidden){
this.showHidden = showHidden;
}
public boolean isShowHidden(){
return showHidden;
}
public void setYourid(int yourid){
this.yourid = yourid;
}
public int getYourid(){
return yourid;
}
public void setLastposttime(String lastposttime){
this.lastposttime = lastposttime;
}
public String getLastposttime(){
return lastposttime;
}
public void setIsModerator(boolean isModerator){
this.isModerator = isModerator;
}
public boolean isIsModerator(){
return isModerator;
}
public void setSignature(String signature){
this.signature = signature;
}
public String getSignature(){
return signature;
}
public void setIconBgColor(String iconBgColor){
this.iconBgColor = iconBgColor;
}
public String getIconBgColor(){
return iconBgColor;
}
public void setCanEdit(boolean canEdit){
this.canEdit = canEdit;
}
public boolean isCanEdit(){
return canEdit;
}
public void setGroupTitle(String groupTitle){
this.groupTitle = groupTitle;
}
public String getGroupTitle(){
return groupTitle;
}
public void setFollowingCount(int followingCount){
this.followingCount = followingCount;
}
public int getFollowingCount(){
return followingCount;
}
public void setLastonlineISO(String lastonlineISO){
this.lastonlineISO = lastonlineISO;
}
public String getLastonlineISO(){
return lastonlineISO;
}
public void setEmailDisableEdit(boolean emailDisableEdit){
this.emailDisableEdit = emailDisableEdit;
}
public boolean isEmailDisableEdit(){
return emailDisableEdit;
}
public void setUid(String uid){
this.uid = uid;
}
public String getUid(){
return uid;
}
public void setCanChangePassword(boolean canChangePassword){
this.canChangePassword = canChangePassword;
}
public boolean isCanChangePassword(){
return canChangePassword;
}
public void setProfileviews(String profileviews){
this.profileviews = profileviews;
}
public String getProfileviews(){
return profileviews;
}
public void setCoverUrl(String coverUrl){
this.coverUrl = coverUrl;
}
public String getCoverUrl(){
return coverUrl;
}
public void setBanned(boolean banned){
this.banned = banned;
}
public boolean isBanned(){
return banned;
}
public void setUserslug(String userslug){
this.userslug = userslug;
}
public String getUserslug(){
return userslug;
}
public void setFollowerCount(int followerCount){
this.followerCount = followerCount;
}
public int getFollowerCount(){
return followerCount;
}
public void setEmail(String email){
this.email = email;
}
public String getEmail(){
return email;
}
public void setWebsite(String website){
this.website = website;
}
public String getWebsite(){
return website;
}
public void setIsFollowing(boolean isFollowing){
this.isFollowing = isFollowing;
}
public boolean isIsFollowing(){
return isFollowing;
}
public void setUploadedpicture(String uploadedpicture){
this.uploadedpicture = uploadedpicture;
}
public String getUploadedpicture(){
return uploadedpicture;
}
public void setPasswordExpiry(String passwordExpiry){
this.passwordExpiry = passwordExpiry;
}
public String getPasswordExpiry(){
return passwordExpiry;
}
public void setCanBan(boolean canBan){
this.canBan = canBan;
}
public boolean isCanBan(){
return canBan;
}
public void setLastonline(String lastonline){
this.lastonline = lastonline;
}
public String getLastonline(){
return lastonline;
}
public void setDisableSignatures(boolean disableSignatures){
this.disableSignatures = disableSignatures;
}
public boolean isDisableSignatures(){
return disableSignatures;
}
public void setGroups(List<GroupsItem> groups){
this.groups = groups;
}
public List<GroupsItem> getGroups(){
return groups;
}
public void setUsernameDisableEdit(boolean usernameDisableEdit){
this.usernameDisableEdit = usernameDisableEdit;
}
public boolean isUsernameDisableEdit(){
return usernameDisableEdit;
}
public void setPicture(String picture){
this.picture = picture;
}
public String getPicture(){
return picture;
}
public void setJoindateISO(String joindateISO){
this.joindateISO = joindateISO;
}
public String getJoindateISO(){
return joindateISO;
}
public void setIsSelfOrAdminOrGlobalModerator(boolean isSelfOrAdminOrGlobalModerator){
this.isSelfOrAdminOrGlobalModerator = isSelfOrAdminOrGlobalModerator;
}
public boolean isIsSelfOrAdminOrGlobalModerator(){
return isSelfOrAdminOrGlobalModerator;
}
public void setWebsiteName(String websiteName){
this.websiteName = websiteName;
}
public String getWebsiteName(){
return websiteName;
}
public void setIsAdminOrGlobalModeratorOrModerator(boolean isAdminOrGlobalModeratorOrModerator){
this.isAdminOrGlobalModeratorOrModerator = isAdminOrGlobalModeratorOrModerator;
}
public boolean isIsAdminOrGlobalModeratorOrModerator(){
return isAdminOrGlobalModeratorOrModerator;
}
public void setCoverPosition(String coverPosition){
this.coverPosition = coverPosition;
}
public String getCoverPosition(){
return coverPosition;
}
public void setPostcount(String postcount){
this.postcount = postcount;
}
public String getPostcount(){
return postcount;
}
public void setLocation(String location){
this.location = location;
}
public String getLocation(){
return location;
}
public void setFullname(String fullname){
this.fullname = fullname;
}
public String getFullname(){
return fullname;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setTheirid(String theirid){
this.theirid = theirid;
}
public String getTheirid(){
return theirid;
}
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return username;
}
@Override
public String toString(){
return
"User{" +
"websiteLink = '" + websiteLink + '\'' +
",reputation = '" + reputation + '\'' +
",sso = '" + sso + '\'' +
",icon:text = '" + iconText + '\'' +
",isGlobalModerator = '" + isGlobalModerator + '\'' +
",joindate = '" + joindate + '\'' +
",profile_links = '" + profileLinks + '\'' +
",reputation:disabled = '" + reputationDisabled + '\'' +
",isAdmin = '" + isAdmin + '\'' +
",moderationNote = '" + moderationNote + '\'' +
",ips = '" + ips + '\'' +
",aboutme = '" + aboutme + '\'' +
",isTargetAdmin = '" + isTargetAdmin + '\'' +
",email:confirmed = '" + emailConfirmed + '\'' +
",isAdminOrGlobalModerator = '" + isAdminOrGlobalModerator + '\'' +
",emailClass = '" + emailClass + '\'' +
",downvote:disabled = '" + downvoteDisabled + '\'' +
",topiccount = '" + topiccount + '\'' +
",isSelf = '" + isSelf + '\'' +
",status = '" + status + '\'' +
",birthday = '" + birthday + '\'' +
",showHidden = '" + showHidden + '\'' +
",yourid = '" + yourid + '\'' +
",lastposttime = '" + lastposttime + '\'' +
",isModerator = '" + isModerator + '\'' +
",signature = '" + signature + '\'' +
",icon:bgColor = '" + iconBgColor + '\'' +
",canEdit = '" + canEdit + '\'' +
",groupTitle = '" + groupTitle + '\'' +
",followingCount = '" + followingCount + '\'' +
",lastonlineISO = '" + lastonlineISO + '\'' +
",email:disableEdit = '" + emailDisableEdit + '\'' +
",uid = '" + uid + '\'' +
",canChangePassword = '" + canChangePassword + '\'' +
",profileviews = '" + profileviews + '\'' +
",cover:url = '" + coverUrl + '\'' +
",banned = '" + banned + '\'' +
",userslug = '" + userslug + '\'' +
",followerCount = '" + followerCount + '\'' +
",email = '" + email + '\'' +
",website = '" + website + '\'' +
",isFollowing = '" + isFollowing + '\'' +
",uploadedpicture = '" + uploadedpicture + '\'' +
",passwordExpiry = '" + passwordExpiry + '\'' +
",canBan = '" + canBan + '\'' +
",lastonline = '" + lastonline + '\'' +
",disableSignatures = '" + disableSignatures + '\'' +
",groups = '" + groups + '\'' +
",username:disableEdit = '" + usernameDisableEdit + '\'' +
",picture = '" + picture + '\'' +
",joindateISO = '" + joindateISO + '\'' +
",isSelfOrAdminOrGlobalModerator = '" + isSelfOrAdminOrGlobalModerator + '\'' +
",websiteName = '" + websiteName + '\'' +
",isAdminOrGlobalModeratorOrModerator = '" + isAdminOrGlobalModeratorOrModerator + '\'' +
",cover:position = '" + coverPosition + '\'' +
",postcount = '" + postcount + '\'' +
",location = '" + location + '\'' +
",fullname = '" + fullname + '\'' +
",age = '" + age + '\'' +
",theirid = '" + theirid + '\'' +
",username = '" + username + '\'' +
"}";
}
}

View File

@ -0,0 +1,376 @@
package com.stardust.scriptdroid.network.entity;
import com.google.gson.annotations.SerializedName;
public class VerifyResponse {
@SerializedName("message")
private String message;
@SerializedName("birthday")
private String birthday;
@SerializedName("lastposttime")
private String lastposttime;
@SerializedName("signature")
private String signature;
@SerializedName("icon:bgColor")
private String iconBgColor;
@SerializedName("groupTitle")
private String groupTitle;
@SerializedName("reputation")
private String reputation;
@SerializedName("followingCount")
private String followingCount;
@SerializedName("lastonlineISO")
private String lastonlineISO;
@SerializedName("uid")
private String uid;
@SerializedName("profileviews")
private String profileviews;
@SerializedName("icon:text")
private String iconText;
@SerializedName("banned")
private String banned;
@SerializedName("userslug")
private String userslug;
@SerializedName("followerCount")
private String followerCount;
@SerializedName("email")
private String email;
@SerializedName("joindate")
private String joindate;
@SerializedName("website")
private String website;
@SerializedName("uploadedpicture")
private String uploadedpicture;
@SerializedName("passwordExpiry")
private String passwordExpiry;
@SerializedName("lastonline")
private String lastonline;
@SerializedName("picture")
private String picture;
@SerializedName("joindateISO")
private String joindateISO;
@SerializedName("email:confirmed")
private Object emailConfirmed;
@SerializedName("postcount")
private String postcount;
@SerializedName("location")
private String location;
@SerializedName("fullname")
private String fullname;
@SerializedName("topiccount")
private String topiccount;
@SerializedName("username")
private String username;
@SerializedName("status")
private String status;
public boolean isSuccessful() {
return message == null;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getBirthday() {
return birthday;
}
public void setLastposttime(String lastposttime) {
this.lastposttime = lastposttime;
}
public String getLastposttime() {
return lastposttime;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getSignature() {
return signature;
}
public void setIconBgColor(String iconBgColor) {
this.iconBgColor = iconBgColor;
}
public String getIconBgColor() {
return iconBgColor;
}
public void setGroupTitle(String groupTitle) {
this.groupTitle = groupTitle;
}
public String getGroupTitle() {
return groupTitle;
}
public void setReputation(String reputation) {
this.reputation = reputation;
}
public String getReputation() {
return reputation;
}
public void setFollowingCount(String followingCount) {
this.followingCount = followingCount;
}
public String getFollowingCount() {
return followingCount;
}
public void setLastonlineISO(String lastonlineISO) {
this.lastonlineISO = lastonlineISO;
}
public String getLastonlineISO() {
return lastonlineISO;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return uid;
}
public void setProfileviews(String profileviews) {
this.profileviews = profileviews;
}
public String getProfileviews() {
return profileviews;
}
public void setIconText(String iconText) {
this.iconText = iconText;
}
public String getIconText() {
return iconText;
}
public void setBanned(String banned) {
this.banned = banned;
}
public String getBanned() {
return banned;
}
public void setUserslug(String userslug) {
this.userslug = userslug;
}
public String getUserslug() {
return userslug;
}
public void setFollowerCount(String followerCount) {
this.followerCount = followerCount;
}
public String getFollowerCount() {
return followerCount;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setJoindate(String joindate) {
this.joindate = joindate;
}
public String getJoindate() {
return joindate;
}
public void setWebsite(String website) {
this.website = website;
}
public String getWebsite() {
return website;
}
public void setUploadedpicture(String uploadedpicture) {
this.uploadedpicture = uploadedpicture;
}
public String getUploadedpicture() {
return uploadedpicture;
}
public void setPasswordExpiry(String passwordExpiry) {
this.passwordExpiry = passwordExpiry;
}
public String getPasswordExpiry() {
return passwordExpiry;
}
public void setLastonline(String lastonline) {
this.lastonline = lastonline;
}
public String getLastonline() {
return lastonline;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getPicture() {
return picture;
}
public void setJoindateISO(String joindateISO) {
this.joindateISO = joindateISO;
}
public String getJoindateISO() {
return joindateISO;
}
public void setEmailConfirmed(Object emailConfirmed) {
this.emailConfirmed = emailConfirmed;
}
public Object getEmailConfirmed() {
return emailConfirmed;
}
public void setPostcount(String postcount) {
this.postcount = postcount;
}
public String getPostcount() {
return postcount;
}
public void setLocation(String location) {
this.location = location;
}
public String getLocation() {
return location;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getFullname() {
return fullname;
}
public void setTopiccount(String topiccount) {
this.topiccount = topiccount;
}
public String getTopiccount() {
return topiccount;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatus() {
return status;
}
@Override
public String toString() {
return
"VerifyResponse{" +
"birthday = '" + birthday + '\'' +
",lastposttime = '" + lastposttime + '\'' +
",signature = '" + signature + '\'' +
",icon:bgColor = '" + iconBgColor + '\'' +
",groupTitle = '" + groupTitle + '\'' +
",reputation = '" + reputation + '\'' +
",followingCount = '" + followingCount + '\'' +
",lastonlineISO = '" + lastonlineISO + '\'' +
",uid = '" + uid + '\'' +
",profileviews = '" + profileviews + '\'' +
",icon:text = '" + iconText + '\'' +
",banned = '" + banned + '\'' +
",userslug = '" + userslug + '\'' +
",followerCount = '" + followerCount + '\'' +
",email = '" + email + '\'' +
",joindate = '" + joindate + '\'' +
",website = '" + website + '\'' +
",uploadedpicture = '" + uploadedpicture + '\'' +
",passwordExpiry = '" + passwordExpiry + '\'' +
",lastonline = '" + lastonline + '\'' +
",picture = '" + picture + '\'' +
",joindateISO = '" + joindateISO + '\'' +
",email:confirmed = '" + emailConfirmed + '\'' +
",postcount = '" + postcount + '\'' +
",location = '" + location + '\'' +
",fullname = '" + fullname + '\'' +
",topiccount = '" + topiccount + '\'' +
",username = '" + username + '\'' +
",status = '" + status + '\'' +
"}";
}
}

View File

@ -0,0 +1,130 @@
package com.stardust.scriptdroid.network.util;
import android.util.Log;
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
/**
* Created by Stardust on 2017/9/20.
*/
public class WebkitCookieManagerProxy extends CookieManager implements CookieJar {
private android.webkit.CookieManager webkitCookieManager;
private static final String TAG = WebkitCookieManagerProxy.class.getSimpleName();
public WebkitCookieManagerProxy() {
this(null, null);
}
WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy) {
super(null, cookiePolicy);
this.webkitCookieManager = android.webkit.CookieManager.getInstance();
}
@Override
public void put(URI uri, Map<String, List<String>> responseHeaders)
throws IOException {
// make sure our args are valid
if ((uri == null) || (responseHeaders == null))
return;
// save our url once
String url = uri.toString();
// go over the headers
for (String headerKey : responseHeaders.keySet()) {
// ignore headers which aren't cookie related
if ((headerKey == null)
|| !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey
.equalsIgnoreCase("Set-Cookie")))
continue;
// process each of the headers
for (String headerValue : responseHeaders.get(headerKey)) {
webkitCookieManager.setCookie(url, headerValue);
}
}
}
@Override
public Map<String, List<String>> get(URI uri,
Map<String, List<String>> requestHeaders) throws IOException {
// make sure our args are valid
if ((uri == null) || (requestHeaders == null))
throw new IllegalArgumentException("Argument is null");
// save our url once
String url = uri.toString();
// prepare our response
Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();
// get the cookie
String cookie = webkitCookieManager.getCookie(url);
// return it
if (cookie != null) {
res.put("Cookie", Arrays.asList(cookie));
}
return res;
}
@Override
public CookieStore getCookieStore() {
// we don't want anyone to work with this cookie store directly
throw new UnsupportedOperationException();
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
HashMap<String, List<String>> generatedResponseHeaders = new HashMap<>();
ArrayList<String> cookiesList = new ArrayList<>();
for (Cookie c : cookies) {
// toString correctly generates a normal cookie string
cookiesList.add(c.toString());
}
generatedResponseHeaders.put("Set-Cookie", cookiesList);
try {
put(url.uri(), generatedResponseHeaders);
} catch (IOException e) {
Log.e(TAG, "Error adding cookies through okhttp", e);
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
ArrayList<Cookie> cookieArrayList = new ArrayList<>();
try {
Map<String, List<String>> cookieList = get(url.uri(), new HashMap<String, List<String>>());
// Format here looks like: "Cookie":["cookie1=val1;cookie2=val2;"]
for (List<String> ls : cookieList.values()) {
for (String s : ls) {
String[] cookies = s.split(";");
for (String cookie : cookies) {
Cookie c = Cookie.parse(url, cookie);
cookieArrayList.add(c);
}
}
}
} catch (IOException e) {
Log.e(TAG, "error making cookie!", e);
}
return cookieArrayList;
}
}

View File

@ -0,0 +1,77 @@
package com.stardust.scriptdroid.ui.login;
import android.util.Log;
import android.widget.TextView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.VerifyResponse;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.BaseActivity;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Stardust on 2017/9/20.
*/
@EActivity(R.layout.activity_login)
public class LoginActivity extends BaseActivity {
@ViewById(R.id.username)
TextView mUserName;
@ViewById(R.id.password)
TextView mPassword;
@AfterViews
void setUpViews() {
setToolbarAsBack(getString(R.string.text_login));
}
@Click(R.id.login)
void login() {
String userName = mUserName.getText().toString();
String password = mPassword.getText().toString();
if (!checkNotEmpty(userName, password)) {
return;
}
NodeBB.getInstance().getRetrofit()
.create(UserApi.class)
.verify(userName, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<VerifyResponse>() {
@Override
public void onNext(@NonNull VerifyResponse verifyResponse) {
Log.d("Login", verifyResponse.toString());
}
@Override
public void onError(@NonNull Throwable e) {
e.printStackTrace();
}
});
}
private boolean checkNotEmpty(String userName, String password) {
if (userName.isEmpty()) {
mUserName.setError(getString(R.string.text_username_cannot_be_empty));
return false;
}
if (password.isEmpty()) {
mUserName.setError(getString(R.string.text_password_cannot_be_empty));
return false;
}
return true;
}
}

View File

@ -1,12 +1,7 @@
package com.stardust.scriptdroid.ui.main.community;
import android.app.Activity;
import android.content.Context;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.view.View;
import android.webkit.WebView;
import com.stardust.scriptdroid.R;
@ -18,6 +13,8 @@ import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.ViewById;
import java.util.regex.Pattern;
/**
* Created by Stardust on 2017/8/22.
*/
@ -25,6 +22,8 @@ import org.androidannotations.annotations.ViewById;
public class CommunityFragment extends ViewPagerFragment implements BackPressedHandler {
private static final String POSTS_PAGE_PATTERN = "[\\S\\s]+/topic/[0-9]+/[\\S\\s]+";
@ViewById(R.id.eweb_view)
EWebView mEWebView;
WebView mWebView;
@ -67,6 +66,15 @@ public class CommunityFragment extends ViewPagerFragment implements BackPressedH
@Override
protected void onFabClick(FloatingActionButton fab) {
if (isInPostsPage()) {
mWebView.loadUrl("javascript:$('button[component=\"topic/reply\"]').click()");
} else {
mWebView.loadUrl("javascript:$('.new_topic').click()");
}
}
private boolean isInPostsPage() {
String url = mWebView.getUrl();
return url.matches(POSTS_PAGE_PATTERN);
}
}

View File

@ -5,6 +5,8 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
@ -14,9 +16,14 @@ import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger;
import com.stardust.scriptdroid.external.floatingwindow.menu.HoverMenuService;
import com.stardust.scriptdroid.network.NodeBB;
import com.stardust.scriptdroid.network.VersionService;
import com.stardust.scriptdroid.network.api.UserApi;
import com.stardust.scriptdroid.network.entity.User;
import com.stardust.scriptdroid.network.entity.VersionInfo;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.login.LoginActivity;
import com.stardust.scriptdroid.ui.login.LoginActivity_;
import com.stardust.scriptdroid.ui.settings.SettingsActivity;
import com.stardust.scriptdroid.ui.update.UpdateInfoDialogBuilder;
import com.stardust.theme.ThemeColorManager;
@ -64,6 +71,12 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
@ViewById(R.id.header)
View mHeaderView;
@ViewById(R.id.username)
TextView mUserName;
@ViewById(R.id.avatar)
ImageView mAvatar;
private Disposable mConnectionStateDisposable;
@ -88,11 +101,46 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
syncSwitchState();
}
@Override
public void onResume() {
super.onResume();
syncUserInfo();
}
@AfterViews
void setUpViews() {
ThemeColorManager.addViewBackground(mHeaderView);
}
private void syncUserInfo() {
NodeBB.getInstance().getRetrofit()
.create(UserApi.class)
.me()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<User>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull User user) {
setUpUserInfo(user);
}
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
e.printStackTrace();
}
});
}
private void setUpUserInfo(User user) {
mUserName.setText(user.getUsername());
}
@Click(R.id.avatar)
void loginOrShowUserInfo() {
LoginActivity_.intent(getActivity()).start();
}
@Click(R.id.accessibility_service)
void enableOrDisableAccessibilityService() {
boolean isAccessibilityServiceEnabled = isAccessibilityServiceEnabled();
@ -173,13 +221,14 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
.onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
mConnectionItem.getSwitchCompat().setChecked(false, false);
IntentUtil.browse(getActivity(), URL_SUBLIME_PLUGIN_HELP);
}
})
.cancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mConnectionItem.getSwitchCompat().toggle(false);
mConnectionItem.getSwitchCompat().setChecked(false, false);
}
})
.show();

View File

@ -55,6 +55,8 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres
settings.setBuiltInZoomControls(true);
settings.setLoadWithOverviewMode(true);
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setDomStorageEnabled(true);
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.setWebChromeClient(new MyWebChromeClient());
}

View File

@ -4,7 +4,9 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.preference.PreferenceManager;
import android.support.annotation.IntDef;
import android.util.AttributeSet;
import android.view.View;
import com.stardust.scriptdroid.R;
@ -16,6 +18,7 @@ public class PrefSwitch extends SwitchCompat implements SharedPreferences.OnShar
private String mPrefKey;
private SharedPreferences mSharedPreferences;
private boolean mDefaultChecked;
public PrefSwitch(Context context) {
super(context);
@ -37,17 +40,23 @@ public class PrefSwitch extends SwitchCompat implements SharedPreferences.OnShar
return;
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.PrefSwitch);
mPrefKey = a.getString(R.styleable.PrefSwitch_key);
boolean defaultValue = a.getBoolean(R.styleable.PrefSwitch_defaultValue, false);
mDefaultChecked = a.getBoolean(R.styleable.PrefSwitch_defaultValue, false);
if (mPrefKey != null) {
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
setChecked(mSharedPreferences.getBoolean(mPrefKey, defaultValue), false);
readInitialState();
} else {
setChecked(defaultValue, false);
setChecked(mDefaultChecked, false);
}
a.recycle();
}
private void readInitialState() {
if (mPrefKey == null || mSharedPreferences == null)
return;
setChecked(mSharedPreferences.getBoolean(mPrefKey, mDefaultChecked), false);
}
private void notifyPrefChanged(boolean isChecked) {
if (mPrefKey == null)
return;
@ -83,5 +92,12 @@ public class PrefSwitch extends SwitchCompat implements SharedPreferences.OnShar
setChecked(mSharedPreferences.getBoolean(mPrefKey, isChecked()), false);
}
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
if (visibility == VISIBLE) {
readInitialState();
}
}
}

View File

@ -0,0 +1,158 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<com.stardust.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="@string/text_login"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/cv"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="64dp"
app:cardCornerRadius="6dp"
app:cardElevation="3dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginTop="10dp">
<View
android:layout_width="8dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:background="#2fa881"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="50dp"
android:text="@string/text_login"
android:textColor="#FFCC00"
android:textSize="18sp"
android:textStyle="bold"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:paddingEnd="30dp"
android:paddingStart="50dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_username"
android:inputType="textPersonName"
android:textSize="16sp"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingEnd="30dp"
android:paddingStart="50dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/text_password"
android:inputType="textPassword"
android:textSize="16sp"
/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="25dp"
android:gravity="center">
<Button
android:id="@+id/login"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="150dp"
android:layout_height="50dp"
android:text="@string/text_login"
>
</Button>
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dp"
android:text="@string/text_forgot_password"
android:textColor="#9a9a9a"
android:textSize="12sp"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@id/cv"
android:layout_alignTop="@id/cv"
android:layout_marginEnd="-20dp"
android:layout_marginTop="25dp"
android:src="@drawable/ic_add_white_48dp"
android:transitionName="loginFab"
app:fabSize="normal"
/>
</RelativeLayout>
</LinearLayout>

View File

@ -243,6 +243,12 @@
<string name="text_choose_file">选择文件</string>
<string name="text_click_too_frequently">您的操作太快啦ヽ(#`Д´)ノ</string>
<string name="text_connecting">连接中…</string>
<string name="text_username">用户名</string>
<string name="text_password">密码</string>
<string name="text_login">登录</string>
<string name="text_forgot_password">忘记密码</string>
<string name="text_username_cannot_be_empty">用户名不能为空</string>
<string name="text_password_cannot_be_empty">密码不能为空</string>
<string-array name="record_control_keys">

View File

@ -0,0 +1,28 @@
package com.stardust.autojs.runtime.api.crypto;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import static javax.crypto.Cipher.ENCRYPT_MODE;
/**
* Created by Stardust on 2017/9/20.
*/
public class Crypto {
public Cipher createCipher(String algorithm, String password) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(algorithm);
KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
keyGenerator.init(128, new SecureRandom(password.getBytes()));
SecretKey secretKey = keyGenerator.generateKey();
cipher.init(ENCRYPT_MODE, secretKey);
return cipher;
}
}

View File

@ -16,13 +16,17 @@ android {
}
}
lintOptions {
disable 'MissingTranslation'
disable 'ExtraTranslation'
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

View File

@ -17,6 +17,19 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name="com.stardust.view.accessibility.AccessibilityService"
android:label="@string/_app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config"/>
</service>
</application>
</manifest>

View File

@ -1,6 +1,9 @@
package com.stardust.auojs.inrt;
import android.app.Application;
import android.app.Fragment;
import com.stardust.auojs.inrt.rt.AutoJs;
/**
* Created by Stardust on 2017/7/1.
@ -8,9 +11,17 @@ import android.app.Application;
public class App extends Application {
private static App sApp;
public static App getApp() {
return sApp;
}
@Override
public void onCreate() {
super.onCreate();
sApp = this;
AutoJs.initInstance(this);
}
}

View File

@ -3,6 +3,7 @@ package com.stardust.auojs.inrt;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.stardust.auojs.inrt.rt.AutoJs;
import com.stardust.autojs.script.StringScriptSource;
import java.io.IOException;
@ -19,7 +20,7 @@ public class MainActivity extends AppCompatActivity {
is.read(data);
String js = new String(data);
StringScriptSource source = new StringScriptSource("<script>", js);
//AutoJs.getInstance().getScriptEngineService().execute(source);
AutoJs.getInstance().getScriptEngineService().execute(source);
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -2,8 +2,11 @@ package com.stardust.auojs.inrt.rt;
import android.accessibilityservice.AccessibilityService;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.text.TextUtils;
import com.stardust.auojs.inrt.App;
import com.stardust.autojs.runtime.api.ProcessShell;
import java.util.Locale;
@ -36,4 +39,8 @@ public class AccessibilityServiceTool {
return true;
}
public static void goToAccessibilitySetting() {
App.getApp().startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}

View File

@ -0,0 +1,242 @@
package com.stardust.auojs.inrt.rt;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.app.SimpleActivityLifecycleCallbacks;
import com.stardust.auojs.inrt.App;
import com.stardust.auojs.inrt.R;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.ScriptEngineServiceBuilder;
import com.stardust.autojs.core.accessibility.AccessibilityBridge;
import com.stardust.autojs.core.inputevent.InputEventObserver;
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
import com.stardust.autojs.engine.RootAutomatorEngine;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.api.AppUtils;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.runtime.api.Shell;
import com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity;
import com.stardust.autojs.runtime.api.image.ScreenCaptureRequester;
import com.stardust.autojs.runtime.console.StardustConsole;
import com.stardust.autojs.runtime.exception.ScriptException;
import com.stardust.autojs.script.AutoFileSource;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.util.ScreenMetrics;
import com.stardust.util.Supplier;
import com.stardust.util.UiHandler;
import com.stardust.view.accessibility.AccessibilityInfoProvider;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
import com.stardust.view.accessibility.LayoutInspector;
import com.stardust.view.accessibility.NotificationListener;
/**
* Created by Stardust on 2017/4/2.
*/
public class AutoJs {
private static AutoJs instance;
private Class<? extends android.accessibilityservice.AccessibilityService> sAccessibilityServiceClass = AccessibilityService.class;
public static AutoJs getInstance() {
return instance;
}
public static void initInstance(Context context) {
instance = new AutoJs(context);
}
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
private final NotificationListener.Observer mNotificationObserver;
private ScriptEngineManager mScriptEngineManager;
private final LayoutInspector mLayoutInspector = new LayoutInspector();
private final Context mContext;
private final UiHandler mUiHandler;
private final AppUtils mAppUtils;
private final AccessibilityInfoProvider mAccessibilityInfoProvider;
private final ScreenCaptureRequester mScreenCaptureRequester = new ScreenCaptureRequesterImpl();
private final ScriptEngineService mScriptEngineService;
private final Console mGlobalConsole;
private AutoJs(final Context context) {
mContext = context;
mUiHandler = new UiHandler(context);
mAppUtils = new AppUtils(context);
mGlobalConsole = new NoOpConsole();
mNotificationObserver = new NotificationListener.Observer(context);
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
mScriptEngineService = buildScriptEngineService();
addAccessibilityServiceDelegates();
//mScriptEngineService.registerGlobalScriptExecutionListener(new ScriptExecutionGlobalListener());
registerActivityLifecycleCallbacks();
InputEventObserver.initGlobal(context);
}
private ScriptEngineService buildScriptEngineService() {
initScriptEngineManager();
return new ScriptEngineServiceBuilder()
.uiHandler(mUiHandler)
.globalConsole(mGlobalConsole)
.engineManger(mScriptEngineManager)
.build();
}
private void initScriptEngineManager() {
mScriptEngineManager = new ScriptEngineManager(mContext);
mScriptEngineManager.registerEngine(JavaScriptSource.ENGINE, new Supplier<ScriptEngine>() {
@Override
public ScriptEngine get() {
LoopBasedJavaScriptEngine engine = new LoopBasedJavaScriptEngine(mContext);
engine.setRuntime(new ScriptRuntime.Builder()
.setConsole(new StardustConsole(mUiHandler, mGlobalConsole))
.setScreenCaptureRequester(mScreenCaptureRequester)
.setAccessibilityBridge(new AccessibilityBridgeImpl())
.setUiHandler(mUiHandler)
.setAppUtils(mAppUtils)
.setEngineService(mScriptEngineService)
.setShellSupplier(new Supplier<AbstractShell>() {
@Override
public AbstractShell get() {
return new Shell(mContext, true);
}
}).build());
return engine;
}
});
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, new Supplier<ScriptEngine>() {
@Override
public ScriptEngine get() {
return new RootAutomatorEngine(mContext);
}
});
}
private void registerActivityLifecycleCallbacks() {
App.getApp().registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ScreenMetrics.initIfNeeded(activity);
mAppUtils.setCurrentActivity(activity);
}
@Override
public void onActivityPaused(Activity activity) {
mAppUtils.setCurrentActivity(null);
}
@Override
public void onActivityResumed(Activity activity) {
mAppUtils.setCurrentActivity(activity);
}
});
}
private void addAccessibilityServiceDelegates() {
AccessibilityService.addDelegate(100, mAccessibilityInfoProvider);
AccessibilityService.addDelegate(200, mNotificationObserver);
AccessibilityService.addDelegate(300, mAccessibilityActionRecorder);
}
public AccessibilityActionRecorder getAccessibilityActionRecorder() {
return mAccessibilityActionRecorder;
}
public AppUtils getAppUtils() {
return mAppUtils;
}
public UiHandler getUiHandler() {
return mUiHandler;
}
public LayoutInspector getLayoutInspector() {
return mLayoutInspector;
}
public ScriptEngineService getScriptEngineService() {
return mScriptEngineService;
}
public AccessibilityInfoProvider getInfoProvider() {
return mAccessibilityInfoProvider;
}
public void ensureAccessibilityServiceEnabled() {
if (AccessibilityService.getInstance() == null) {
String errorMessage = null;
if (AccessibilityServiceUtils.isAccessibilityServiceEnabled(App.getApp(), sAccessibilityServiceClass)) {
errorMessage = App.getApp().getString(R.string.text_auto_operate_service_enabled_but_not_running);
} else {
if (true) {
if (!AccessibilityServiceTool.enableAccessibilityServiceByRootAndWaitFor(App.getApp(), 2000)) {
errorMessage = App.getApp().getString(R.string.text_enable_accessibility_service_by_root_timeout);
}
} else {
errorMessage = App.getApp().getString(R.string.text_no_accessibility_permission);
}
}
if (errorMessage != null) {
AccessibilityServiceTool.goToAccessibilitySetting();
throw new ScriptException(errorMessage);
}
}
}
private class AccessibilityBridgeImpl extends AccessibilityBridge {
@Override
public void ensureServiceEnabled() {
AutoJs.this.ensureAccessibilityServiceEnabled();
}
@Nullable
@Override
public AccessibilityService getService() {
return AccessibilityService.getInstance();
}
@Override
public AccessibilityInfoProvider getInfoProvider() {
return mAccessibilityInfoProvider;
}
@Override
public NotificationListener.Observer getNotificationObserver() {
return mNotificationObserver;
}
}
private class ScreenCaptureRequesterImpl extends ScreenCaptureRequester.AbstractScreenCaptureRequester {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void request() {
Activity activity = mAppUtils.getCurrentActivity();
if (activity instanceof OnActivityResultDelegate.DelegateHost) {
ScreenCaptureRequester requester = new ActivityScreenCaptureRequester(
((OnActivityResultDelegate.DelegateHost) activity).getOnActivityResultDelegateMediator(), activity);
requester.setOnActivityResultCallback(mCallback);
requester.request();
} else {
ScreenCaptureRequestActivity.request(mContext, mCallback);
}
}
}
}

View File

@ -0,0 +1,71 @@
package com.stardust.auojs.inrt.rt;
import android.support.annotation.Nullable;
import com.stardust.autojs.runtime.api.Console;
/**
* Created by Stardust on 2017/9/21.
*/
public class NoOpConsole implements Console {
@Override
public void verbose(@Nullable Object data, Object... options) {
}
@Override
public void log(@Nullable Object data, Object... options) {
}
@Override
public void print(int level, Object data, Object... options) {
}
@Override
public void info(@Nullable Object data, Object... options) {
}
@Override
public void warn(@Nullable Object data, Object... options) {
}
@Override
public void error(@Nullable Object data, Object... options) {
}
@Override
public void assertTrue(boolean value, @Nullable Object data, Object... options) {
}
@Override
public void clear() {
}
@Override
public void show() {
}
@Override
public void hide() {
}
@Override
public void println(int level, CharSequence charSequence) {
}
@Override
public void setTitle(CharSequence title) {
}
}

View File

@ -2,4 +2,5 @@
<string name="app_name">inrt</string>
<string name="text_no_accessibility_permission">无障碍服务未启动</string>
<string name="text_auto_operate_service_enabled_but_not_running">无障碍服务已启用但没有运行,您可以尝试重新启用或重启手机</string>
<string name="text_enable_accessibility_service_by_root_timeout">使用root权限启用无障碍服务失败</string>
</resources>