2019 Nov. 02.
android端末でブラウザを起動する。https://www.icloud.com/ にアクセスしiPhoneのApple IDでログインする。
目的のファイルをダウンロードする。ダウンロード時に指定するアプリはブラウザにする。
android端末内部共有ストレージ/Download ディレクトリ内にファイルが保管される。
public class MyActivity extends AppCompatActivity {
Button buttonOK;
/*
* MyAsyncTask内のListenerインターフェースを呼び出す
*/
private MyAsyncTask.Listener createListener() {
return new MyAsyncTask.Listener() {
/*
* Listenerインターフェースの抽象メソッドonSuccessにコードを実装
*/
@Override
public void onSuccess(String result) {
CODES_TO_RUN_AFTER_MyAsyncTask;
}
};
}
/*
* buttonOKがタップされたらMyAsyncTaskが呼び出される
*/
buttonOK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myAsyncTask = new MyAsyncTask();
/*
* MyAsyncTask内のListenerインターフェース型変数listenerに
* createListener()をセットする
* createListener()ではListenerインターフェースの
* 抽象メソッドonSuccessの実装コードが記述されている。
* MyAsyncTask内で"listener.onSuccess()"によって実装コードを実行できる。
*/
myAsyncTask.setListener(createListener());
myAsyncTask.execute();
}
});
}
(MyAsyncTask.java)public class MyAsyncTask extends AsyncTask{ private Listener listener; /* * 抽象メソッドonSuccess()は、MyAsyncTask内で実行させたい処理。 * 抽象メソッドonSuccess()は、MyAsyncTaskを呼び出すMyActivity内の * createListener()内で実装されている。 */ interface Listener { void onSuccess(String str); } void setListener(Listener listener) { this.listener = listener; } @Override protected String doInBackground(Void... params) { } @Override protected void onPostExecute(String result) { super.onPostExecute(result); CODES_TO_EXECUTE_onPostExecute; /* * onSuccess()メソッド実行 */ listener.onSuccess(result); return; } }
package your.package;
import android.content.Context;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.UserInfo;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
class MyJsch {
private final String ServerIp;
private final int Port;
private final String User;
private final String PassPhraseWord;
private final String IdentityKeyPath;
private final Context AppContext;
/** Channel接続タイプ */
private static final String CHANNEL_TYPE = "sftp";
/*
* コンストラクタ
*/
MyJsch( final String ServerIp, final int Port, final String User, final String PassPhraseWord,
final String IdentityKeyPath, final Context AppContext) {
this.ServerIp = ServerIp;
this.Port = Port;
this.User = User;
this.PassPhraseWord = PassPhraseWord;
this.IdentityKeyPath = IdentityKeyPath;
this.AppContext = AppContext;
}
/*
* Sessionを開始
*/
protected Session connectSession() throws JSchException {
Session session = null;
// android端末内の外部ストーリッジ確認
List sdCardFilesDirPaths =
SdCardDirPaths.getSdCardFilesDirPathListForLollipop( AppContext );
Collections.sort(sdCardFilesDirPaths, new CompStringLength());
String externalPath = sdCardFilesDirPaths.get(0);
externalPath = externalPath.replaceAll("/Android.*$", "");
final JSch jsch = new JSch();
// クライアント側のknownHostsチェックを行わない
Hashtable config = new Hashtable();
config.put("StrictHostKeyChecking", "no");
jsch.setConfig(config);
// パスフレーズ・秘密鍵方式
String privKeyFilePath = externalPath + "/" + IdentityKeyPath;
File privKeyFile = new File(privKeyFilePath);
if (privKeyFile.exists() ) {
jsch.addIdentity(privKeyFilePath, PassPhraseWord);
}
// Session取得
session = jsch.getSession(User, ServerIp, Port);
// パスワード方式でも可とする
session.setPassword(PassPhraseWord);
final UserInfo userInfo = new SftpUserInfo();
session.setUserInfo(userInfo);
session.connect();
return session;
}
/**
* SFTPのChannelを開始
*
* @param session
* 開始されたSession情報
*/
protected ChannelSftp connectChannelSftp(final Session session)
throws JSchException {
final ChannelSftp channel = (ChannelSftp) session.openChannel(CHANNEL_TYPE);
try {
channel.connect();
} catch (JSchException e) {
return null;
}
return channel;
}
/**
* Session・Channelの終了
*
* @param session
* 開始されたSession情報
* @param channels
* 開始されたChannel情報.複数指定可能
*/
protected void disconnect(final Session session, final Channel... channels) {
if (channels != null) {
for (Channel c: channels ) {
if (c != null) {
c.disconnect();
}
}
}
if (session != null) {
session.disconnect();
}
}
/**
* SFTPに接続するユーザ情報を保持するクラス
*/
private static class SftpUserInfo implements UserInfo {
@Override
public String getPassword() {
return null;
}
@Override
public boolean promptPassword(String arg0) {
return true;
}
@Override
public boolean promptPassphrase(String arg0) {
return true;
}
@Override
public boolean promptYesNo(String arg0) {
return true;
}
@Override
public void showMessage(String arg0) {
}
@Override
public String getPassphrase() {
return null;
}
}
/**
* ファイルアップロード
*
* @throws JSchException
* Session・Channelの設定/接続エラー時に発生
*/
public void putFile(ChannelSftp channel, InputStream inStream, String destPath)
throws SftpException {
/*
* sftp通信を実行
*/
String absoluteDestPath = channel.getHome() + "/" + destPath;
String destFile = new File(absoluteDestPath).getName();
int numDestPath = absoluteDestPath.length();
int numDestFile = destFile.length();
String destParentPath = absoluteDestPath.substring( 0, numDestPath - numDestFile );
channel.cd(destParentPath);
channel.put( inStream, destFile);
// confirm existance of destFile
channel.lstat(destFile);
}
/*
* サーバー上のファイルの削除
* destFileNameFront文字列から始まるファイルを全て削除する
*/
public void deleteFiles(ChannelSftp channel, String destFileNameFront) throws SftpException {
channel.rm(destFileNameFront + "*");
}
}
package your.package;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class SdCardDirPaths {
/**
* SDカードのfilesディレクトリパスのリストを取得する。
* Android5.0以上対応。
*
* @param context
* @return SDカードのfilesディレクトリパスのリスト
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static List getSdCardFilesDirPathListForLollipop(Context context) {
List sdCardFilesDirPathList = new ArrayList<>();
// getExternalFilesDirsはAndroid4.4から利用できるAPI。
// filesディレクトリのリストを取得できる。
File[] dirArr = context.getExternalFilesDirs(null);
for (File dir : dirArr) {
if (dir != null) {
String path = dir.getAbsolutePath();
// isExternalStorageRemovableはAndroid5.0から利用できるAPI。
// 取り外し可能かどうか(SDカードかどうか)を判定している。
if (Environment.isExternalStorageRemovable(dir)) {
// 取り外し可能であればSDカード。
// このパスをパスリストに加える
if (!sdCardFilesDirPathList.contains(path)) {
sdCardFilesDirPathList.add(path);
}
}
}
}
return sdCardFilesDirPathList;
}
}
package your.package; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.widget.Toast; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; // 複数のファイルをSSH送信する public class Send2ServerTask extends AsyncTask{ final String ServerIp = "SSH.SERVER.IP.ADDRESS"; final int Port = 22; final String User = "SshLogInUser"; final String IdentityKeyPath = "PRIVATE/KEY/FILE/PATH/IN/CLIENT/DEVICE"; // if IdentityKeyPath is illegal, password authentication is used. final String DestParentPath = "SERVER/DIR/TO/BE/STORED"; private WeakReference weakRef; private HashMap inStreamMap; final private String passPhrase; final private String fileNameFront; // SSH失敗時のファイル削除のためにファイル名共通文字列を保持 // 複数の送信ファイルはいずれもfileNameFront文字列で始まるファイル名とすること private Listener listener; /* * constructor * inStreamMap 送信する複数ファイルのファイル名とインプットストリームをHashMapで渡す */ Send2ServerTask(Activity parentActivity, HashMap inStreamMap, String passPhrase, String fileNameFront) { weakRef = new WeakReference<>(parentActivity); this.inStreamMap = new HashMap<>(inStreamMap); this.passPhrase = passPhrase; this.fileNameFront = fileNameFront; } @Override protected String doInBackground(Void... params) { MyJsch mJsch; Session sftpSession = null; ChannelSftp sftpChannel = null; Activity refActivity = weakRef.get(); if (refActivity == null || refActivity.isFinishing()) { return null; } Context appContext = weakRef.get().getApplicationContext(); // initialise Jsch mJsch = new MyJsch(ServerIp, Port, User, passPhrase, IdentityKeyPath, appContext); // connect session, channel try { sftpSession = mJsch.connectSession(); sftpChannel = mJsch.connectChannelSftp( sftpSession ); // upload int count = 0; for ( Map.Entry entry : inStreamMap.entrySet()) { // entry.getKey() entry.getValue() String destPath = DestParentPath + "/" + entry.getKey(); try { mJsch.putFile(sftpChannel, entry.getValue(), destPath); } catch (SftpException e) { try { // このセッションでアップロードされたファイルをすべて削除する mJsch.deleteFiles(sftpChannel, fileNameFront); mJsch.disconnect( sftpSession, sftpChannel); return "Failed to upload files. count: " + count + ". " + destPath + " " + e.toString(); } catch (SftpException e1) { mJsch.disconnect( sftpSession, sftpChannel); return "Failed to delete remote files. " + e1.toString(); } } try { // take sleep between SFTP#puts Thread.sleep(500); } catch (InterruptedException e) { // このセッションでアップロードされたファイルをすべて削除する mJsch.deleteFiles(sftpChannel, fileNameFront); mJsch.disconnect( sftpSession, sftpChannel); return "Failed! sleep" + e.toString(); } count++; } if ( count != inStreamMap.size()) { // このセッションでアップロードされたファイルをすべて削除する mJsch.deleteFiles(sftpChannel, fileNameFront); mJsch.disconnect( sftpSession, sftpChannel); return "Could not upload " + inStreamMap.size() + " files"; } } catch (JSchException | SftpException e) { mJsch.disconnect( sftpSession, sftpChannel); return "connection failed. " + e.toString(); } finally { // disconnect channel, session mJsch.disconnect( sftpSession, sftpChannel); } return "Succeeded. " + inStreamMap.size() + " files upload"; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); Activity refActivity = weakRef.get(); if (refActivity == null || listener == null) { Toast.makeText(refActivity, "failed sending to server.", Toast.LENGTH_LONG).show(); } else { if ( result.contains("Succeeded") ) { Toast.makeText(refActivity, result, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(refActivity, result, Toast.LENGTH_LONG).show(); } listener.onSuccess(result); } return; } void setListener(Listener listener) { this.listener = listener; } interface Listener { void onSuccess(String str); } }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_confirm_before_send);
buttonOK = findViewById(R.id.buttonOK);
setListeners();
}
/*
* Send2ServerTaskへのリスナ
* サーバーへのアップロード終了後に行う処理を記述
*/
private Send2ServerTask.Listener createListener() {
return new Send2ServerTask.Listener() {
@Override
public void onSuccess(String result) {
deleteFiles();
}
};
}
protected void setListeners(){
buttonOK.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*
* HashMap SSHサーバーに送るデータ
* String 送信先ファイルパス
* InputStream 送信ファイルのインプットストリーム
*/
HashMap dataMap = new HashMap<>();
setData2dataMap(); // dataMapにSSH通信データをセットする
setPassPhraseWord();
setFileNameFront();
/*
* dataMapを保管サーバーに送る
*/
send2serverTask = new Send2ServerTask(thisActivity, dataMap, passPhraseWord, fileNameFront);
// Listenerを設定し、send2serverTaskを実行してdataMapを保管サーバーに送る
send2serverTask.setListener(createListener());
send2serverTask.execute();
}
});
}
package YOUR.PACKAGE.alertdialogsample;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button button_dialog1, button_dialog2, button_dialog3;
private TextView text_view;
private FragmentManager flagmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text_view = findViewById(R.id.text_view);
button_dialog1 = findViewById(R.id.button_dialog1);
button_dialog2 = findViewById(R.id.button_dialog2);
button_dialog3 = findViewById(R.id.button_dialog3);
// button_dialog1ボタンタップでAlertを表示させる
button_dialog1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
flagmentManager = getSupportFragmentManager();
// DialogFragment を継承したAlertDialogFragment1のインスタンス
AlertDialogFragment1 dialogFragment = AlertDialogFragment1.newInstance(100);
// DialogFragmentの表示
dialogFragment.show(flagmentManager, "test alert dialog1");
}
});
// button_dialog2ボタンタップでダイアログのメッセージを変えたAlertを表示させる
// newInstance()への引数を変更してメッセージを変える
button_dialog2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
flagmentManager = getSupportFragmentManager();
// DialogFragmentを継承したAlertDialogFragment2のインスタンス
AlertDialogFragment1 dialogFragment = AlertDialogFragment1.newInstance(200);
// DialogFragmentの表示
dialogFragment.show(flagmentManager, "test alert dialog2");
}
});
// button_dialog3ボタンタップでItemを選択するAlertを表示させる
button_dialog3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
flagmentManager = getSupportFragmentManager();
// DialogFragment を継承したAlertDialogFragmentのインスタンス
AlertDialogFragment2 dialogFragment = new AlertDialogFragment2();
// DialogFragmentの表示
dialogFragment.show(flagmentManager, "test alert dialog");
}
});
}
public void setTextView(String message){
text_view.setText(message);
}
/*
* DialogFragmentを継承したクラスAlertDialogFragment1
*/
public static class AlertDialogFragment1 extends DialogFragment {
/*
* コンストラクタを記述してはならない。
* newInstance()でのsetArguments、onCreateDialog()でのgetArgumentsを利用する。
*/
public static AlertDialogFragment1 newInstance( int requestCode) {
AlertDialogFragment1 fragment = new AlertDialogFragment1();
Bundle arguments = new Bundle();
arguments.putInt("reqCode", requestCode);
fragment.setArguments(arguments);
return fragment;
}
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
int requestCode = getArguments().getInt("reqCode");
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
switch (requestCode) {
case 100:
alert.setTitle("Test AlertDialog1");
alert.setMessage("Message is 100");
break;
case 200:
alert.setTitle("Test AlertDialog2");
alert.setMessage("Message is 200");
break;
}
alert.setPositiveButton(R.string.dialog_ok, null);
return alert.create();
}
}
/*
* DialogFragmentを継承したクラスAlertDialogFragment2
*/
public static class AlertDialogFragment2 extends DialogFragment {
// 選択肢のリスト
private String[] menulist = {"選択(1)","選択(2)","選択(3)"};
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
alert.setTitle("Test AlertDialog3");
alert.setItems(menulist, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int idx) {
// 選択1
if (idx == 0) {
setMassage(menulist[0]);
}
// 選択2
else if (idx == 1) {
setMassage(menulist[1]);
}
// 選択3, idx == 2
else{
setMassage(menulist[2]);
}
}
});
return alert.create();
}
private void setMassage(String message) {
MainActivity mainActivity = (MainActivity) getActivity();
if (mainActivity != null) {
mainActivity.setTextView(message);
}
}
}
}
package YOUR.PACKAGE.APPLICATION;
/*
* Re-use of https://akira-watson.com/android/file_search.html
*/
import android.os.Environment;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class SearchExternalStorageFile {
// 外部ストレージ内のfileStrにマッチするファイルを検索
public String[] searchFiles( String fileStr ){
// マッチしたファイルの絶対パスを格納する
List listMatchedFiles = new ArrayList<>();
// String 型の ArrayList を生成
List listDirectory = new ArrayList<>();
// 外部ストレージのパスを取得する、パスは機種によって異なる
File file = Environment.getExternalStorageDirectory();
String storagePath = file.getPath();
listDirectory.add(storagePath);
int m = 0;
int n = 0;
String[] fileNames;
String imgPath = null, fName;
while(listDirectory.size() > m){
File directory = new File(listDirectory.get(m));
fileNames = directory.list();
n = 0;
while(fileNames.length > n){
File subFile;
subFile = new File(directory.getPath() + "/" + fileNames[n]);
if (subFile.isDirectory()) {
listDirectory.add(directory.getPath() + "/" + fileNames[n]);
} else {
if (fileNames[n].contains(fileStr)) {
listMatchedFiles.add(directory.getPath() + "/" + fileNames[n]);
}
}
n++;
}
m++;
}
int listSize = listMatchedFiles.size();
return listMatchedFiles.toArray(new String[listSize]);
}
}
package YOUR.PACKAGE;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
boolean is1stRun = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if ( is1stRun ) {
// get text by dialog
InputTextDialogFragment cdf = new InputTextDialogFragment();
cdf.show(getSupportFragmentManager(),"dialog");
is1stRun = false;
}
}
public void onReturnValue(String value) {
TextView textViewPhrase = (TextView)findViewById(R.id.textViewPhrase);
textViewPhrase.setText(value);
}
}
package YOUR.PACKAGE;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
public class InputTextDialogFragment extends DialogFragment {
EditText editTextPhrase;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new Dialog(getActivity());
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
dialog.setContentView(R.layout.input_text_dialog);
editTextPhrase = (dialog.findViewById(R.id.editTextPhrase));
dialog.findViewById(R.id.buttonOK).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textPhrase = editTextPhrase.getText().toString();
MainActivity callingActivity = (MainActivity) getActivity();
callingActivity.onReturnValue(textPhrase);
dismiss();
}
});
return dialog;
}
}
public class FirstActivity extends AppCompatActivity {
Button button1 = (Button) findViewById(R.id.button1);
button1.setEnabled(true);
TextView textView1 = (TextView) findViewById(R.id.textView1);
textView1.setText("start")
new SecondTask(this).execute();
}
public class SecondTask extends AsyncTask {
private WeakReference weakReference;
/**
* make WeakReference in constructor
* 参照しているActivityを引数にしてWeakReferenceのインスタンスを生成する
**/
SecondTask(Context referenceContext) {
private WeakReference weakReference;
weakReference = new WeakReference<>(referenceContext);
}
/**
* use of WeakReference in onPostExecute
* weakReference.get()で参照しているActivityのContextを取得し、それを通じてView を設定したりする
**/
@Override
protected void onPostExecute(String result) {
Activity activity = (Activity) weakReference.get();
if (activity == null || activity.isFinishing()) return;
activity.findViewById(R.id.button1).setEnabled(false);
TextView tv = activity.findViewById(R.id.textView1);
tv.setText("end");
}
}
package YOUR.PACKAGE.NAME;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
/** Channel接続タイプ */
private static final String CHANNEL_TYPE = "sftp";
private MyTask task;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
final String ServerIP = "ServerIP";
final int Port = PortNum;
final String UserId = "USER";
final String PassPhrase = "YOURPASSPHRASE";
final String IdentityKeyPath = "YOUR/SECRET/FILE/PATH"; // Do not attach '/' at head of path
final String SourcePath = "PATH/TO/SOURCE/FILE"; // Do not attach '/' at head of path
final String DestPath = "PATH/TO/DEST/FILE";
*/
final String ServerIP="";
final int Port = ;
final String UserId = "";
final String PassPhrase = "";
final String IdentityKeyPath = "";
final String SourcePath = "";
final String DestPath = "";
Button button1= (Button) findViewById(R.id.button1);
TextView textView1 = (TextView) findViewById(R.id.textView1);
// タスクの生成
task = new MyTask(ServerIP, Port, UserId, PassPhrase, IdentityKeyPath, SourcePath, DestPath,this);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setEnabled(false);
// 非同期処理を開始する
task.execute();
}
});
}
}
package YOUR.PACKAGE.NAME; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.widget.TextView; import com.jcraft.jsch.JSchException; import java.lang.ref.WeakReference; public class MyTask extends AsyncTask{ private final String ServerIp; private final int Port; private final String User; private final String IdentityKeyPath; private final String PassPhrase; private final String SrcPath; private final String DestPath; private WeakReference weakReference; // constructor MyTask(final String ServerIp, final int Port, final String User, final String PassPhrase, final String IdentityKeyPath, final String SrcPath, final String DestPath, Context referenceContext) { super(); // 呼び出し元へのweakReference weakReference = new WeakReference<>(referenceContext); this.ServerIp = ServerIp; this.Port = Port; this.User = User; this.PassPhrase = PassPhrase; this.IdentityKeyPath = IdentityKeyPath; this.SrcPath = SrcPath; this.DestPath = DestPath; } /** * バックグランドで行う処理 */ @Override protected String doInBackground(Void... value) { // startJsch MyJsch mJsch = new MyJsch( ServerIp, Port, User, PassPhrase, IdentityKeyPath, SrcPath, DestPath, weakReference.get()); try { mJsch.putFile(); } catch (JSchException e) { e.printStackTrace(); return e.toString(); } return "Success"; } /** * バックグランド処理が完了し、UIスレッドに反映する */ @Override protected void onPostExecute(String result) { // get a reference to the activity if it is still there Activity activity = (Activity) weakReference.get(); if (activity == null || activity.isFinishing()) return; activity.findViewById(R.id.button1).setEnabled(true); TextView tv = activity.findViewById(R.id.textView1); tv.setText(result); } }
package YOUR.PACKAGE.NAME;
import android.content.Context;
import android.util.Log;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.UserInfo;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class MyJsch {
private final String ServerIp;
private final int Port;
private final String User;
private final String PassPhrase;
private final String IdentityKeyPath;
private final String SrcPath;
private final String DestPath;
private Context activityContext;
private String externalPath;
/** Channel接続タイプ */
private static final String CHANNEL_TYPE = "sftp";
/**
* コンストラクタ
*/
MyJsch(final String ServerIp, final int Port, final String User, final String PassPhrase,
final String IdentityKeyPath, final String SrcPath, final String DestPath,
Context activityContext) {
this.ServerIp = ServerIp;
this.Port = Port;
this.User = User;
this.IdentityKeyPath = IdentityKeyPath;
this.PassPhrase = PassPhrase;
this.SrcPath = SrcPath;
this.DestPath = DestPath;
this.activityContext = activityContext;
}
/**
* ファイルアップロード
*
* @throws JSchException
* Session・Channelの設定/接続エラー時に発生
*/
public void putFile()
throws JSchException {
Session session = null;
ChannelSftp channel = null;
// 外部ストーリッジ確認
List sdCardFilesDirPaths =
SdCardDirPaths.getSdCardFilesDirPathListForLollipop( activityContext );
Collections.sort(sdCardFilesDirPaths, new CompStringLength());
for (String p : sdCardFilesDirPaths) {
Log.d("My", "SDパスの1つ: " + p);
}
externalPath = sdCardFilesDirPaths.get(0);
externalPath = externalPath.replaceAll("/Android.*$", "");
Log.d("My", "SDパス: " + externalPath);
// get sourcePath
final String sourcePath = externalPath + "/" + SrcPath;
Log.d("My", "sourcePath " + sourcePath );
if ( new File(sourcePath).exists()) {
Log.d("My", sourcePath + " exists.");
} else {
Log.d("My", sourcePath + " not exist.");
}
/*
* sftp通信を実行
*/
try {
session = connectSession();
channel = connectChannelSftp(session);
String absoluteDestPath = channel.getHome() + "/" + DestPath;
String destFile = new File(absoluteDestPath).getName();
int numDestPath = absoluteDestPath.length();
int numDestFile = destFile.length();
String destParentPath = absoluteDestPath.substring( 0, numDestPath - numDestFile );
Log.d("My", "absoluteDestPath is " + absoluteDestPath);
Log.d("My", "destFile is " + destFile);
Log.d("My", "destParentPath is " + destParentPath);
Log.d("My", "current local directory is " + channel.lpwd());
Log.d("My", "remote home directory is " + channel.getHome());
channel.cd(destParentPath);
channel.put(sourcePath, destFile);
try {
channel.lstat(destFile);
} catch (SftpException e) {
Log.d("My", DestPath + " does not exist.");
Log.d("My", e.toString());
}
} catch (SftpException e) {
Log.d("My",e.toString());
} finally {
disconnect(session, channel);
}
}
/**
* Sessionを開始
*/
private Session connectSession()
throws JSchException {
final JSch jsch = new JSch();
// 鍵追加
String keyFilePath = externalPath + "/" + IdentityKeyPath;
if ( new File(keyFilePath).exists()) {
Log.d("My", keyFilePath + " exists.");
} else {
Log.d("My", keyFilePath + " not exist.");
}
jsch.addIdentity(keyFilePath, PassPhrase);
// Session設定
final Session session = jsch.getSession(User, ServerIp, Port);
final UserInfo userInfo = new SftpUserInfo();
// TODO 今回は使用しないがパスフレーズ等が必要な場合はUserInfoインスタンス経由で設定する
session.setUserInfo(userInfo);
session.connect();
return session;
}
/**
* SFTPのChannelを開始
*
* @param session
* 開始されたSession情報
*/
private ChannelSftp connectChannelSftp(final Session session)
throws JSchException {
final ChannelSftp channel = (ChannelSftp) session.openChannel(CHANNEL_TYPE);
try {
channel.connect();
} catch (JSchException e) {
Log.d("My", e.toString());
}
return channel;
}
/**
* Session・Channelの終了
*
* @param session
* 開始されたSession情報
* @param channels
* 開始されたChannel情報.複数指定可能
*/
private void disconnect(final Session session, final Channel... channels) {
if (channels != null) {
for (Channel c: channels ) {
if (c != null) {
c.disconnect();
}
}
}
if (session != null) {
session.disconnect();
}
}
/**
* SFTPに接続するユーザ情報を保持するクラス
*/
private static class SftpUserInfo implements UserInfo {
@Override
public String getPassword() {
return null;
}
@Override
public boolean promptPassword(String arg0) {
return true;
}
@Override
public boolean promptPassphrase(String arg0) {
return true;
}
@Override
public boolean promptYesNo(String arg0) {
return true;
}
@Override
public void showMessage(String arg0) {
}
@Override
public String getPassphrase() {
return null;
}
}
}
$ sm partition disk:xxx,yy mixed N
N: SDカードを外部ストレージ として残す割合(%)
android端末のストレージ設定で内部ストレージ設定を行う
・kvmグループにユーザーを追加する
・# chown USER:kvm /dev/kvm
もしくは
# chmod a+x /dev/kvm
client dev tun proto udp remote YOUR.GLOBAL.ADDRESS.HERE 1194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert CLIENTDEVNAME.crt key CLIENTDEVNAME.key comp-lzo verb 3
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
if (br != null) try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
String str;
try {
while((str = br.readLine()) != null){
Log.v("Read",str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String filename = "hoge.txt";
private File directory = Environment.getExternalStorageDirectory();
private String filepath = directory.getAbsolutePath() + "/YourDir/" + filename;
private File file = new File(filepath);
// SDカードマウント状態
final String state = Environment.getExternalStorageState();
if (!state.equals(Environment.MEDIA_MOUNTED)) {
try {
throw new IOException("No Mount");
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
if (br != null) try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
String str;
try {
while((str = br.readLine()) != null){
Log.v("Read",str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn = (Button)findViewById(R.id.btn);
btn.setText("Show Dialog");
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final CharSequence[] items = {"car", "train", "byke"};
new AlertDialog.Builder(MainActivity.this)
.setTitle("Select tool")
.setIcon(R.drawable.myIcon)
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int which) {
btn.setText(String.format("%sが選択されました。",items[which]));
}
})
.show();
}
});
}
}
public class MainActivity extends Activity implements DialogInterface.OnClickListener {
final String[] items = {"car", "train", "byke"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn = (Button)findViewById(R.id.btn);
btn.setText("Show Dialog");
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
myShowDialog("Not Selected");
}
});
}
@Override
public void onClick(DialogInterface dlg, int which) {
myShowDialog(items[which]);
}
public void myShowDialog(final String titleStr) {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(titleStr);
dialog.setIcon(R.drawable.myIcon);
dialog.setItems(items, this);
dialog.show();
}
}
public class MainActivity extends Activity implements DialogInterface.OnClickListener {
TextView tv;
final String[] items = {"car", "train", "byke"};
final List listItems = Arrays.asList(items); //配列をList型オブジェクトに変換
@Override
public void onClick(DialogInterface dlg, int which) {
Log.v("dialog_which", String.valueOf(which)); // int of order of items
showDialog(items[which]);
}
public void showDialog(final String titleStr) {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(titleStr);
dialog.setIcon(R.drawable.myIcon);
dialog.setItems(items, this);
dialog.setPositiveButton("決 定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int index) {
Log.v("dialog_index", String.valueOf(index)); // unexpected int
tv.setText(titleStr);
}
});
dialog.setNeutralButton("前 へ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int index) {
Log.v("dialog_index", String.valueOf(index)); // unexpected int
int i = listItems.indexOf(titleStr); //list内に引数の要素が存在する最小のインデックスを返す
int numArray = (i+3-1)%3;
tv.setText(items[numArray]);
}
});
dialog.setNegativeButton("2つ前へ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int index) {
Log.v("dialog_index", String.valueOf(index)); // unexpected int
int i = listItems.indexOf(titleStr); //list内に引数の要素が存在する最小のインデックスを返す
int numArray = (i+3-2)%3;
tv.setText(items[numArray]);
}
});
dialog.show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = ((TextView)findViewById(R.id.tv));
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
showDialog("");
}
});
}
}