Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.

Commit 7746524

Browse files
Add files via upload
1 parent bb2d6f4 commit 7746524

9 files changed

Lines changed: 454 additions & 0 deletions
16 KB
Binary file not shown.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.beeware.android;
2+
3+
public class DrawHandlerView extends android.view.View {
4+
private IDrawHandler drawHandler = null;
5+
6+
public DrawHandlerView(android.content.Context context) {
7+
super(context);
8+
}
9+
10+
public void setDrawHandler(IDrawHandler drawHandler) {
11+
this.drawHandler = drawHandler;
12+
}
13+
14+
public void onDraw(android.graphics.Canvas canvas) {
15+
super.onDraw(canvas);
16+
drawHandler.handleDraw(canvas);
17+
}
18+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.beeware.android;
2+
3+
public interface IDrawHandler {
4+
public void handleDraw(android.graphics.Canvas canvas);
5+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.beeware.android;
2+
3+
import android.content.Intent;
4+
import android.content.res.Configuration;
5+
import android.view.Menu;
6+
import android.view.MenuItem;
7+
8+
public interface IPythonApp {
9+
void onCreate();
10+
void onResume();
11+
void onStart();
12+
void onActivityResult(int requestCode, int resultCode, Intent data);
13+
void onConfigurationChanged(Configuration newConfig);
14+
boolean onOptionsItemSelected(MenuItem menuitem);
15+
boolean onPrepareOptionsMenu(Menu menu);
16+
// There's no need to add any more methods to this interface, as the Python
17+
// call mechanism no longer uses it.
18+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.beeware.android;
2+
3+
import android.app.Activity;
4+
import android.os.Build;
5+
import android.view.View;
6+
import android.view.ViewGroup;
7+
import android.widget.LinearLayout;
8+
9+
public class LTRConfig {
10+
11+
public static void applyLTR(Activity activity) {
12+
ViewGroup rootView = (ViewGroup) activity.findViewById(android.R.id.content);
13+
setLTR(rootView);
14+
}
15+
16+
private static void setLTR(ViewGroup viewGroup) {
17+
for (int i = 0; i < viewGroup.getChildCount(); i++) {
18+
View view = viewGroup.getChildAt(i);
19+
if (view instanceof ViewGroup) {
20+
setLTR((ViewGroup) view);
21+
}
22+
}
23+
24+
// اگر نسخه اندروید بالاتر از نوقا است، جهت LTR را تنظیم می‌کنیم
25+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
26+
viewGroup.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
27+
}
28+
}
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.beeware.android;
2+
3+
import android.content.Context;
4+
import android.os.Environment;
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.util.logging.FileHandler;
8+
import java.util.logging.Handler;
9+
import java.util.logging.Level;
10+
import java.util.logging.Logger;
11+
import java.util.logging.SimpleFormatter;
12+
13+
public class LoggingConfig {
14+
15+
public static void setup(Context context) {
16+
String logPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download/wwarpscanner/app_java.txt";
17+
File logFile = new File(logPath);
18+
19+
if (logFile.exists()) {
20+
logFile.delete();
21+
}
22+
23+
try {
24+
if (logFile.createNewFile()) {
25+
Handler fileHandler = new FileHandler(logPath, true);
26+
fileHandler.setFormatter(new SimpleFormatter());
27+
Logger logger = Logger.getLogger(context.getPackageName());
28+
logger.addHandler(fileHandler);
29+
logger.setLevel(Level.ALL);
30+
Logger.getLogger("").addHandler(fileHandler); // Add handler to root logger
31+
}
32+
} catch (IOException e) {
33+
e.printStackTrace();
34+
}
35+
}
36+
}
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
package org.beeware.android;
2+
3+
import android.content.Intent;
4+
import android.content.res.Configuration;
5+
import android.os.Bundle;
6+
import android.util.Log;
7+
import android.view.Menu;
8+
import android.view.MenuItem;
9+
import android.widget.LinearLayout;
10+
import android.content.Context;
11+
12+
import androidx.appcompat.app.AppCompatActivity;
13+
14+
import com.chaquo.python.Kwarg;
15+
import com.chaquo.python.PyException;
16+
import com.chaquo.python.PyObject;
17+
import com.chaquo.python.Python;
18+
import com.chaquo.python.android.AndroidPlatform;
19+
20+
import java.util.List;
21+
import java.util.logging.Logger;
22+
23+
import org.json.JSONArray;
24+
import org.json.JSONException;
25+
26+
import com.arshiacomplus.warpscanner.warpscanner.R;
27+
28+
import android.app.Activity;
29+
30+
import android.os.StrictMode;
31+
32+
public class MainActivity extends AppCompatActivity {
33+
34+
35+
36+
// To profile app launch, use `adb -s MainActivity`; look for "onCreate() start" and "onResume() completed".
37+
private String TAG = "MainActivity";
38+
private static PyObject pythonApp;
39+
private static Logger logger;
40+
41+
42+
43+
/**
44+
* This method is called by `app.__main__` over JNI in Python when the BeeWare
45+
* app launches.
46+
*
47+
* @param app
48+
*/
49+
@SuppressWarnings("unused")
50+
public static void setPythonApp(IPythonApp app) {
51+
52+
pythonApp = PyObject.fromJava(app);
53+
54+
}
55+
56+
/**
57+
* We store the MainActivity instance on the *class* so that we can easily
58+
* access it from Python.
59+
*/
60+
public static MainActivity singletonThis;
61+
62+
protected void onCreate(Bundle savedInstanceState) {
63+
Log.d(TAG, "onCreate() start");
64+
// Change away from the splash screen theme to the app theme.
65+
setTheme(R.style.AppTheme);
66+
super.onCreate(savedInstanceState);
67+
LinearLayout layout = new LinearLayout(this);
68+
this.setContentView(layout);
69+
singletonThis = this;
70+
71+
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
72+
StrictMode.setThreadPolicy(policy);
73+
74+
PermissionUtils.requestStoragePermissions(this);
75+
76+
Context appContext = getApplicationContext();
77+
LoggingConfig.setup(appContext);
78+
logger = Logger.getLogger(appContext.getPackageName());
79+
80+
// ثبت UncaughtExceptionHandler
81+
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
82+
@Override
83+
public void uncaughtException(Thread t, Throwable e) {
84+
logger.severe("Uncaught exception: " + e.getMessage());
85+
for (StackTraceElement element : e.getStackTrace()) {
86+
logger.severe(element.toString());
87+
}
88+
}
89+
});
90+
91+
logger.info("Application started");
92+
93+
94+
95+
96+
97+
// Call PermissionUtils to request permissions
98+
99+
100+
101+
LTRConfig.applyLTR(this);
102+
// فراخوانی بررسی نسخه
103+
VersionChecker.checkVersion(this);
104+
105+
106+
// اکنون می‌توانید لاگ بگیرید
107+
Logger logger = Logger.getLogger(getPackageName());
108+
logger.info("Application started");
109+
110+
111+
Python py;
112+
if (Python.isStarted()) {
113+
Log.d(TAG, "Python already started");
114+
py = Python.getInstance();
115+
} else {
116+
Log.d(TAG, "Starting Python");
117+
AndroidPlatform platform = new AndroidPlatform(this);
118+
platform.redirectStdioToLogcat();
119+
Python.start(platform);
120+
py = Python.getInstance();
121+
122+
String argvStr = getIntent().getStringExtra("org.beeware.ARGV");
123+
if (argvStr != null) {
124+
try {
125+
JSONArray argvJson = new JSONArray(argvStr);
126+
List<PyObject> sysArgv = py.getModule("sys").get("argv").asList();
127+
for (int i = 0; i < argvJson.length(); i++) {
128+
sysArgv.add(PyObject.fromJava(argvJson.getString(i)));
129+
}
130+
} catch (JSONException e) {
131+
throw new RuntimeException(e);
132+
}
133+
}
134+
}
135+
136+
Log.d(TAG, "Running main module " + getString(R.string.main_module));
137+
py.getModule("runpy").callAttr(
138+
"run_module",
139+
getString(R.string.main_module),
140+
new Kwarg("run_name", "__main__"),
141+
new Kwarg("alter_sys", true)
142+
);
143+
144+
userCode("onCreate");
145+
Log.d(TAG, "onCreate() complete");
146+
}
147+
148+
protected void onStart() {
149+
Log.d(TAG, "onStart() start");
150+
super.onStart();
151+
userCode("onStart");
152+
Log.d(TAG, "onStart() complete");
153+
}
154+
155+
protected void onResume() {
156+
Log.d(TAG, "onResume() start");
157+
super.onResume();
158+
userCode("onResume");
159+
Log.d(TAG, "onResume() complete");
160+
}
161+
162+
protected void onPause() {
163+
Log.d(TAG, "onPause() start");
164+
super.onPause();
165+
userCode("onPause");
166+
Log.d(TAG, "onPause() complete");
167+
}
168+
169+
protected void onStop() {
170+
Log.d(TAG, "onStop() start");
171+
super.onStop();
172+
userCode("onStop");
173+
Log.d(TAG, "onStop() complete");
174+
}
175+
protected void onDestroy() {
176+
Log.d(TAG, "onDestroy() start");
177+
super.onDestroy();
178+
userCode("onDestroy");
179+
Log.d(TAG, "onDestroy() complete");
180+
}
181+
protected void onRestart() {
182+
Log.d(TAG, "onRestart() start");
183+
super.onRestart();
184+
userCode("onRestart");
185+
Log.d(TAG, "onRestart() complete");
186+
}
187+
public void onTopResumedActivityChanged (boolean isTopResumedActivity){
188+
Log.d(TAG, "onTopResumedActivityChanged() start");
189+
super.onTopResumedActivityChanged(isTopResumedActivity);
190+
userCode("onTopResumedActivityChanged", isTopResumedActivity);
191+
Log.d(TAG, "onTopResumedActivityChanged() complete");
192+
}
193+
194+
protected void onActivityResult(int requestCode, int resultCode, Intent data)
195+
{
196+
Log.d(TAG, "onActivityResult() start");
197+
super.onActivityResult(requestCode, resultCode, data);
198+
userCode("onActivityResult", requestCode, resultCode, data);
199+
Log.d(TAG, "onActivityResult() complete");
200+
}
201+
202+
public void onConfigurationChanged(Configuration newConfig) {
203+
Log.d(TAG, "onConfigurationChanged() start");
204+
super.onConfigurationChanged(newConfig);
205+
userCode("onConfigurationChanged", newConfig);
206+
Log.d(TAG, "onConfigurationChanged() complete");
207+
}
208+
209+
public boolean onOptionsItemSelected(MenuItem menuitem) {
210+
Log.d(TAG, "onOptionsItemSelected() start");
211+
PyObject pyResult = userCode("onOptionsItemSelected", menuitem);
212+
boolean result = (pyResult == null) ? false : pyResult.toBoolean();
213+
Log.d(TAG, "onOptionsItemSelected() complete");
214+
return result;
215+
}
216+
217+
public boolean onPrepareOptionsMenu(Menu menu) {
218+
Log.d(TAG, "onPrepareOptionsMenu() start");
219+
PyObject pyResult = userCode("onPrepareOptionsMenu", menu);
220+
boolean result = (pyResult == null) ? false : pyResult.toBoolean();
221+
Log.d(TAG, "onPrepareOptionsMenu() complete");
222+
return result;
223+
}
224+
225+
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
226+
{
227+
Log.d(TAG, "onRequestPermissionsResult() start");
228+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
229+
userCode("onRequestPermissionsResult", requestCode, permissions, grantResults);
230+
Log.d(TAG, "onRequestPermissionsResult() complete");
231+
}
232+
233+
private PyObject userCode(String methodName, Object... args) {
234+
if (pythonApp == null) {
235+
// Could be a non-graphical app such as Python-support-testbed.
236+
return null;
237+
}
238+
try {
239+
if (pythonApp.containsKey(methodName)) {
240+
return pythonApp.callAttr(methodName, args);
241+
} else {
242+
// Handle the case where the method doesn't exist
243+
return null;
244+
}
245+
} catch (PyException e) {
246+
if (e.getMessage().startsWith("NotImplementedError")) {
247+
return null;
248+
}
249+
throw e;
250+
}
251+
}
252+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.beeware.android;
2+
3+
import android.Manifest;
4+
import android.app.Activity;
5+
import android.content.pm.PackageManager;
6+
import androidx.core.app.ActivityCompat;
7+
import androidx.core.content.ContextCompat;
8+
9+
public class PermissionUtils {
10+
public static void requestStoragePermissions(Activity activity) {
11+
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
12+
ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
13+
14+
ActivityCompat.requestPermissions(activity, new String[]{
15+
Manifest.permission.READ_EXTERNAL_STORAGE,
16+
Manifest.permission.WRITE_EXTERNAL_STORAGE
17+
}, 1);
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)