Fujifilm X Series Remote Control for Android (Prototype)
Fujifilm Xシリーズカメラの遠隔操作アプリ for Android (プロトタイプ)
Revision | 1737fcbf426455f76c09158d622bd5346fd12950 (tree) |
---|---|
Zeit | 2019-05-19 22:56:57 |
Autor | MRSa <mrsa@myad...> |
Commiter | MRSa |
ちょっとだけ、preferenceの準備。
@@ -21,6 +21,7 @@ dependencies { | ||
21 | 21 | implementation fileTree(dir: 'libs', include: ['*.jar']) |
22 | 22 | implementation 'androidx.appcompat:appcompat:1.1.0-alpha04' |
23 | 23 | implementation 'com.google.android.material:material:1.1.0-alpha06' |
24 | + implementation 'androidx.preference:preference:1.0.0' | |
24 | 25 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' |
25 | 26 | implementation project(':opencv41') |
26 | 27 | } |
@@ -0,0 +1,99 @@ | ||
1 | +package net.osdn.gokigen.cameratest; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.content.DialogInterface; | |
5 | + | |
6 | +import androidx.appcompat.app.AlertDialog; | |
7 | +import androidx.appcompat.app.AppCompatDialogFragment; | |
8 | + | |
9 | +public class ConfirmationDialog extends AppCompatDialogFragment | |
10 | +{ | |
11 | + private Context context = null; | |
12 | + | |
13 | + public static ConfirmationDialog newInstance(Context context) | |
14 | + { | |
15 | + ConfirmationDialog instance = new ConfirmationDialog(); | |
16 | + instance.prepare(context); | |
17 | + | |
18 | + return (instance); | |
19 | + } | |
20 | + | |
21 | + private void prepare(Context context) | |
22 | + { | |
23 | + this.context = context; | |
24 | + } | |
25 | + | |
26 | + public void show(int titleResId, int messageResId, final Callback callback) | |
27 | + { | |
28 | + String title = ""; | |
29 | + String message = ""; | |
30 | + | |
31 | + // タイトルとメッセージをのダイアログを表示する | |
32 | + if (context != null) | |
33 | + { | |
34 | + title = context.getString(titleResId); | |
35 | + message = context.getString(messageResId); | |
36 | + } | |
37 | + show(title, message, callback); | |
38 | + } | |
39 | + | |
40 | + public void show(String title, String message, final Callback callback) | |
41 | + { | |
42 | + // 確認ダイアログの生成 | |
43 | + final AlertDialog.Builder alertDialog = new AlertDialog.Builder(context); | |
44 | + alertDialog.setTitle(title); | |
45 | + alertDialog.setIcon(android.R.drawable.ic_dialog_alert); | |
46 | + alertDialog.setMessage(message); | |
47 | + alertDialog.setCancelable(true); | |
48 | + | |
49 | + // ボタンを設定する(実行ボタン) | |
50 | + alertDialog.setPositiveButton(context.getString(R.string.dialog_positive_execute), | |
51 | + new DialogInterface.OnClickListener() { | |
52 | + public void onClick(DialogInterface dialog, int which) | |
53 | + { | |
54 | + callback.confirm(); | |
55 | + dialog.dismiss(); | |
56 | + } | |
57 | + }); | |
58 | + | |
59 | + // ボタンを設定する (キャンセルボタン) | |
60 | + alertDialog.setNegativeButton(context.getString(R.string.dialog_negative_cancel), | |
61 | + new DialogInterface.OnClickListener() { | |
62 | + public void onClick(DialogInterface dialog, int which) | |
63 | + { | |
64 | + dialog.cancel(); | |
65 | + } | |
66 | + }); | |
67 | + | |
68 | + // 確認ダイアログを表示する | |
69 | + alertDialog.show(); | |
70 | + } | |
71 | + | |
72 | + public void show(int iconResId, String title, String message) | |
73 | + { | |
74 | + // 表示イアログの生成 | |
75 | + final AlertDialog.Builder alertDialog = new AlertDialog.Builder(context); | |
76 | + alertDialog.setTitle(title); | |
77 | + alertDialog.setIcon(iconResId); | |
78 | + alertDialog.setMessage(message); | |
79 | + alertDialog.setCancelable(true); | |
80 | + | |
81 | + // ボタンを設定する(実行ボタン) | |
82 | + alertDialog.setPositiveButton(context.getString(R.string.dialog_positive_execute), | |
83 | + new DialogInterface.OnClickListener() { | |
84 | + public void onClick(DialogInterface dialog, int which) | |
85 | + { | |
86 | + dialog.dismiss(); | |
87 | + } | |
88 | + }); | |
89 | + | |
90 | + // 確認ダイアログを表示する | |
91 | + alertDialog.show(); | |
92 | + } | |
93 | + | |
94 | + // コールバックインタフェース | |
95 | + public interface Callback | |
96 | + { | |
97 | + void confirm(); | |
98 | + } | |
99 | +} |
@@ -0,0 +1,7 @@ | ||
1 | +package net.osdn.gokigen.cameratest; | |
2 | + | |
3 | +public interface IApplicationControl | |
4 | +{ | |
5 | + void exitApplication(); | |
6 | + | |
7 | +} |
@@ -27,7 +27,7 @@ import net.osdn.gokigen.cameratest.pages.SectionsPagerAdapter; | ||
27 | 27 | import org.opencv.android.BaseLoaderCallback; |
28 | 28 | import org.opencv.android.LoaderCallbackInterface; |
29 | 29 | |
30 | -public class MainActivity extends AppCompatActivity | |
30 | +public class MainActivity extends AppCompatActivity implements IApplicationControl | |
31 | 31 | { |
32 | 32 | /////// OpenCV /////// : license https://opencv.org/license/ |
33 | 33 | static |
@@ -77,7 +77,7 @@ public class MainActivity extends AppCompatActivity | ||
77 | 77 | |
78 | 78 | // Create the adapter that will return a fragment for each of the three |
79 | 79 | // primary sections of the activity. |
80 | - mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), testTarget); | |
80 | + mSectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager(), testTarget, this); | |
81 | 81 | |
82 | 82 | // Set up the ViewPager with the sections adapter. |
83 | 83 | mViewPager = findViewById(R.id.container); |
@@ -173,13 +173,12 @@ public class MainActivity extends AppCompatActivity | ||
173 | 173 | testTarget.disconnect(); |
174 | 174 | return (true); |
175 | 175 | } |
176 | +/* | |
176 | 177 | if (id == R.id.action_settings) |
177 | 178 | { |
178 | 179 | testTarget.settings(); |
179 | 180 | return (true); |
180 | 181 | } |
181 | - | |
182 | -/* | |
183 | 182 | if (id == R.id.action_reset) |
184 | 183 | { |
185 | 184 | testTarget.resetConnection(); |
@@ -250,7 +249,8 @@ public class MainActivity extends AppCompatActivity | ||
250 | 249 | /** |
251 | 250 | * |
252 | 251 | */ |
253 | - private void exitApplication() | |
252 | + @Override | |
253 | + public void exitApplication() | |
254 | 254 | { |
255 | 255 | try |
256 | 256 | { |
@@ -14,6 +14,7 @@ import com.google.android.material.snackbar.Snackbar; | ||
14 | 14 | |
15 | 15 | import net.osdn.gokigen.cameratest.R; |
16 | 16 | import net.osdn.gokigen.cameratest.fuji.Connection; |
17 | +import net.osdn.gokigen.cameratest.fuji.preference.FujiPreferenceFragment; | |
17 | 18 | import net.osdn.gokigen.cameratest.fuji.ILiveViewImage; |
18 | 19 | import net.osdn.gokigen.cameratest.fuji.ReceivedDataHolder; |
19 | 20 | import net.osdn.gokigen.cameratest.fuji.statuses.IFujiStatus; |
@@ -27,6 +28,8 @@ public class CamTest implements View.OnClickListener, View.OnTouchListener, ILiv | ||
27 | 28 | private final Activity activity; |
28 | 29 | private TextView textview; |
29 | 30 | private Connection connection; |
31 | + | |
32 | + private FujiPreferenceFragment preferenceFragment = null; | |
30 | 33 | //private FileOutputStream outputStream = null; |
31 | 34 | private static final int offsetSize = 18; // 4byte: データサイズ、14byte: (謎の)ヘッダ |
32 | 35 |
@@ -113,14 +116,25 @@ public class CamTest implements View.OnClickListener, View.OnTouchListener, ILiv | ||
113 | 116 | } |
114 | 117 | } |
115 | 118 | |
119 | +/* | |
116 | 120 | public void settings() |
117 | 121 | { |
118 | 122 | Log.v(TAG, "Show settings menu"); |
119 | 123 | |
124 | + if (preferenceFragment == null) | |
125 | + { | |
126 | + preferenceFragment = FujiPreferenceFragment.newInstance(); | |
127 | + } | |
128 | + FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction(); | |
129 | + transaction.replace(R.id.fragment1, logCatFragment); | |
130 | + // backstackに追加 | |
131 | + transaction.addToBackStack(null); | |
132 | + transaction.commit(); | |
133 | + | |
134 | + | |
120 | 135 | showMessageText("BBBB"); |
121 | 136 | } |
122 | 137 | |
123 | -/* | |
124 | 138 | public void valueUp() |
125 | 139 | { |
126 | 140 | Log.v(TAG, "value UP"); |
@@ -0,0 +1,59 @@ | ||
1 | +package net.osdn.gokigen.cameratest.fuji.preference; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.os.Bundle; | |
5 | + | |
6 | +import androidx.annotation.NonNull; | |
7 | +import androidx.preference.ListPreference; | |
8 | +import androidx.preference.Preference; | |
9 | +import androidx.preference.PreferenceFragmentCompat; | |
10 | + | |
11 | +import net.osdn.gokigen.cameratest.IApplicationControl; | |
12 | +import net.osdn.gokigen.cameratest.R; | |
13 | + | |
14 | +public class FujiPreferenceFragment extends PreferenceFragmentCompat | |
15 | +{ | |
16 | + private PowerOffController powerOffController = null; | |
17 | + | |
18 | + /** | |
19 | + * | |
20 | + * | |
21 | + */ | |
22 | + public static FujiPreferenceFragment newInstance(@NonNull Context context, @NonNull IApplicationControl control) | |
23 | + { | |
24 | + FujiPreferenceFragment instance = new FujiPreferenceFragment(); | |
25 | + instance.prepare(context, control); | |
26 | + | |
27 | + // パラメータはBundleにまとめておく | |
28 | + Bundle arguments = new Bundle(); | |
29 | + //arguments.putString("title", title); | |
30 | + //arguments.putString("message", message); | |
31 | + instance.setArguments(arguments); | |
32 | + | |
33 | + return (instance); | |
34 | + } | |
35 | + | |
36 | + private void prepare(@NonNull Context context, @NonNull IApplicationControl control) | |
37 | + { | |
38 | + powerOffController = new PowerOffController(context, control); | |
39 | + } | |
40 | + | |
41 | + @Override | |
42 | + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) | |
43 | + { | |
44 | + setPreferencesFromResource(R.xml.preferences_fuji_x, rootKey); | |
45 | + | |
46 | + ListPreference connectionMethod = (ListPreference) findPreference(IPreferencePropertyAccessor.CONNECTION_METHOD); | |
47 | + connectionMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { | |
48 | + @Override | |
49 | + public boolean onPreferenceChange(Preference preference, Object newValue) { | |
50 | + preference.setSummary(newValue + " "); | |
51 | + return (true); | |
52 | + } | |
53 | + }); | |
54 | + connectionMethod.setSummary(connectionMethod.getValue() + " "); | |
55 | + | |
56 | + findPreference("exit_application").setOnPreferenceClickListener(powerOffController); | |
57 | + | |
58 | + } | |
59 | +} |
@@ -0,0 +1,10 @@ | ||
1 | +package net.osdn.gokigen.cameratest.fuji.preference; | |
2 | + | |
3 | +public interface IPreferencePropertyAccessor | |
4 | +{ | |
5 | + String EXIT_APPLICATION = "exit_application"; | |
6 | + String CONNECTION_METHOD = "connection_method"; | |
7 | + String CONNECTION_METHOD_DEFAULT_VALUE = "FUJI_X"; | |
8 | + | |
9 | + | |
10 | +} |
@@ -0,0 +1,65 @@ | ||
1 | +package net.osdn.gokigen.cameratest.fuji.preference; | |
2 | + | |
3 | +import android.content.Context; | |
4 | + | |
5 | +import androidx.annotation.NonNull; | |
6 | +import androidx.preference.Preference; | |
7 | + | |
8 | +import net.osdn.gokigen.cameratest.ConfirmationDialog; | |
9 | +import net.osdn.gokigen.cameratest.IApplicationControl; | |
10 | +import net.osdn.gokigen.cameratest.R; | |
11 | + | |
12 | +public class PowerOffController implements Preference.OnPreferenceClickListener, ConfirmationDialog.Callback | |
13 | +{ | |
14 | + private final Context context; | |
15 | + private final IApplicationControl appControl; | |
16 | + private String preferenceKey = null; | |
17 | + | |
18 | + PowerOffController(@NonNull Context context, @NonNull IApplicationControl control) | |
19 | + { | |
20 | + this.context = context; | |
21 | + this.appControl = control; | |
22 | + } | |
23 | + | |
24 | + @Override | |
25 | + public boolean onPreferenceClick(Preference preference) | |
26 | + { | |
27 | + if (!preference.hasKey()) | |
28 | + { | |
29 | + return (false); | |
30 | + } | |
31 | + | |
32 | + preferenceKey = preference.getKey(); | |
33 | + if (preferenceKey.contains(IPreferencePropertyAccessor.EXIT_APPLICATION)) | |
34 | + { | |
35 | + | |
36 | + // 確認ダイアログの生成と表示 | |
37 | + ConfirmationDialog dialog = ConfirmationDialog.newInstance(context); | |
38 | + dialog.show(R.string.dialog_title_confirmation, R.string.dialog_message_power_off, this); | |
39 | + return (true); | |
40 | + } | |
41 | + return (false); | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * | |
46 | + * | |
47 | + */ | |
48 | + @Override | |
49 | + public void confirm() | |
50 | + { | |
51 | + try | |
52 | + { | |
53 | + if (preferenceKey.contains(IPreferencePropertyAccessor.EXIT_APPLICATION)) | |
54 | + { | |
55 | + // カメラの電源をOFFにしたうえで、アプリケーションを終了する。 | |
56 | + appControl.exitApplication(); | |
57 | + | |
58 | + } | |
59 | + } | |
60 | + catch (Exception e) | |
61 | + { | |
62 | + e.printStackTrace(); | |
63 | + } | |
64 | + } | |
65 | +} |
@@ -0,0 +1,64 @@ | ||
1 | +package net.osdn.gokigen.cameratest.logcat; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.content.Intent; | |
5 | +import android.util.Log; | |
6 | +import android.view.View; | |
7 | +import android.widget.AdapterView; | |
8 | +import android.widget.ArrayAdapter; | |
9 | + | |
10 | +import androidx.annotation.NonNull; | |
11 | + | |
12 | +import net.osdn.gokigen.cameratest.ConfirmationDialog; | |
13 | +import net.osdn.gokigen.cameratest.R; | |
14 | + | |
15 | +class LogCatExporter implements AdapterView.OnItemLongClickListener | |
16 | +{ | |
17 | + private final String TAG = toString(); | |
18 | + private final Activity activity; | |
19 | + | |
20 | + LogCatExporter(@NonNull Activity context) | |
21 | + { | |
22 | + this.activity = context; | |
23 | + | |
24 | + } | |
25 | + | |
26 | + @Override | |
27 | + public boolean onItemLongClick(final AdapterView<?> adapterView, View view, int i, long l) | |
28 | + { | |
29 | + Log.v(TAG, "onItemLongClick()" ); | |
30 | + | |
31 | + ConfirmationDialog confirm = ConfirmationDialog.newInstance(activity); | |
32 | + | |
33 | + confirm.show(R.string.dialog_confirm_title_output_log, R.string.dialog_confirm_message_output_log, new ConfirmationDialog.Callback() { | |
34 | + @Override | |
35 | + public void confirm() | |
36 | + { | |
37 | + Log.v(TAG, "confirm()" ); | |
38 | + try { | |
39 | + StringBuilder buf = new StringBuilder(); | |
40 | + ArrayAdapter<String> adapter = (ArrayAdapter<String>) adapterView.getAdapter(); | |
41 | + for (int index = 0; index < adapter.getCount(); index++) | |
42 | + { | |
43 | + buf.append(adapter.getItem(index)); | |
44 | + buf.append("\r\n"); | |
45 | + } | |
46 | + | |
47 | + Intent intent = new Intent(); | |
48 | + intent.setAction(Intent.ACTION_SEND); | |
49 | + intent.setType("text/plain"); | |
50 | + intent.putExtra(Intent.EXTRA_TITLE, "debug log for " + activity.getString(R.string.app_name)); | |
51 | + intent.putExtra(Intent.EXTRA_TEXT, new String(buf)); | |
52 | + activity.startActivity(intent); | |
53 | + | |
54 | + // Toast.makeText(activity, adapter.getItem(adapter.getCount() - 1), Toast.LENGTH_SHORT).show(); | |
55 | + } | |
56 | + catch (Exception e) | |
57 | + { | |
58 | + e.printStackTrace(); | |
59 | + } | |
60 | + } | |
61 | + }); | |
62 | + return (true); | |
63 | + } | |
64 | +} |
@@ -0,0 +1,198 @@ | ||
1 | +package net.osdn.gokigen.cameratest.logcat; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.os.Bundle; | |
5 | +import android.util.Log; | |
6 | +import android.view.LayoutInflater; | |
7 | +import android.view.Menu; | |
8 | +import android.view.MenuInflater; | |
9 | +import android.view.MenuItem; | |
10 | +import android.view.View; | |
11 | +import android.view.ViewGroup; | |
12 | +import android.widget.ArrayAdapter; | |
13 | +import android.widget.ListView; | |
14 | +import android.widget.Toast; | |
15 | + | |
16 | +import java.util.ArrayList; | |
17 | +import java.util.List; | |
18 | + | |
19 | +import androidx.annotation.Nullable; | |
20 | +import androidx.fragment.app.FragmentActivity; | |
21 | +import androidx.fragment.app.ListFragment; | |
22 | + | |
23 | +import net.osdn.gokigen.cameratest.R; | |
24 | + | |
25 | +/** | |
26 | + * | |
27 | + */ | |
28 | +public class LogCatFragment extends ListFragment | |
29 | +{ | |
30 | + private final String TAG = toString(); | |
31 | + private ArrayAdapter<String> adapter; | |
32 | + private List<String> dataItems = new ArrayList<>(); | |
33 | + private LogCatUpdater updater = new LogCatUpdater(); | |
34 | + public static LogCatFragment newInstance() | |
35 | + { | |
36 | + LogCatFragment instance = new LogCatFragment(); | |
37 | + | |
38 | + // パラメータはBundleにまとめておく | |
39 | + Bundle arguments = new Bundle(); | |
40 | + //arguments.putString("title", title); | |
41 | + //arguments.putString("message", message); | |
42 | + instance.setArguments(arguments); | |
43 | + | |
44 | + //instance.prepare(); | |
45 | + return (instance); | |
46 | + } | |
47 | + | |
48 | + @Override | |
49 | + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) | |
50 | + { | |
51 | + inflater.inflate(R.menu.debug_view, menu); | |
52 | +/* | |
53 | + String title = getString(R.string.app_name) + " " + getString(R.string.pref_degug_info); | |
54 | + try { | |
55 | + AppCompatActivity activity = (AppCompatActivity) getActivity(); | |
56 | + ActionBar bar = activity.getSupportActionBar(); | |
57 | + if (bar != null) | |
58 | + { | |
59 | + bar.setTitle(title); | |
60 | + } | |
61 | + } | |
62 | + catch (Exception e) | |
63 | + { | |
64 | + e.printStackTrace(); | |
65 | + } | |
66 | +*/ | |
67 | + } | |
68 | + | |
69 | + @Override | |
70 | + public boolean onOptionsItemSelected(MenuItem item) | |
71 | + { | |
72 | + if (item.getItemId() == R.id.action_refresh) | |
73 | + { | |
74 | + update(); | |
75 | + return true; | |
76 | + } | |
77 | + return super.onOptionsItemSelected(item); | |
78 | + } | |
79 | + | |
80 | + /** | |
81 | + * 表示データの更新 | |
82 | + * | |
83 | + */ | |
84 | + private void update() | |
85 | + { | |
86 | + dataItems.clear(); | |
87 | + Thread thread = new Thread(new Runnable() | |
88 | + { | |
89 | + @Override | |
90 | + public void run() | |
91 | + { | |
92 | + Log.v(TAG, "START LOGCAT"); | |
93 | + dataItems = updater.getLogCat("main", "time", "*:v", "gokigen", ""); | |
94 | + Log.v(TAG, "FINISH LOGCAT"); | |
95 | + try | |
96 | + { | |
97 | + final FragmentActivity activity = getActivity(); | |
98 | + if (activity != null) | |
99 | + { | |
100 | + activity.runOnUiThread(new Runnable() | |
101 | + { | |
102 | + @Override | |
103 | + public void run() | |
104 | + { | |
105 | + try | |
106 | + { | |
107 | + // 中身があったらクリアする | |
108 | + if (adapter.getCount() > 0) | |
109 | + { | |
110 | + adapter.clear(); | |
111 | + } | |
112 | + | |
113 | + // リストの内容を更新する | |
114 | + adapter.addAll(dataItems); | |
115 | + | |
116 | + // 最下部にカーソルを移したい | |
117 | + ListView view = activity.findViewById(android.R.id.list); | |
118 | + view.setSelection(dataItems.size()); | |
119 | + | |
120 | + // 更新終了通知 | |
121 | + //Snackbar.make(getActivity().findViewById(R.id.fragment1), getString(R.string.finish_refresh), Snackbar.LENGTH_SHORT).show(); | |
122 | + Toast.makeText(getActivity(), getString(R.string.finish_refresh), Toast.LENGTH_SHORT).show(); | |
123 | + } | |
124 | + catch (Exception ee) | |
125 | + { | |
126 | + ee.printStackTrace(); | |
127 | + } | |
128 | + } | |
129 | + }); | |
130 | + } | |
131 | + } | |
132 | + catch (Exception e) | |
133 | + { | |
134 | + e.printStackTrace(); | |
135 | + } | |
136 | + } | |
137 | + }); | |
138 | + try | |
139 | + { | |
140 | + // 本当は、ここでダイアログを出したい | |
141 | + thread.start(); | |
142 | + } | |
143 | + catch (Exception e) | |
144 | + { | |
145 | + e.printStackTrace(); | |
146 | + } | |
147 | + } | |
148 | + | |
149 | + @Override | |
150 | + public void onResume() | |
151 | + { | |
152 | + super.onResume(); | |
153 | + Log.v(TAG, "onResume()"); | |
154 | + | |
155 | + update(); | |
156 | + } | |
157 | + | |
158 | + @Override | |
159 | + public void onPause() | |
160 | + { | |
161 | + super.onPause(); | |
162 | + Log.v(TAG, "onPause()"); | |
163 | + } | |
164 | + | |
165 | + @Override | |
166 | + public void onCreate(Bundle savedInstanceState) | |
167 | + { | |
168 | + super.onCreate(savedInstanceState); | |
169 | + Log.v(TAG, "LogCatFragment::onCreate()"); | |
170 | + } | |
171 | + | |
172 | + @Override | |
173 | + public void onActivityCreated(@Nullable Bundle savedInstanceState) | |
174 | + { | |
175 | + super.onActivityCreated(savedInstanceState); | |
176 | + Log.v(TAG, "LogCatFragment::onActivityCreated()"); | |
177 | + setHasOptionsMenu(true); | |
178 | + | |
179 | + Activity activity = getActivity(); | |
180 | + if (activity != null) | |
181 | + { | |
182 | + ListView view = getListView(); | |
183 | + if (view != null) | |
184 | + { | |
185 | + getListView().setOnItemLongClickListener(new LogCatExporter(activity)); | |
186 | + } | |
187 | + } | |
188 | + } | |
189 | + | |
190 | + @Override | |
191 | + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) | |
192 | + { | |
193 | + adapter = new ArrayAdapter<>(inflater.getContext(), android.R.layout.simple_list_item_1, dataItems); | |
194 | + setListAdapter(adapter); | |
195 | + | |
196 | + return (super.onCreateView(inflater, container, savedInstanceState)); | |
197 | + } | |
198 | +} |
@@ -0,0 +1,69 @@ | ||
1 | +package net.osdn.gokigen.cameratest.logcat; | |
2 | + | |
3 | +import java.io.BufferedReader; | |
4 | +import java.io.InputStreamReader; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.List; | |
7 | + | |
8 | +class LogCatUpdater | |
9 | +{ | |
10 | + LogCatUpdater() | |
11 | + { | |
12 | + // | |
13 | + } | |
14 | + | |
15 | + /** | |
16 | + * | |
17 | + * @param ringbuffer : main - メイン ログバッファ, radio - 無線通信や電話に関連するメッセージが含まれるバッファ, events - イベントに関連するメッセージが含まれるバッファ | |
18 | + * @param logFormat : brief - 優先度 / タグとメッセージ発行元プロセスの PID, process - PID のみ, tag - 優先度 / タグのみ, raw - 生のログ, time - 日付、起動時刻、優先度 / タグ、メッセージ発行元プロセスの PID , threadtime - 日付、起動時刻、優先度、タグ、メッセージ発行元スレッドの PID および TID, long - すべてのメタデータ フィールド | |
19 | + * @param filterSpec : レベル : SFEWIDV | |
20 | + * @param filterString : 指定した文字列がログに含まれている場合に表示 | |
21 | + * @param filterRegEx : 指定した正規表現の文字列がログに含まれている場合に表示 | |
22 | + * @return ログのリスト | |
23 | + */ | |
24 | + | |
25 | + List<String> getLogCat(String ringbuffer, String logFormat, String filterSpec, String filterString, String filterRegEx) | |
26 | + { | |
27 | + final int BUFFER_SIZE = 8192; | |
28 | + ArrayList<String> listItems = new ArrayList<String>(); | |
29 | + try | |
30 | + { | |
31 | + ArrayList<String> commandLine = new ArrayList<String>(); | |
32 | + commandLine.add("logcat"); | |
33 | + commandLine.add("-d"); // -d: dump the log and then exit (don't block) | |
34 | + commandLine.add("-b"); // -b <buffer> : request alternate ring buffer ('main' (default), 'radio', 'events') | |
35 | + commandLine.add(ringbuffer); // <buffer> option. | |
36 | + commandLine.add("-v"); // -v <format> : Sets the log print format, where <format> is one of: | |
37 | + commandLine.add(logFormat); // brief process tag thread raw time threadtime long | |
38 | + commandLine.add(filterSpec); // | |
39 | + Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[commandLine.size()])); | |
40 | + | |
41 | + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()), BUFFER_SIZE); | |
42 | + String line; | |
43 | + do | |
44 | + { | |
45 | + line = bufferedReader.readLine(); | |
46 | + try | |
47 | + { | |
48 | + int filterLength = filterString.length(); | |
49 | + int filterRegExLength = filterRegEx.length(); | |
50 | + if (((filterLength == 0)&&(filterRegExLength == 0))|| | |
51 | + ((filterLength > 0)&&(line.contains(filterString)))|| | |
52 | + ((filterRegExLength > 0)&&(line.matches(filterRegEx)))) | |
53 | + { | |
54 | + listItems.add(line); | |
55 | + } | |
56 | + } | |
57 | + catch (Exception ee) | |
58 | + { | |
59 | + ee.printStackTrace(); | |
60 | + } | |
61 | + } while (line != null); | |
62 | + } | |
63 | + catch (Exception e) | |
64 | + { | |
65 | + e.printStackTrace(); | |
66 | + } | |
67 | + return (listItems); | |
68 | + } | |
69 | +} |
@@ -1,7 +1,13 @@ | ||
1 | 1 | package net.osdn.gokigen.cameratest.pages; |
2 | 2 | |
3 | +import android.content.Context; | |
4 | + | |
5 | +import net.osdn.gokigen.cameratest.IApplicationControl; | |
3 | 6 | import net.osdn.gokigen.cameratest.camtest.CamTest; |
7 | +import net.osdn.gokigen.cameratest.fuji.preference.FujiPreferenceFragment; | |
8 | +import net.osdn.gokigen.cameratest.logcat.LogCatFragment; | |
4 | 9 | |
10 | +import androidx.annotation.NonNull; | |
5 | 11 | import androidx.fragment.app.Fragment; |
6 | 12 | import androidx.fragment.app.FragmentManager; |
7 | 13 | import androidx.fragment.app.FragmentPagerAdapter; |
@@ -12,25 +18,49 @@ import androidx.fragment.app.FragmentPagerAdapter; | ||
12 | 18 | */ |
13 | 19 | public class SectionsPagerAdapter extends FragmentPagerAdapter |
14 | 20 | { |
21 | + private final Context context; | |
15 | 22 | private final CamTest testTarget; |
16 | - public SectionsPagerAdapter(FragmentManager fm, CamTest testTarget) | |
23 | + private final IApplicationControl appControl; | |
24 | + private LogCatFragment logCatFragment = null; | |
25 | + private FujiPreferenceFragment preferenceFragment = null; | |
26 | + private TestViewFragment testViewFragment = null; | |
27 | + public SectionsPagerAdapter(@NonNull Context context, FragmentManager fm, CamTest testTarget, IApplicationControl control) | |
17 | 28 | { |
18 | 29 | super(fm); |
30 | + this.context = context; | |
19 | 31 | this.testTarget = testTarget; |
32 | + this.appControl = control; | |
20 | 33 | } |
21 | 34 | |
22 | 35 | @Override |
23 | - public Fragment getItem(int position) | |
36 | + public @NonNull Fragment getItem(int position) | |
24 | 37 | { |
25 | - // getItem is called to instantiate the fragment for the given page. | |
26 | - // Return a TestViewFragment (defined as a static inner class below). | |
27 | - return TestViewFragment.newInstance((position + 1), testTarget); | |
38 | + if (position == 2) | |
39 | + { | |
40 | + if (logCatFragment == null) | |
41 | + { | |
42 | + logCatFragment = LogCatFragment.newInstance(); | |
43 | + } | |
44 | + return (logCatFragment); | |
45 | + } | |
46 | + else if (position == 1) | |
47 | + { | |
48 | + if (preferenceFragment == null) | |
49 | + { | |
50 | + preferenceFragment = FujiPreferenceFragment.newInstance(context, appControl); | |
51 | + } | |
52 | + return (preferenceFragment); | |
53 | + } | |
54 | + if (testViewFragment == null) | |
55 | + { | |
56 | + testViewFragment = TestViewFragment.newInstance((position + 1), testTarget); | |
57 | + } | |
58 | + return (testViewFragment); | |
28 | 59 | } |
29 | 60 | |
30 | 61 | @Override |
31 | 62 | public int getCount() |
32 | 63 | { |
33 | - // Show only one page. | |
34 | - return 1; | |
64 | + return 3; | |
35 | 65 | } |
36 | 66 | } |
@@ -0,0 +1,9 @@ | ||
1 | +<vector xmlns:android="http://schemas.android.com/apk/res/android" | |
2 | + android:width="24dp" | |
3 | + android:height="24dp" | |
4 | + android:viewportWidth="24.0" | |
5 | + android:viewportHeight="24.0"> | |
6 | + <path | |
7 | + android:fillColor="#FF000000" | |
8 | + android:pathData="M13,3h-2v10h2L13,3zM17.83,5.17l-1.42,1.42C17.99,7.86 19,9.81 19,12c0,3.87 -3.13,7 -7,7s-7,-3.13 -7,-7c0,-2.19 1.01,-4.14 2.58,-5.42L6.17,5.17C4.23,6.82 3,9.26 3,12c0,4.97 4.03,9 9,9s9,-4.03 9,-9c0,-2.74 -1.23,-5.18 -3.17,-6.83z"/> | |
9 | +</vector> |
@@ -0,0 +1,9 @@ | ||
1 | +<vector xmlns:android="http://schemas.android.com/apk/res/android" | |
2 | + android:width="24dp" | |
3 | + android:height="24dp" | |
4 | + android:viewportWidth="24.0" | |
5 | + android:viewportHeight="24.0"> | |
6 | + <path | |
7 | + android:fillColor="#FF000000" | |
8 | + android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/> | |
9 | +</vector> |
@@ -0,0 +1,12 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<menu xmlns:android="http://schemas.android.com/apk/res/android" | |
3 | + xmlns:compat="http://schemas.android.com/apk/res-auto" > | |
4 | + | |
5 | + <item | |
6 | + android:id="@+id/action_refresh" | |
7 | + compat:showAsAction="always" | |
8 | + android:icon="@drawable/ic_refresh_black_24dp" | |
9 | + android:title="@string/action_refresh" | |
10 | + android:visible="true" /> | |
11 | + | |
12 | +</menu> |
@@ -12,11 +12,7 @@ | ||
12 | 12 | android:orderInCategory="100" |
13 | 13 | android:title="@string/action_wifi_settings" |
14 | 14 | app:showAsAction="never" /> |
15 | - <item | |
16 | - android:id="@+id/action_settings" | |
17 | - android:orderInCategory="100" | |
18 | - android:title="@string/action_settings" | |
19 | - app:showAsAction="never" /> | |
15 | + | |
20 | 16 | <item |
21 | 17 | android:id="@+id/action_disconnect" |
22 | 18 | android:orderInCategory="100" |
@@ -25,6 +21,12 @@ | ||
25 | 21 | |
26 | 22 | <!-- |
27 | 23 | <item |
24 | + android:id="@+id/action_settings" | |
25 | + android:orderInCategory="100" | |
26 | + android:title="@string/action_settings" | |
27 | + app:showAsAction="never" /> | |
28 | + | |
29 | + <item | |
28 | 30 | android:id="@+id/action_reset" |
29 | 31 | android:orderInCategory="100" |
30 | 32 | android:title="@string/action_reset" |
@@ -35,6 +37,7 @@ | ||
35 | 37 | android:orderInCategory="100" |
36 | 38 | android:title="@string/action_up" |
37 | 39 | app:showAsAction="never" /> |
40 | + | |
38 | 41 | <item |
39 | 42 | android:id="@+id/action_down_value" |
40 | 43 | android:orderInCategory="100" |
@@ -0,0 +1,15 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<resources> | |
3 | + <string-array name="connection_method"> | |
4 | + <item>Fuji X Series</item> | |
5 | + <item>Ricoh GR II / PENTAX DSLR</item> | |
6 | + <item>OPC(Olympus Air)</item> | |
7 | + </string-array> | |
8 | + | |
9 | + <string-array name="connection_method_value"> | |
10 | + <item>FUJI_X</item> | |
11 | + <item>RICOH_GR2</item> | |
12 | + <item>OPC</item> | |
13 | + </string-array> | |
14 | + | |
15 | +</resources> |
@@ -18,4 +18,33 @@ | ||
18 | 18 | <string name="action_down">Down</string> |
19 | 19 | <string name="action_reset">Reset Connection</string> |
20 | 20 | <string name="action_disconnect">Disconnect</string> |
21 | + | |
22 | + <string name="pref_cat_application_control">App. Control</string> | |
23 | + <string name="pref_exit_power_off">Exit Application(and Camera OFF)</string> | |
24 | + <string name="pref_connection_method">Connection Method</string> | |
25 | + <string name="pref_cat_camera">Camera</string> | |
26 | + <string name="pref_capture_both_camera_and_live_view">Capture both camera and Live View</string> | |
27 | + | |
28 | + <string name="pref_cat_others">Others</string> | |
29 | + | |
30 | + <string name="pref_cat_gokigen">GOKIGEN</string> | |
31 | + <string name="pref_instruction_manual">Instructions</string> | |
32 | + <string name="pref_privacy_policy">Privacy Policy</string> | |
33 | + | |
34 | + <string name="pref_degug_info">Debug Information</string> | |
35 | + <string name="pref_summary_debug_info">LogCat Information</string> | |
36 | + | |
37 | + | |
38 | + <string name="dialog_title_confirmation">Confirmation</string> | |
39 | + <string name="dialog_positive_execute">OK</string> | |
40 | + <string name="dialog_negative_cancel">Cancel</string> | |
41 | + | |
42 | + <string name="dialog_confirm_title_output_log">Share debug log</string> | |
43 | + <string name="dialog_confirm_message_output_log">Share the debug log, OK?</string> | |
44 | + | |
45 | + <string name="action_refresh">Refresh</string> | |
46 | + <string name="finish_refresh">Finished Refresh</string> | |
47 | + | |
48 | + <string name="dialog_message_power_off">Power Off</string> | |
49 | + | |
21 | 50 | </resources> |
@@ -6,6 +6,7 @@ | ||
6 | 6 | <item name="colorPrimary">@color/colorPrimary</item> |
7 | 7 | <item name="colorPrimaryDark">@color/colorPrimaryDark</item> |
8 | 8 | <item name="colorAccent">@color/colorAccent</item> |
9 | + <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> | |
9 | 10 | </style> |
10 | 11 | |
11 | 12 | <style name="AppTheme.NoActionBar"> |
@@ -0,0 +1,58 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > | |
3 | + <PreferenceCategory | |
4 | + android:title="@string/pref_cat_application_control"> | |
5 | + | |
6 | + <PreferenceScreen | |
7 | + android:key="exit_application" | |
8 | + android:icon="@drawable/ic_power_settings_new_black_24dp" | |
9 | + android:title="@string/pref_exit_power_off" /> | |
10 | + | |
11 | + <ListPreference | |
12 | + android:title="@string/pref_connection_method" | |
13 | + android:entryValues="@array/connection_method_value" | |
14 | + android:entries="@array/connection_method" | |
15 | + android:key="connection_method" | |
16 | + android:defaultValue="RICOH_GR2"/> | |
17 | + | |
18 | + </PreferenceCategory> | |
19 | + | |
20 | + <PreferenceCategory | |
21 | + android:title="@string/pref_cat_camera"> | |
22 | + | |
23 | + <CheckBoxPreference | |
24 | + android:key="capture_both_camera_and_live_view" | |
25 | + android:title="@string/pref_capture_both_camera_and_live_view" /> | |
26 | + | |
27 | + </PreferenceCategory> | |
28 | + | |
29 | + | |
30 | + <PreferenceCategory | |
31 | + android:title="@string/pref_cat_others"> | |
32 | + | |
33 | + | |
34 | + </PreferenceCategory> | |
35 | + | |
36 | + <PreferenceCategory | |
37 | + android:title="@string/pref_cat_gokigen"> | |
38 | + | |
39 | + <Preference | |
40 | + android:key="instruction_link" | |
41 | + android:title="@string/pref_instruction_manual" | |
42 | + android:summary="https://osdn.net/projects/gokigen/wiki/GR2Control" | |
43 | + android:selectable="true"> | |
44 | + <intent android:action="android.intent.action.VIEW" | |
45 | + android:data="https://osdn.net/projects/gokigen/wiki/GR2Control" /> | |
46 | + </Preference> | |
47 | + | |
48 | + <Preference | |
49 | + android:key="privacy_policy" | |
50 | + android:title="@string/pref_privacy_policy" | |
51 | + android:summary="https://osdn.net/projects/gokigen/wiki/PrivacyPolicy" | |
52 | + android:selectable="true"> | |
53 | + <intent android:action="android.intent.action.VIEW" | |
54 | + android:data="https://osdn.net/projects/gokigen/wiki/PrivacyPolicy" /> | |
55 | + </Preference> | |
56 | + | |
57 | + </PreferenceCategory> | |
58 | +</PreferenceScreen> |