Skip to content

Commit

Permalink
修复4.2中的多用户BUG
Browse files Browse the repository at this point in the history
增加应用内配置工具

fix multi users bug in 4.2
add in-app configuration tool
  • Loading branch information
w2016561536 committed Feb 11, 2022
1 parent 91cf9d7 commit 77fda64
Show file tree
Hide file tree
Showing 19 changed files with 476 additions and 150 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@

9. 目录重定向消息默认只显示一次,如果错过了目录重定向的Toast消息,可以在`/[内部存储]/DCIM/Camera1/`目录下创建`force_show.jpg`文件来覆盖默认设定。(全局实时生效)

10. 如果需要为每一个应用程序分配视频,可以在`/[内部存储]/DCIM/Camera1/`目录下创建`private_dir.jpg`强制使用应用程序私有目录。(全局实时生效)

> 注意:6~10的配置开关均在应用程序中,您可以快捷地在应用程序中配置,也可以手动创建文件。
## 常见问题

Expand Down
3 changes: 3 additions & 0 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ A virtual camera based on Xposed

9. The directory redirection message is displayed only once by default. If you miss the toast message of directory redirection, you can create a `force_show.jpg` file in the `/[INTERNEL_STORAGE]/DCIM/Camera1/` directory to override the default setting. (Global real-time effective)

10. If you need to allocate videos for each application, you can create `private_dir.jpg` in the `/[INTERNEL_STORAGE]/DCIM/Camera1/` directory to enforce apps use private directory. (Global real-time effective)

> Note: the configuration switches of 6 ~ 10 are in the application. You can quickly configure them in the application or create files manually.
## FAQ

Expand Down
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ android {
defaultConfig {
applicationId "com.example.vcam"
minSdk 21
targetSdk 27
versionCode 26
versionName "4.2"
targetSdk 26
versionCode 27
versionName "4.3"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
Expand Down
Binary file modified app/release/app-release.apk
Binary file not shown.
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 26,
"versionName": "4.2",
"versionCode": 27,
"versionName": "4.3",
"outputFile": "app-release.apk"
}
],
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@
android:value="51" />
</application>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

</manifest>
213 changes: 130 additions & 83 deletions app/src/main/java/com/example/vcam/HookMain.java

Large diffs are not rendered by default.

262 changes: 209 additions & 53 deletions app/src/main/java/com/example/vcam/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,101 +1,257 @@
package com.example.vcam;


import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.os.Environment;
import android.util.Log;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.Toast;

import java.io.File;

import de.robv.android.xposed.XposedBridge;
import java.io.IOException;

public class MainActivity extends Activity {
@SuppressLint("CommitPrefEdits")
public void onCreate(Bundle savedInstanceState) {
makeWorldReadable();

SharedPreferences preference;
preference = this.getSharedPreferences("module_set", MODE_PRIVATE);
private Switch force_show_switch;
private Switch disable_switch;
private Switch play_sound_switch;
private Switch force_private_dir;
private Switch disable_toast_switch;

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
Toast.makeText(MainActivity.this, R.string.permission_lack_warn, Toast.LENGTH_SHORT).show();
}else {
File camera_dir = new File (Environment.getExternalStorageDirectory().getAbsolutePath()+"/DCIM/Camera1/");
if (!camera_dir.exists()){
camera_dir.mkdir();
}
}
}
}

@Override
protected void onResume() {
super.onResume();
sync_statue_with_files();
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button repo_button = findViewById(R.id.button);
Switch force_display = findViewById(R.id.switch2);
Switch disable_module_switch = findViewById(R.id.switch1);
force_show_switch = findViewById(R.id.switch1);
disable_switch = findViewById(R.id.switch2);
play_sound_switch = findViewById(R.id.switch3);
force_private_dir = findViewById(R.id.switch4);
disable_toast_switch = findViewById(R.id.switch5);

disable_module_switch.setChecked(preference.getBoolean("disable", false));
force_display.setChecked(preference.getBoolean("force_display",false));

repo_button.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
sync_statue_with_files();

Uri uri = Uri.parse("https://github.com/w2016561536/android_virtual_cam");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
repo_button.setOnClickListener(v -> {

Uri uri = Uri.parse("https://github.com/w2016561536/android_virtual_cam");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
});

Button repo_button_chinamainland = findViewById(R.id.button2);
repo_button_chinamainland.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri uri = Uri.parse("https://gitee.com/w2016561536/android_virtual_cam");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
repo_button_chinamainland.setOnClickListener(view -> {
Uri uri = Uri.parse("https://gitee.com/w2016561536/android_virtual_cam");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
});

disable_switch.setOnCheckedChangeListener((compoundButton, b) -> {
if (compoundButton.isPressed()) {
if (!has_permission()) {
request_permission();
} else {
File disable_file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/disable.jpg");
if (disable_file.exists() != b){
if (b){
try {
disable_file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}else {
disable_file.delete();
}
}
}
sync_statue_with_files();
}
});

force_show_switch.setOnCheckedChangeListener((compoundButton, b) -> {
if (compoundButton.isPressed()) {
if (!has_permission()) {
request_permission();
} else {
File force_show_switch = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/force_show.jpg");
if (force_show_switch.exists() != b){
if (b){
try {
force_show_switch.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}else {
force_show_switch.delete();
}
}
}
sync_statue_with_files();
}
});

SharedPreferences finalPreference = preference;
disable_module_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
play_sound_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
SharedPreferences.Editor editor = finalPreference.edit();
editor.putBoolean("disable",b);
editor.apply();
editor.commit();
makeWorldReadable();
if (compoundButton.isPressed()) {
if (!has_permission()) {
request_permission();
} else {
File play_sound_switch = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/no-silent.jpg");
if (play_sound_switch.exists() != b){
if (b){
try {
play_sound_switch.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}else {
play_sound_switch.delete();
}
}
}
sync_statue_with_files();
}
}
});

force_display.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
SharedPreferences.Editor editor = finalPreference.edit();
editor.putBoolean("force_display",b);
editor.apply();
editor.commit();
makeWorldReadable();
force_private_dir.setOnCheckedChangeListener((compoundButton, b) -> {
if (compoundButton.isPressed()) {
if (!has_permission()) {
request_permission();
} else {
File force_private_dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/private_dir.jpg");
if (force_private_dir.exists() != b){
if (b){
try {
force_private_dir.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}else {
force_private_dir.delete();
}
}
}
sync_statue_with_files();
}
});


disable_toast_switch.setOnCheckedChangeListener((compoundButton, b) -> {
if (compoundButton.isPressed()) {
if (!has_permission()) {
request_permission();
} else {
File disable_toast_file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/no_toast.jpg");
if (disable_toast_file.exists() != b){
if (b){
try {
disable_toast_file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}else {
disable_toast_file.delete();
}
}
}
sync_statue_with_files();
}
});

}

@TargetApi(Build.VERSION_CODES.N)
@SuppressLint({"SetWorldReadable", "SetWorldWritable"})
private void makeWorldReadable() {
try {
File f = new File(this.getDataDir().getAbsolutePath()+"/shared_prefs/module_set.xml");
f.setReadable(true, false);
f.setExecutable(true, false);
f.setWritable(true, false);
} catch (Exception e) {
XposedBridge.log("【VCAM】权限设置失败"+ e.toString());
private void request_permission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED
|| this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(R.string.permission_lack_warn);
builder.setMessage(R.string.permission_description);

builder.setNegativeButton(R.string.negative, (dialogInterface, i) -> Toast.makeText(MainActivity.this, R.string.permission_lack_warn, Toast.LENGTH_SHORT).show());

builder.setPositiveButton(R.string.positive, (dialogInterface, i) -> requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1));
builder.show();
}
}
}

private boolean has_permission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_DENIED
&& this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_DENIED;
}
return true;
}


private void sync_statue_with_files() {
Log.d(this.getApplication().getPackageName(), "【VCAM】[sync]同步开关状态");

if (!has_permission()){
request_permission();
}else {
File camera_dir = new File (Environment.getExternalStorageDirectory().getAbsolutePath()+"/DCIM/Camera1");
if (!camera_dir.exists()){
camera_dir.mkdir();
}
}

File disable_file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/disable.jpg");
disable_switch.setChecked(disable_file.exists());

File force_show_file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/force_show.jpg");
force_show_switch.setChecked(force_show_file.exists());

File play_sound_file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/no-silent.jpg");
play_sound_switch.setChecked(play_sound_file.exists());

File force_private_dir_file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/private_dir.jpg");
force_private_dir.setChecked(force_private_dir_file.exists());

File disable_toast_file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera1/no_toast.jpg");
disable_toast_switch.setChecked(disable_toast_file.exists());

}


}



2 changes: 1 addition & 1 deletion app/src/main/java/com/example/vcam/VideoToFrames.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public void videoDecode(String videoFilePath) throws IOException {
decoder.stop();
}
}catch (Exception e){
XposedBridge.log("【VCAM】[videofile]"+ e.getMessage());
XposedBridge.log("【VCAM】[videofile]"+ e.toString());
} finally {
if (decoder != null) {
decoder.stop();
Expand Down
Loading

0 comments on commit 77fda64

Please sign in to comment.